From 62c613f6d2d4e3e2cf0918f75e302d48a3df673e Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Tue, 5 Oct 2021 13:54:47 +0100 Subject: [PATCH 001/504] Add initial port for FT9xx series from Bridgetek. Add FT90X and FT93X to the list of devices in tusb_option.h. 1700 for FT90x and 1701 for FT93x. Set endpoint attributes for FT90x and FT93x in dcd_attr.h. Add FT90x routines for USB device in src/portable/bridgetek/ft90x/dcd_ft90x.c The location for hardware header files and libraries is hw/mcu/bridgetek/ft90x/hardware. There are no files in the repository, but files will be linked as a submodule in the future. The required files can be copied from or linked to the location "C:/Program Files(x86)/Bridgetek/FT9xx Toolchain/Toolchain/hardware" once the toolchain is installed. Makefile for the MM900EV1B board for developing with an FT900 device is present. Use "BOARD=mm900ev1b". --- hw/bsp/brtmm90x/boards/mm900ev1b/board.h | 56 + hw/bsp/brtmm90x/family.c | 210 ++++ hw/bsp/brtmm90x/family.mk | 35 + hw/mcu/bridgetek/ft90x/Readme.md | 6 + .../bridgetek/ft90x/hardware/scripts/crt0.S | 286 +++++ .../ft90x/hardware/scripts/ldscript.ld | 94 ++ src/device/dcd_attr.h | 7 + src/portable/bridgetek/ft90x/dcd_ft90x.c | 1101 +++++++++++++++++ src/tusb_option.h | 4 + 9 files changed, 1799 insertions(+) create mode 100644 hw/bsp/brtmm90x/boards/mm900ev1b/board.h create mode 100644 hw/bsp/brtmm90x/family.c create mode 100644 hw/bsp/brtmm90x/family.mk create mode 100644 hw/mcu/bridgetek/ft90x/Readme.md create mode 100644 hw/mcu/bridgetek/ft90x/hardware/scripts/crt0.S create mode 100644 hw/mcu/bridgetek/ft90x/hardware/scripts/ldscript.ld create mode 100644 src/portable/bridgetek/ft90x/dcd_ft90x.c diff --git a/hw/bsp/brtmm90x/boards/mm900ev1b/board.h b/hw/bsp/brtmm90x/boards/mm900ev1b/board.h new file mode 100644 index 000000000..dfb566289 --- /dev/null +++ b/hw/bsp/brtmm90x/boards/mm900ev1b/board.h @@ -0,0 +1,56 @@ +/* + * 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. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(__FT900__) +#define GPIO_UART0_TX 48 +#define GPIO_UART0_RX 49 +#define GPIO_ETH_LED0 61 +#define GPIO_ETH_LED1 62 +#define GPIO_REMOTE_WAKEUP_PIN 18 +#define USBD_VBUS_DTC_PIN 3 +#elif defined(__FT930__) +#define GPIO_UART0_TX 23 +#define GPIO_UART0_RX 22 +#define GPIO_ETH_LED0 4 +#define GPIO_ETH_LED1 5 +#define GPIO_REMOTE_WAKEUP_PIN 12 +#define USBD_VBUS_DTC_PIN 39 +#endif + +//#define GPIO_REMOTE_WAKEUP + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/hw/bsp/brtmm90x/family.c b/hw/bsp/brtmm90x/family.c new file mode 100644 index 000000000..010704d92 --- /dev/null +++ b/hw/bsp/brtmm90x/family.c @@ -0,0 +1,210 @@ +/* + * The MIT License (MIT) + * + * Copyright 2019 Sony Semiconductor Solutions Corporation + * + * 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 +#include "bsp/board.h" +#include "board.h" +//#include "src/device/dcd.h" + +#if TUSB_OPT_DEVICE_ENABLED +int8_t board_ft90x_vbus(void); // Board specific implementation of VBUS detection for USB device. +extern void ft90x_usbd_pm_ISR(uint16_t pmcfg); // Interrupt handler for USB device power management +#endif + +#ifdef GPIO_REMOTE_WAKEUP +void gpio_ISR(void); +#endif +void timer_ISR(void); +volatile unsigned int timer_ms = 0; +void board_pm_ISR(void); + +#define WELCOME_MSG "\x1B[2J\x1B[H" \ + "MM900EV1B board\r\n" + +// Initialize on-board peripherals : led, button, uart and USB +void board_init(void) +{ + sys_reset_all(); + // Enable the UART Device. + sys_enable(sys_device_uart0); + // Set UART0 GPIO functions to UART0_TXD and UART0_RXD. + gpio_function(GPIO_UART0_TX, pad_uart0_txd); /* UART0 TXD */ + gpio_function(GPIO_UART0_RX, pad_uart0_rxd); /* UART0 RXD */ + uart_open(UART0, /* Device */ + 1, /* Prescaler = 1 */ + UART_DIVIDER_19200_BAUD, /* Divider = 1302 */ + uart_data_bits_8, /* No. Data Bits */ + uart_parity_none, /* Parity */ + uart_stop_bits_1); /* No. Stop Bits */ + // Print out a welcome message. + // Use sizeof to avoid pulling in strlen unnecessarily. + board_uart_write(WELCOME_MSG, sizeof(WELCOME_MSG)); + +#if 1 + gpio_function(GPIO_ETH_LED0, pad_gpio4); /* ETH LED0 */ + gpio_dir(GPIO_ETH_LED0, pad_dir_open_drain); + gpio_function(GPIO_ETH_LED1, pad_gpio5); /* ETH LED0 */ + gpio_dir(GPIO_ETH_LED1, pad_dir_output); +#endif + sys_enable(sys_device_timer_wdt); + interrupt_attach(interrupt_timers, (int8_t)interrupt_timers, timer_ISR); + /* Timer A = 1ms */ + timer_prescaler(timer_select_a, 1000); + timer_init(timer_select_a, 100, timer_direction_down, timer_prescaler_select_on, timer_mode_continuous); + timer_enable_interrupt(timer_select_a); + timer_start(timer_select_a); + + // Setup VBUS detect GPIO. If the device is connected then this + // will set the MASK_SYS_PMCFG_DEV_DETECT_EN bit in PMCFG. + gpio_interrupt_disable(USBD_VBUS_DTC_PIN); + gpio_function(USBD_VBUS_DTC_PIN, pad_vbus_dtc); + gpio_pull(USBD_VBUS_DTC_PIN, pad_pull_pulldown); + gpio_dir(USBD_VBUS_DTC_PIN, pad_dir_input); + + interrupt_attach(interrupt_0, (int8_t)interrupt_0, board_pm_ISR); + +#ifdef GPIO_REMOTE_WAKEUP + //Configuring GPIO pin to wakeup. + // Set up the wakeup pin. + gpio_dir(GPIO_REMOTE_WAKEUP_PIN, pad_dir_input); + gpio_pull(GPIO_REMOTE_WAKEUP_PIN, pad_pull_pullup); + + // Attach an interrupt handler. + interrupt_attach(interrupt_gpio, (uint8_t)interrupt_gpio, gpio_ISR); + gpio_interrupt_enable(GPIO_REMOTE_WAKEUP_PIN, gpio_int_edge_falling); +#endif + + uart_disable_interrupt(UART0, uart_interrupt_tx); + uart_disable_interrupt(UART0, uart_interrupt_rx); + + // Enable all peripheral interrupts. + interrupt_enable_globally(); + + TU_LOG1("MM900EV1B board setup complete\r\n"); +}; + +void timer_ISR(void) +{ + if (timer_is_interrupted(timer_select_a)) + { + timer_ms++; + } +} + +#ifdef GPIO_REMOTE_WAKEUP +void gpio_ISR(void) +{ + if (gpio_is_interrupted(GPIO_REMOTE_WAKEUP_PIN)) + { + } +} +#endif + +/* Power management ISR */ +void board_pm_ISR(void) +{ + uint16_t pmcfg = SYS->PMCFG_H; + +#if defined(__FT930__) + if (pmcfg & MASK_SYS_PMCFG_SLAVE_PERI_IRQ_PEND) + { + // Clear d2xx hw engine wakeup. + SYS->PMCFG_H = MASK_SYS_PMCFG_SLAVE_PERI_IRQ_PEND; + } +#endif + if (pmcfg & MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND) + { + // Clear GPIO wakeup pending. + SYS->PMCFG_H = MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND; + } + +#if defined(__FT900__) + // USB device power management interrupts. + if (pmcfg & (MASK_SYS_PMCFG_DEV_CONN_DEV | + MASK_SYS_PMCFG_DEV_DIS_DEV | + MASK_SYS_PMCFG_HOST_RST_DEV | + MASK_SYS_PMCFG_HOST_RESUME_DEV) + ) + { +#if TUSB_OPT_DEVICE_ENABLED + ft90x_usbd_pm_ISR(pmcfg); +#endif + } +#endif +} + +#if TUSB_OPT_DEVICE_ENABLED +int8_t board_ft90x_vbus(void) +{ + return gpio_read(USBD_VBUS_DTC_PIN); +} +#endif + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +// Turn LED on or off +void board_led_write(bool state) +{ + gpio_write(GPIO_ETH_LED0, state); +} + +// Get the current state of button +// a '1' means active (pressed), a '0' means inactive. +uint32_t board_button_read(void) +{ + return 0; +} + +// Get characters from UART +int board_uart_read(uint8_t *buf, int len) +{ + int r = uart_readn(UART0, (uint8_t *)buf, len); + + return r; +} + +// Send characters to UART +int board_uart_write(void const *buf, int len) +{ + int r = uart_writen(UART0, (uint8_t *)buf, len); + + return r; +} + +// Get current milliseconds +uint32_t board_millis(void) +{ + uint32_t safe_ms; + + CRITICAL_SECTION_BEGIN + safe_ms = timer_ms; + CRITICAL_SECTION_END + + return safe_ms; +} diff --git a/hw/bsp/brtmm90x/family.mk b/hw/bsp/brtmm90x/family.mk new file mode 100644 index 000000000..57a141506 --- /dev/null +++ b/hw/bsp/brtmm90x/family.mk @@ -0,0 +1,35 @@ + +CROSS_COMPILE = ft32-elf- +DEPS_SUBMODULES += hw/mcu/bridgetek/ft90x/hardware +SKIP_NANOLIB = 1 + +# This is installed at "C:/Program Files(x86)/Bridgetek/FT9xx Toolchain/Toolchain/hardware" +FT90X_SDK = $(TOP)/hw/mcu/bridgetek/ft90x/hardware + +CFLAGS += \ + -D__FT900__ \ + -fvar-tracking \ + -fvar-tracking-assignments \ + -fmessage-length=0 \ + -ffunction-sections \ + -DCFG_TUSB_MCU=OPT_MCU_FT90X + +# lwip/src/core/raw.c:334:43: error: declaration of 'recv' shadows a global declaration +CFLAGS += -Wno-error=shadow +CFLAGS:=$(filter-out -Wcast-function-type,$(CFLAGS)) + +# All source paths should be relative to the top level. +LDINC += $(FT90X_SDK)/lib/Release +LIBS += -lft900 +LD_FILE = hw/mcu/bridgetek/ft90x/hardware/scripts/ldscript.ld +LDFLAGS += $(addprefix -L,$(LDINC)) \ + -Xlinker --entry=_start \ + -Wl,-lc + +SRC_C += src/portable/bridgetek/ft90x/dcd_ft90x.c + +#SRC_S += hw/mcu/bridgetek/ft90x/hardware/scripts/crt0.S + +INC += \ + $(FT90X_SDK)/include \ + $(TOP)/$(BOARD_PATH) diff --git a/hw/mcu/bridgetek/ft90x/Readme.md b/hw/mcu/bridgetek/ft90x/Readme.md new file mode 100644 index 000000000..e197f182e --- /dev/null +++ b/hw/mcu/bridgetek/ft90x/Readme.md @@ -0,0 +1,6 @@ +# BridgeTek FT9xx MCU + +**BridgeTek** provides a hardware abstraction library with software source code for the SDKs for FT9xx software family. +The pre-built libraries and the source code can be redistributed. +Registers definition files `/include/registers/ft900_registers.h` and included peripheral register definition files have licenses that allow for redistribution. +Whole SDK repository is installed as part of the FT9xx Toolchain and can be downloaded from BridgeTek web page `https://www.brtchip.com` diff --git a/hw/mcu/bridgetek/ft90x/hardware/scripts/crt0.S b/hw/mcu/bridgetek/ft90x/hardware/scripts/crt0.S new file mode 100644 index 000000000..62fa266ee --- /dev/null +++ b/hw/mcu/bridgetek/ft90x/hardware/scripts/crt0.S @@ -0,0 +1,286 @@ +.equ SYS_REGMSC0CFG_B3 , 0x1001b +.equ SYS_REGIRQCTL_B3 , 0x100e3 +.equ MAILBOX_MEMORY , 0x13000 + +.equ IS_IMG_SDBL_PRESENT, 0 +.equ IS_IMG_D2XX_PRESENT, 0 +.equ IS_IMG_DLOG_PRESENT, 0 + +.section .crt0 +.global _start + +_start: +# START Interrupt Vector Table [[ + jmp __PMSIZE-4 # RESET Vector + jmp interrupt_33 # Watchdog reset vector + jmp interrupt_0 + jmp interrupt_1 + jmp interrupt_2 + jmp interrupt_3 + jmp interrupt_4 + jmp interrupt_5 + jmp interrupt_6 + jmp interrupt_7 + jmp interrupt_8 + jmp interrupt_9 + jmp interrupt_10 + jmp interrupt_11 + jmp interrupt_12 + jmp interrupt_13 + jmp interrupt_14 + jmp interrupt_15 + jmp interrupt_16 + jmp interrupt_17 + jmp interrupt_18 + jmp interrupt_19 + jmp interrupt_20 + jmp interrupt_21 + jmp interrupt_22 + jmp interrupt_23 + jmp interrupt_24 + jmp interrupt_25 + jmp interrupt_26 + jmp interrupt_27 + jmp interrupt_28 + jmp interrupt_29 + jmp interrupt_30 + jmp interrupt_31 + jmp __PMSIZE-8 #Interrupt vector 32 (NMI) +# ]] END Interrupt Vector Table + +codestart: + jmp init + +.global _exithook +_exithook: # Debugger uses '_exithook' at 0x90 to catch program exit + return + +init: + # Disable all interrupts + ldk $r0,0x80 +.ifdef __FT930__ + sta.b 0x10123, $r0 +.else + sta.b 0x100e3,$r0 +.endif + + # Reset all peripherals + # lda.l $r0, 0x10018 + # bins.l $r0, $r0, 0x23F # Set bit 31 + # sta.l 0x10018, $r0 + + # Initialize DATA by copying from program memory + ldk.l $r0,__data_load_start + ldk.l $r1,__data_load_end + ldk.l $r2,0 # Will use __data after binutils patch + + jmp .dscopy +.dsloop: + # Copy PM[$r0] to RAM $r2 + lpmi.l $r3,$r0,0 + sti.l $r2,0,$r3 + add.l $r0,$r0,4 + add.l $r2,$r2,4 +.dscopy: + cmp.l $r0,$r1 + jmpc lt,.dsloop + + # Zero BSS + ldk.l $r0,_bss_start + ldk.l $r2,_end + sub.l $r2,$r2,$r0 + ldk.l $r1,0 + ldk $r3,32764 +1: + cmp $r2,$r3 + jmpc lt,2f + memset $r0,$r1,$r3 + add $r0,$r0,$r3 + sub $r2,$r2,$r3 + jmp 1b +2: + memset $r0,$r1,$r2 +.ifdef __FT930__ +/*##############################################################*/ + # copy UserConfig DATA from flash to mailbox memory +/*##############################################################*/ + ldk.l $r0,D2XX_Struct_start /*start of d2xx config in PM memory */ + ldk.l $r1,D2XX_Struct_end /*end of d2xx config in PM memory */ + ldk.l $r2,D2XXTEST_UserD2xxConfig /* RAM cache where the d2xx config from PM to be copied*/ + jmp .configcopy + +.configloop: + # Copy PM[$r0] to RAM[$r2] + lpmi.l $r3,$r0,0 + sti.l $r2,0,$r3 + # Increment + add.l $r0,$r0,4 + add.l $r2,$r2,4 +.configcopy: + cmp.l $r0,$r1 + jmpc lt,.configloop + + ldk.l $r1,D2XX_Struct_start + ldk.l $r2,D2XX_Struct_end + #compute size + sub.l $r2,$r2,$r1 + ldk.l $r1,D2XXTEST_UserD2xxConfig + ldk.l $r0,MAILBOX_MEMORY /* D2xx config from RAM cache to be copied to Mailbox memory */ + # Copy RAM[$r1] to Mailbox $r0, for $r2 bytes + streamouti.b $r0,$r1,$r2 +/*############################################################*/ +.endif + sub.l $sp,$sp,24 # Space for the caller argument frame + call main + +.equ EXITEXIT , 0x1fffc + +.global _exit +_exit: + sta.l EXITEXIT,$r0 # simulator end of test + jmp _exithook + +#_watchdog_isr: +# ldk $sp,__RAMSIZE +# jmp __PMSIZE-4 + +# Macro to construct the interrupt stub code. +# it just saves r0, loads r0 with the int vector +# and branches to interrupt_common. + +.macro inth i=0 +interrupt_\i: + push $r0 # { + lda $r0,(vector_table + 4 * \i) + jmp interrupt_common +.endm + + inth 0 + inth 1 + inth 2 + inth 3 + inth 4 + inth 5 + inth 6 + inth 7 + inth 8 + inth 9 + inth 10 + inth 11 + inth 12 + inth 13 + inth 14 + inth 15 + inth 16 + inth 17 + inth 18 + inth 19 + inth 20 + inth 21 + inth 22 + inth 23 + inth 24 + inth 25 + inth 26 + inth 27 + inth 28 + inth 29 + inth 30 + inth 31 + inth 32 + inth 33 + + # On entry: r0, already saved, holds the handler function +interrupt_common: + push $r1 # { + push $r2 # { + push $r3 # { + push $r4 # { + push $r5 # { + push $r6 # { + push $r7 # { + push $r8 # { + push $r9 # { + push $r10 # { + push $r11 # { + push $r12 # { + push $cc # { + + calli $r0 + + pop $cc # } + pop $r12 # } + pop $r11 # } + pop $r10 # } + pop $r9 # } + pop $r8 # } + pop $r7 # } + pop $r6 # } + pop $r5 # } + pop $r4 # } + pop $r3 # } + pop $r2 # } + pop $r1 # } + pop $r0 # } matching push in interrupt_0-31 above + reti + + # Null function for unassigned interrupt to point at +.global nullvector +nullvector: + return + +.section .data +.global vector_table + .align (4) # assembler alignment is in the power of 2 (in this case 2^4) +vector_table: + .rept 34 + .long nullvector + .endr + + +.section .text +.global __gxx_personality_sj0 +__gxx_personality_sj0: + + + .section ._flash_d2xx_config +.global __pD2XXDefaultConfiguration + .align (10) + +D2XX_partition_start = . + +.if IS_IMG_D2XX_PRESENT +.ifdef __FT930__ +.include "ft930_d2xx_default_config.inc" +.else +.include "ft900_d2xx_default_config.inc" +.endif +.endif + +D2XX_partition_end = . + + .section ._flash_dlog_partition + .align (10) +.global __dlog_partition +__dlog_partition: +dlog_partition_start = . +.if IS_IMG_DLOG_PRESENT + .long 0xF7D1D106 + .rept (0x1000-4) + .byte 0xFF + .endr +.endif +dlog_partition_end = . + + .section ._pm +.global __sdbl_partition_sizeof +.global __D2XX_partition_sizeof +.global __dlog_partition_sizeof + .if IS_IMG_SDBL_PRESENT +__sdbl_partition_sizeof = 0x2000 + .else +__sdbl_partition_sizeof = 0 + .endif + +__D2XX_partition_sizeof = D2XX_partition_end - D2XX_partition_start +__dlog_partition_sizeof = dlog_partition_end - dlog_partition_start diff --git a/hw/mcu/bridgetek/ft90x/hardware/scripts/ldscript.ld b/hw/mcu/bridgetek/ft90x/hardware/scripts/ldscript.ld new file mode 100644 index 000000000..d1b4d46cd --- /dev/null +++ b/hw/mcu/bridgetek/ft90x/hardware/scripts/ldscript.ld @@ -0,0 +1,94 @@ +/* Default linker script, for normal executables */ +OUTPUT_FORMAT("elf32-ft32") +OUTPUT_ARCH(ft32) +SEARCH_DIR("/data/win8/ft32/ft32-elf/lib"); +/* Allow the command line to override the memory region sizes. */ +__PMSIZE = DEFINED(__PMSIZE) ? __PMSIZE : 256K; +__RAMSIZE = DEFINED(__RAMSIZE) ? __RAMSIZE : 64K; +MEMORY +{ + flash (rx) : ORIGIN = 0, LENGTH = __PMSIZE + ram (rw!x) : ORIGIN = 0x800000, LENGTH = __RAMSIZE +} +SECTIONS +{ + .text : + { + *(.text*) + *(.strings) + *(._pm*) + *(.init) + *(.fini) + _etext = . ; + . = ALIGN(4); + } > flash + .tors : + { + ___ctors = . ; + *(.ctors) + ___ctors_end = . ; + ___dtors = . ; + *(.dtors) + ___dtors_end = . ; + . = ALIGN(4); + } > ram + .data : AT (ADDR (.text) + SIZEOF (.text)) + { + *(.data) + *(.data*) + *(.rodata) + *(.rodata*) + _edata = . ; + . = ALIGN(4); + } > ram + .bss SIZEOF(.data) + ADDR(.data) : + { + _bss_start = . ; + *(.bss) + *(.bss*) + *(COMMON) + _end = . ; + . = ALIGN(4); + } > ram + __data_load_start = LOADADDR(.data); + __data_load_end = __data_load_start + SIZEOF(.data); + .stab 0 (NOLOAD) : + { + *(.stab) + } + .stabstr 0 (NOLOAD) : + { + *(.stabstr) + } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* DWARF 3 */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + /* DWARF Extension. */ + .debug_macro 0 : { *(.debug_macro) } + .debug_addr 0 : { *(.debug_addr) } +} diff --git a/src/device/dcd_attr.h b/src/device/dcd_attr.h index a35fc0ac5..638a17814 100644 --- a/src/device/dcd_attr.h +++ b/src/device/dcd_attr.h @@ -151,6 +151,13 @@ #elif TU_CHECK_MCU(GD32VF103) #define DCD_ATTR_ENDPOINT_MAX 4 +//------------- BridgeTek -------------// +#elif TU_CHECK_MCU(FT90X) + #define DCD_ATTR_ENDPOINT_MAX 8 + +#elif TU_CHECK_MCU(FT93X) + #define DCD_ATTR_ENDPOINT_MAX 16 + #else #warning "DCD_ATTR_ENDPOINT_MAX is not defined for this MCU, default to 8" #define DCD_ATTR_ENDPOINT_MAX 8 diff --git a/src/portable/bridgetek/ft90x/dcd_ft90x.c b/src/portable/bridgetek/ft90x/dcd_ft90x.c new file mode 100644 index 000000000..ac13f11d1 --- /dev/null +++ b/src/portable/bridgetek/ft90x/dcd_ft90x.c @@ -0,0 +1,1101 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2018, hathach (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" +#include "bsp/board.h" + +#if TUSB_OPT_DEVICE_ENABLED && CFG_TUSB_MCU == OPT_MCU_FT90X + +#define USBD_USE_STREAMS + +#include +#include +#include +#include + +#include "device/dcd.h" + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ + +// Board code will determine the state of VBUS from USB host. +extern int8_t board_ft90x_vbus(void); + +// Static array to store an incoming SETUP request for processing by tinyusb. +static uint8_t _ft90x_setup_packet[8]; + +struct ft90x_xfer_state +{ + volatile int16_t total_size; // Total transfer size in bytes for this transfer. + volatile int16_t remain_size; // Total remaining in transfer. + volatile uint8_t *buff_ptr; // Pointer to buffer to transmit from or receive to. + volatile uint8_t valid; // Transfer is pending and total_size, remain_size, and buff_ptr are valid. + + uint8_t type; // Endpoint type. Of type USBD_ENDPOINT_TYPE from endpoint descriptor. + uint8_t dir; // Endpoint direction. TUSB_DIR_OUT or TUSB_DIR_IN. For control endpoint this is the current direction. + uint16_t buff_size; // Actual size of buffer RAM used by endpoint. + uint16_t size; // Max packet size for endpoint from endpoint descriptor. +}; +// Endpoint description array for each endpoint. +static struct ft90x_xfer_state ep_xfer[USBD_MAX_ENDPOINT_COUNT]; +// USB speed. +static tusb_speed_t _speed; + +// Interrupt handlers. +void _ft90x_usbd_ISR(void); // Interrupt handler for USB device. +void ft90x_usbd_pm_ISR(void); // Interrupt handler for USB device for power management (called by board). + +// Internal functions forward declarations. +static uint16_t _ft90x_edpt_xfer_out(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes); +static uint16_t _ft90x_edpt_xfer_in(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes); +static void _ft90x_reset_edpts(void); +static inline void _ft90x_phy_enable(bool en); +static void _ft90x_usb_speed(void); +static void _dcd_ft90x_attach(void); +static void _dcd_ft90x_detach(void) __attribute__((unused)); +static uint16_t _ft90x_dusb_in(uint8_t ep_number, const uint8_t *buffer, uint16_t length); +static uint16_t _ft90x_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t length); + +// Internal functions. + +// Manage an OUT transfer from the host. +// This can be up-to the maximum packet size of the endpoint. +// Continuation of a transfer beyond the maximum packet size is performed +// by the interrupt handler. +static uint16_t _ft90x_edpt_xfer_out(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes) +{ + //Note: this is called from only the interrupt handler when an OUT transfer is called. + uint16_t ep_size = ep_xfer[ep_number].size; + (void)ep_size; + if (xfer_bytes > ep_size) + { + xfer_bytes = ep_size; + } + + // Wait until the endpoint has finished - it should be complete! + //while (!(USBD_EP_SR_REG(ep_number) & MASK_USBD_EPxSR_OPRDY)) + //; + + // Send the first packet of max packet size + xfer_bytes = _ft90x_dusb_out(ep_number, (uint8_t *)buffer, xfer_bytes); + if (ep_number == USBD_EP_0) + { + // Set flags to indicate data ready. + USBD_EP_SR_REG(USBD_EP_0) = (MASK_USBD_EP0SR_OPRDY); + } + else + { + USBD_EP_SR_REG(ep_number) = (MASK_USBD_EPxSR_OPRDY); + } + + return xfer_bytes; +} + +// Manage an IN transfer to the host. +// This can be up-to the maximum packet size of the endpoint. +// Continuation of a transfer beyond the maximum packet size is performed +// by the interrupt handler. +static uint16_t _ft90x_edpt_xfer_in(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes) +{ + //Note: this may be called from the interrupt handler or from normal code. + uint8_t end = 0; + uint16_t ep_size = ep_xfer[ep_number].size; + (void)ep_size; + if ((xfer_bytes == 0) || (xfer_bytes < ep_size)) + { + end = 1; + } + else + { + xfer_bytes = ep_size; + } + + if (ep_number == USBD_EP_0) + { + // An IN direction SETUP can be interrupted by an OUT packet. + // This will result in a STALL generated by the silicon. + while (USBD_EP_SR_REG(USBD_EP_0) & MASK_USBD_EP0SR_STALL) + { + // Clear the STALL and finish the transaction. + USBD_EP_SR_REG(USBD_EP_0) = (MASK_USBD_EP0SR_STALL); + } + } + else + { + uint8_t sr_reg; + // If there is data to transmit then wait until the IN buffer + // for the endpoint is empty. + do + { + sr_reg = USBD_EP_SR_REG(ep_number); + } while (sr_reg & MASK_USBD_EPxSR_INPRDY); + + } + + xfer_bytes = _ft90x_dusb_in(ep_number, (uint8_t *)buffer, xfer_bytes); + + if (ep_number == USBD_EP_0) + { + if (end) + { + // Set flags to indicate data ready and transfer complete. + USBD_EP_SR_REG(USBD_EP_0) = MASK_USBD_EP0SR_INPRDY | MASK_USBD_EP0SR_DATAEND; + } + else + { + // Set flags to indicate data ready. + USBD_EP_SR_REG(USBD_EP_0) = (MASK_USBD_EP0SR_INPRDY); + } + } + else + { + // Set flags to indicate data ready. + USBD_EP_SR_REG(ep_number) = (MASK_USBD_EPxSR_INPRDY); + } + + return xfer_bytes; +} + +// Reset all endpoints to a default state. +// Control endpoint enabled and ready. All others disabled. +static void _ft90x_reset_edpts(void) +{ + // Disable all endpoints and remove configuration values. + // Clear settings. + tu_memclr(ep_xfer, sizeof(ep_xfer)); + for (int i = 0; i < USBD_MAX_ENDPOINT_COUNT; i++) + { + // Disable hardware. + USBD_EP_CR_REG(i) = 0; + } + + // Setup the control endpoint only. +#if CFG_TUD_ENDPOINT0_SIZE == 64 + USBD_EP_CR_REG(USBD_EP_0) = (USBD_EP0_MAX_SIZE_64 << BIT_USBD_EP0_MAX_SIZE); +#elif CFG_TUD_ENDPOINT0_SIZE == 32 + USBD_EP_CR_REG(USBD_EP_0) = (USBD_EP0_MAX_SIZE_32 << BIT_USBD_EP0_MAX_SIZE); +#elif CFG_TUD_ENDPOINT0_SIZE == 16 + USBD_EP_CR_REG(USBD_EP_0) = (USBD_EP0_MAX_SIZE_16 << BIT_USBD_EP0_MAX_SIZE); +#elif CFG_TUD_ENDPOINT0_SIZE == 8 + USBD_EP_CR_REG(USBD_EP_0) = (USBD_EP0_MAX_SIZE_8 << BIT_USBD_EP0_MAX_SIZE); +#else +#error "CFG_TUD_ENDPOINT0_SIZE must be defined with a value of 8, 16, 32 or 64." +#endif + // Configure the control endpoint. + ep_xfer[USBD_EP_0].size = CFG_TUD_ENDPOINT0_SIZE; + ep_xfer[USBD_EP_0].type = TUSB_XFER_CONTROL; + + // Enable interrupts from USB device control. + USBD_REG(cmie) = MASK_USBD_CMIE_ALL; + // Enable interrupts on EP0. + USBD_REG(epie) = (MASK_USBD_EPIE_EP0IE); +} + +// Enable or disable the USB PHY. +static inline void _ft90x_phy_enable(bool en) +{ + if (en) + SYS->PMCFG_L |= MASK_SYS_PMCFG_DEV_PHY_EN; + else + SYS->PMCFG_L &= ~MASK_SYS_PMCFG_DEV_PHY_EN; +} + +// Safely connect to the USB. +static void _dcd_ft90x_attach(void) +{ + uint8_t reg; + + CRITICAL_SECTION_BEGIN + // Disable device responses. + USBD_REG(faddr) = 0; + + // Reset USB Device. + SYS->MSC0CFG = SYS->MSC0CFG | MASK_SYS_MSC0CFG_DEV_RESET_ALL; + // Disable device connect/disconnect/host reset detection. + SYS->PMCFG_H = MASK_SYS_PMCFG_DEV_DIS_DEV; + SYS->PMCFG_H = MASK_SYS_PMCFG_DEV_CONN_DEV; + SYS->PMCFG_L = SYS->PMCFG_L & (~MASK_SYS_PMCFG_DEV_DETECT_EN); + + // Enable Chip USB device clock/PM configuration. + sys_enable(sys_device_usb_device); + CRITICAL_SECTION_END; + + // Wait a short time to get started. + delayms(1); + + CRITICAL_SECTION_BEGIN + // Turn off the device enable bit. +#if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED + USBD_REG(fctrl) = 0; +#else + //Set the full speed only bit if required. + USBD_REG(fctrl) = MASK_USBD_FCTRL_MODE_FS_ONLY; +#endif + + // Clear first reset and suspend interrupts. + do + { + reg = USBD_REG(cmif); + USBD_REG(cmif) = reg; + } while (reg); + // Clear any endpoint interrupts. + reg = USBD_REG(epif); + USBD_REG(epif) = reg; + + // Disable all interrupts from USB device control before attaching interrupt. + USBD_REG(cmie) = 0; + CRITICAL_SECTION_END; + + // Enable device connect/disconnect/host reset detection. + // Set device detect and remote wakeup enable interrupt enables. + SYS->PMCFG_L = SYS->PMCFG_L | MASK_SYS_PMCFG_DEV_DETECT_EN; + +#if defined(__FT930__) + // Setup VBUS detect + SYS->MSC0CFG = SYS->MSC0CFG | MASK_SYS_MSC0CFG_USB_VBUS_EN; +#endif +} + +// Gracefully disconnect from the USB. +static void _dcd_ft90x_detach(void) +{ + // Disable device connect/disconnect/host reset detection. + SYS->PMCFG_L = SYS->PMCFG_L & (~MASK_SYS_PMCFG_DEV_DETECT_EN); + +#if defined(__FT930__) + // Disable VBUS detection. + SYS->MSC0CFG = SYS->MSC0CFG & (~MASK_SYS_MSC0CFG_USB_VBUS_EN); +#endif + CRITICAL_SECTION_BEGIN + USBD_REG(epie) = 0; + USBD_REG(cmie) = 0; + CRITICAL_SECTION_END; + + // Disable the USB function. + USBD_REG(fctrl) = 0; + delayms(1); + + // Disable USB PHY + dcd_disconnect(0); + delayms(1); + + // Disable Chip USB device clock/PM configuration. + sys_disable(sys_device_usb_device); + + // Reset USB Device... Needed for Back voltage D+ to be <400mV + SYS->MSC0CFG = SYS->MSC0CFG | MASK_SYS_MSC0CFG_DEV_RESET_ALL; + + delayms(1); + // Set device detect and remote wakeup enable interrupt enables. + SYS->PMCFG_L = SYS->PMCFG_L | MASK_SYS_PMCFG_DEV_DETECT_EN; + +#if defined(__FT930__) + // Setup VBUS detect + SYS->MSC0CFG = SYS->MSC0CFG | MASK_SYS_MSC0CFG_USB_VBUS_EN; +#endif +} + +// Determine the speed of the USB to which we are connected. +// Set the speed of the PHY accordingly. +// High speed can be disabled through CFG_TUSB_RHPORT0_MODE settings. +static void _ft90x_usb_speed(void) +{ + uint8_t fctrl_val; + + // If USB device function is already enabled then disable it. + if (USBD_REG(fctrl) & MASK_USBD_FCTRL_USB_DEV_EN) { + USBD_REG(fctrl) = (USBD_REG(fctrl) & (~MASK_USBD_FCTRL_USB_DEV_EN)); + delayus(200); + } + +#if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED + + /* Detect high or full speed */ + fctrl_val = MASK_USBD_FCTRL_USB_DEV_EN; +#if defined(__FT900__) + if (!sys_check_ft900_revB())//if 90x series is rev C + { + fctrl_val |= MASK_USBD_FCTRL_IMP_PERF; + } +#endif + USBD_REG(fctrl) = fctrl_val; + +#if defined(__FT930__) + delayus(200); + + _speed = (SYS->MSC0CFG & MASK_SYS_MSC0CFG_HIGH_SPED_MODE) ? + TUSB_SPEED_HIGH : TUSB_SPEED_FULL; +#else /* __FT930__ */ + /* Detection by SOF */ + while (!(USBD_REG(cmif) & MASK_USBD_CMIF_SOFIRQ)); + USBD_REG(cmif) = MASK_USBD_CMIF_SOFIRQ; + delayus(125 + 5); + _speed = (USBD_REG(cmif) & MASK_USBD_CMIF_SOFIRQ) ? + TUSB_SPEED_HIGH : TUSB_SPEED_FULL; + dcd_event_bus_reset(0, _speed, true); + +#endif /* !__FT930__ */ + +#else /* CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED */ + + /* User force set to full speed */ + _speed = TUSB_SPEED_FULL; + fctrl_val = + MASK_USBD_FCTRL_USB_DEV_EN | MASK_USBD_FCTRL_MODE_FS_ONLY; +#if defined(__FT900__) + if (!sys_check_ft900_revB())//if 90x series is rev C + { + fctrl_val |= MASK_USBD_FCTRL_IMP_PERF; + } +#endif + USBD_REG(fctrl) = fctrl_val; + dcd_event_bus_reset(0, _speed, true); + return; + +#endif /* CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED */ +} + +// Send a buffer to the USB IN FIFO. +// When the macro USBD_USE_STREAMS is defined this will stream a buffer of data +// to the FIFO using the most efficient MCU streamout combination. +// If streaming is disabled then it will send each byte of the buffer in turn +// to the FIFO. The is no reason to not stream. +// The total number of bytes sent to the FIFO is returned. +static uint16_t _ft90x_dusb_in(uint8_t ep_number, const uint8_t *buffer, uint16_t length) +{ + uint16_t bytes_read = 0; + uint16_t buff_size = length; + +#ifdef USBD_USE_STREAMS + volatile uint8_t *data_reg; + + data_reg = (uint8_t *)&(USBD->ep[ep_number].epxfifo); + if (buff_size) + { + if (((uint32_t)buffer) % 4 == 0) + { + uint16_t aligned = buff_size & (~3); + uint16_t left = buff_size & 3; + + if (aligned) + { + __asm__ volatile("streamout.l %0,%1,%2" + : + : "r"(data_reg), "r"(buffer), "r"(aligned)); + buffer += aligned; + } + if (left) + { + __asm__ volatile("streamout.b %0,%1,%2" + : + : "r"(data_reg), "r"(buffer), "r"(left)); + } + } + else + { + __asm__ volatile("streamout.b %0,%1,%2" + : + : "r"(data_reg), "r"(buffer), "r"(buff_size)); + } + bytes_read = buff_size; + } +#else // USBD_USE_STREAMS + + bytes_read = buff_size; + while (buff_size--) + { + USBD_EP_FIFO_REG(ep_number) = *buffer++; + }; + +#endif // USBD_USE_STREAMS + + return bytes_read; +} + +// Receive a buffer from the USB OUT FIFO. +// When the macro USBD_USE_STREAMS is defined this will stream from the FIFO +// to a buffer of data using the most efficient MCU streamin combination. +// If streaming is disabled then it will receive each byte from the FIFO in turn +// to the buffer. The is no reason to not stream. +// The total number of bytes received from the FIFO is returned. +static uint16_t _ft90x_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t length) +{ +#ifdef USBD_USE_STREAMS + volatile uint8_t *data_reg; +#endif // USBD_USE_STREAMS + uint16_t bytes_read = 0; + uint16_t buff_size = length; + + if (length > 0) + { + if (ep_number == USBD_EP_0) + { + buff_size = USBD_EP_CNT_REG(USBD_EP_0); + } + else + { + if (USBD_EP_SR_REG(ep_number) & (MASK_USBD_EPxSR_OPRDY)) + { + buff_size = USBD_EP_CNT_REG(ep_number); + } + } + } + + // Only read as many bytes as we have space for. + if (buff_size > length) + buff_size = length; + +#ifdef USBD_USE_STREAMS + data_reg = (uint8_t *)&(USBD->ep[ep_number].epxfifo); + if (buff_size) + { + if ((uint32_t)buffer % 4 == 0) + { + uint16_t aligned = buff_size & (~3); + uint16_t left = buff_size & 3; + + if (aligned) + { + __asm__ volatile("streamin.l %0,%1,%2" + : + : "r"(buffer), "r"(data_reg), "r"(aligned)); + buffer += aligned; + } + if (left) + { + __asm__ volatile("streamin.b %0,%1,%2" + : + : "r"(buffer), "r"(data_reg), "r"(left)); + } + } + else + { + __asm__ volatile("streamin.b %0,%1,%2" + : + : "r"(buffer), "r"(data_reg), "r"(buff_size)); + } + bytes_read = buff_size; + } +#else // USBD_USE_STREAMS + + bytes_read = buff_size; + while (buff_size--) + { + *buffer++ = USBD_EP_FIFO_REG(ep_number); + } + +#endif // USBD_USE_STREAMS + + return bytes_read; +} + +/*------------------------------------------------------------------*/ +/* Device API + *------------------------------------------------------------------*/ + +// Initialize controller to device mode +void dcd_init(uint8_t rhport) +{ + TU_LOG2("FT90x initialisation\r\n"); + + _dcd_ft90x_attach(); + + //_ft90x_reset_edpts(void);//tu_memclr(ep_xfer, sizeof(ep_xfer)); + + interrupt_attach(interrupt_usb_device, (int8_t)interrupt_usb_device, _ft90x_usbd_ISR); + + dcd_connect(rhport); +} + +// Enable device interrupt +void dcd_int_enable(uint8_t rhport) +{ + (void)rhport; + TU_LOG3("FT90x int enable\r\n"); + + // Peripheral devices interrupt enable. + interrupt_enable_globally(); +} + +// Disable device interrupt +void dcd_int_disable(uint8_t rhport) +{ + (void)rhport; + TU_LOG3("FT90x int disable\r\n"); + + // Peripheral devices interrupt disable. + interrupt_disable_globally(); +} + +// Receive Set Address request, mcu port must also include status IN response +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + (void)rhport; + (void)dev_addr; + + // Respond with status. There is no checking that the address is in range. + dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); + + // Set the update bit for the address register. + dev_addr |= 0x80; + + // Modify the address register within a critical section. + CRITICAL_SECTION_BEGIN + { + USBD_REG(faddr) = dev_addr; + } + CRITICAL_SECTION_END; +} + +// Invoked when a control transfer's status stage is complete. +// May help DCD to prepare for next control transfer, this API is optional. +#if 0 // never called +void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) +{ + (void) rhport; + + if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && + request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD ) + { + if (request->bRequest == TUSB_REQ_SET_ADDRESS) + { + } + else if (request->bRequest == TUSB_REQ_SET_CONFIGURATION) + { + } + } +} +#endif // 0 + +// Wake up host +void dcd_remote_wakeup(uint8_t rhport) +{ + (void)rhport; + + SYS->MSC0CFG = SYS->MSC0CFG | MASK_SYS_MSC0CFG_DEV_RMWAKEUP; + + // Atleast 2 ms of delay needed for RESUME Data K state. + delayms(2); + + SYS->MSC0CFG &= ~MASK_SYS_MSC0CFG_DEV_RMWAKEUP; + + // Enable USB PHY and determine current bus speed. + dcd_connect(0); +} + +// Connect by enabling internal pull-up resistor on D+/D- +void dcd_connect(uint8_t rhport) +{ + (void)rhport; + TU_LOG2("FT90x connect\r\n"); + + CRITICAL_SECTION_BEGIN + // Is device connected? + if (board_ft90x_vbus()) + { + // Clear/disable address register. + USBD_REG(faddr) = 0; + _ft90x_phy_enable(true); + + // Determine bus speed and signal speed to tusb. + _ft90x_usb_speed(); + } + CRITICAL_SECTION_END; + + // Restore default endpoint state. + _ft90x_reset_edpts(); +} + +// Disconnect by disabling internal pull-up resistor on D+/D- +void dcd_disconnect(uint8_t rhport) +{ + (void)rhport; + TU_LOG2("FT90x disconnect\r\n"); + + // Disable the USB PHY. + _ft90x_phy_enable(false); +} + + +//--------------------------------------------------------------------+ +// Endpoint API +//--------------------------------------------------------------------+ + +// 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 ep_number = tu_edpt_number(ep_desc->bEndpointAddress); + uint8_t const ep_dir = tu_edpt_dir(ep_desc->bEndpointAddress); + uint8_t const ep_type = ep_desc->bmAttributes.xfer; + uint16_t const ep_size = ep_desc->wMaxPacketSize.size; + uint16_t ep_buff_size; + uint8_t ep_reg_size = USBD_EP_MAX_SIZE_8; + uint8_t ep_reg_data = 0; + int16_t total_ram; + + TU_LOG2("FT90x endpoint open %d %c\r\n", ep_number, ep_dir?'I':'O'); + + // Check that the requested endpoint number is allowable. + if (ep_number >= USBD_MAX_ENDPOINT_COUNT) + { + TU_LOG1("FT90x endpoint not valid: requested %d max %d\r\n", ep_number, USBD_MAX_ENDPOINT_COUNT); + return false; + } + + // Calculate the physical size of the endpoint as a power of 2. This may be more than + // the requested size. + while (ep_desc->wMaxPacketSize.size > (8 * (1 << ep_reg_size))) + { + ep_reg_size++; + } + if (ep_reg_size > USBD_EP_MAX_SIZE_1024) + { + TU_LOG1("FT90x endpoint size not valid: requested %d max 1024\r\n", ep_desc->wMaxPacketSize.size); + return false; + } + // Calculate actual amount of buffer RAM used by this endpoint. This may be more than the + // requested size. + ep_buff_size = 8 << ep_reg_size; + + if (ep_number > 0) + { + // Set EP cmd parameters... + ep_reg_data |= (ep_reg_size << BIT_USBD_EP_MAX_SIZE); + + if (ep_xfer[ep_number].type != USBD_EP_TYPE_DISABLED) + { + // This could be because an endpoint has been assigned with the same number. + // On FT90x, IN and OUT endpoints may not have the same number. e.g. There + // cannot been an 0x81 and 0x01 endpoint. + TU_LOG1("FT90x endpoint %d already assigned\r\n", ep_number); + return false; + } + + // Check that there is enough buffer RAM to allocate to this new endpoint. + // Available buffer RAM depends on the device revision. + // The IN and OUT buffer RAM should be the same size. + if (ep_dir == USBD_DIR_IN) + total_ram = USBD_RAMTOTAL_IN; + else + total_ram = USBD_RAMTOTAL_OUT; + // Work out how much has been allocated to existing endpoints. + // The total RAM allocated shoudl alsyes be a positive number as this + // algorithm should not let it go below zero. + for (int i = 1; i < USBD_MAX_ENDPOINT_COUNT; i++) + { + if (ep_xfer[i].type != USBD_EP_TYPE_DISABLED) + { + if (ep_xfer[i].dir == ep_dir) + { + total_ram -= ep_xfer[i].buff_size; + } + } + } + // The control endpoint is taken into account as well. + total_ram -= ep_xfer[0].buff_size; + // Make sure we have enough space. The corner case is having zero bytes + // free which means that total_ram must be signed as zero bytes free is + // allowable. + if (total_ram < ep_buff_size) + { + TU_LOG1("FT90x insufficient buffer RAM for endpoint %d\r\n", ep_number); + return false; + } + + // Set the type of this endpoint in the control register. + if (ep_type == USBD_EP_BULK) + ep_reg_data |= (USBD_EP_DIS_BULK << BIT_USBD_EP_CONTROL_DIS); + else if (ep_type == USBD_EP_INT) + ep_reg_data |= (USBD_EP_DIS_INT << BIT_USBD_EP_CONTROL_DIS); + else if (ep_type == USBD_EP_ISOC) + ep_reg_data |= (USBD_EP_DIS_ISO << BIT_USBD_EP_CONTROL_DIS); + // Set the direction of this endpoint in the control register. + if (ep_dir == USBD_DIR_IN) + ep_reg_data |= MASK_USBD_EPxCR_DIR; + // Do not perform double buffering. + //if ( != USBD_DB_OFF) + //ep_reg_data |= MASK_USBD_EPxCR_DB; + // Set the control endpoint for this endpoint. + USBD_EP_CR_REG(ep_number) = ep_reg_data; + TU_LOG2("FT90x endpoint setting %x\r\n", ep_reg_data); + } + else + { + // Set the control register for endpoint zero. + USBD_EP_CR_REG(USBD_EP_0) = (ep_reg_size << BIT_USBD_EP0_MAX_SIZE); + } + + // Store the endpoint characteristics for later reference. + ep_xfer[ep_number].dir = ep_dir; + ep_xfer[ep_number].type = ep_type; + ep_xfer[ep_number].size = ep_size; + ep_xfer[ep_number].buff_size = ep_buff_size; + + CRITICAL_SECTION_BEGIN + // Clear register transaction continuation and signalling state. + ep_xfer[ep_number].valid = 0; + ep_xfer[ep_number].buff_ptr = NULL; + ep_xfer[ep_number].total_size = 0; + ep_xfer[ep_number].remain_size = 0; + CRITICAL_SECTION_END + + return true; +} + +// Close all endpoints. +void dcd_edpt_close_all(uint8_t rhport) +{ + (void)rhport; + // Reset the endpoint configurations. + _ft90x_reset_edpts(); +} + +// 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) +{ + (void)rhport; + uint8_t ep_number = tu_edpt_number(ep_addr); + uint8_t dir = tu_edpt_dir(ep_addr); + uint16_t xfer_bytes; + bool status = false; + + // We will attempt to transfer the buffer. If it is less than or equal to the endpoint + // maximum packet size then the whole buffer will be transferred. If it is larger then + // the interrupt handler will transfer the remainder. + // ep_xfer is used to tell the interrupt handler what to do. + // ep_xfer can be used at interrupt level to continue transfers. + CRITICAL_SECTION_BEGIN + // Transfer currently in progress. + if (ep_xfer[ep_number].valid == 0) + { + status = true; + + ep_xfer[ep_number].total_size = total_bytes; + ep_xfer[ep_number].remain_size = total_bytes; + ep_xfer[ep_number].buff_ptr = buffer; + ep_xfer[ep_number].valid = 1; + + if (ep_number == USBD_EP_0) + { + ep_xfer[USBD_EP_0].dir = dir; + } + else + { + // Enable the interrupt for this endpoint allowing the interrupt handler to report + // continue the transfer and signal completion. + USBD_REG(epie) = USBD_REG(epie) | (1 << ep_number); + } + + if (dir == TUSB_DIR_IN) + { + // For IN transfers send the first packet as a starter. Interrupt handler to complete + // this if it is larger than one packet. + xfer_bytes = _ft90x_edpt_xfer_in(ep_number, buffer, total_bytes); + + ep_xfer[ep_number].buff_ptr += xfer_bytes; + ep_xfer[ep_number].remain_size -= xfer_bytes; + } + } + CRITICAL_SECTION_END + + return status; +} + +// Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack - optional, however, must be listed in usbd.c +bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes) +{ + (void)rhport; + (void)ep_addr; + (void)ff; + (void)total_bytes; + bool status = false; + return status; +} + +// Stall endpoint (non-control endpoint) +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + uint8_t ep_number = tu_edpt_number(ep_addr); + (void)rhport; + + CRITICAL_SECTION_BEGIN + if (ep_number == USBD_EP_0) + { + USBD_EP_CR_REG(USBD_EP_0) = USBD_EP_CR_REG(USBD_EP_0) | + MASK_USBD_EP0CR_SDSTL; + } + else + { + USBD_EP_CR_REG(ep_number) = USBD_EP_CR_REG(ep_number) | + MASK_USBD_EPxCR_SDSTL; + USBD_EP_SR_REG(ep_number) = MASK_USBD_EPxSR_CLR_TOGGLE | + MASK_USBD_EPxSR_FIFO_FLUSH; + } + CRITICAL_SECTION_END +} + +// Clear stall (non-control endpoint), data toggle is also reset to DATA0 +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + uint8_t ep_number = tu_edpt_number(ep_addr); + (void)rhport; + + if (ep_number > USBD_EP_0) + { + CRITICAL_SECTION_BEGIN + USBD_EP_CR_REG(ep_number) = USBD_EP_CR_REG(ep_number) & + (~MASK_USBD_EPxCR_SDSTL); + USBD_EP_SR_REG(ep_number) = MASK_USBD_EPxSR_CLR_TOGGLE; + + // Allow transfers to restart. + ep_xfer[ep_number].valid = 0; + ep_xfer[ep_number].remain_size = 0; + CRITICAL_SECTION_END + } +} + +// Interrupt handling. + +void _ft90x_usbd_ISR(void) +{ + tud_int_handler(0); // Resolves to dcd_int_handler(). +} + +void dcd_int_handler(uint8_t rhport) +{ + (void)rhport; + + // Read the Common Interrupt Flag Register. + uint8_t cmif = USBD_REG(cmif); + // Read the Endpoint Interrupt Flag Register. +#if defined(__FT930__) + // This is 16 bits on FT93x. + uint16_t epif = USBD_REG(epif); +#else + // This is 8 bits on FT90x. + uint8_t epif = USBD_REG(epif); +#endif + + if (cmif & MASK_USBD_CMIF_ALL) + { + // Clear all CMIF bits. + USBD_REG(cmif) = MASK_USBD_CMIF_ALL; + if (cmif & MASK_USBD_CMIF_PHYIRQ) //Handle PHY interrupt + { + } + if (cmif & MASK_USBD_CMIF_PIDIRQ) //Handle PIDIRQ interrupt + { + } + if (cmif & MASK_USBD_CMIF_CRC16IRQ) //Handle CRC16IRQ interrupt + { + } + if (cmif & MASK_USBD_CMIF_CRC5IRQ) //Handle CRC5 interrupt + { + } + if (cmif & MASK_USBD_CMIF_RSTIRQ) //Handle Reset interrupt + { + // Reset endpoints to default state. + _ft90x_reset_edpts(); + dcd_event_bus_reset(0, _speed, true); + } + if (cmif & MASK_USBD_CMIF_SUSIRQ) //Handle Suspend interrupt + { + dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); + } + if (cmif & MASK_USBD_CMIF_RESIRQ) //Handle Resume interrupt + { + dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); + } + if (cmif & MASK_USBD_CMIF_SOFIRQ) //Handle SOF interrupt + { + dcd_event_bus_signal(0, DCD_EVENT_SOF, true); + } + } + // Handle endpoint interrupts. + if (epif) + { + uint16_t xfer_bytes; + + // Check for EP0 interrupts pending. + if (epif & MASK_USBD_EPIF_EP0IRQ) + { + // Clear interrupt register. + USBD_REG(epif) = MASK_USBD_EPIF_EP0IRQ; + + // Test for an incoming SETUP request on the control endpoint. + if (USBD_EP_SR_REG(USBD_EP_0) & MASK_USBD_EP0SR_SETUP) + { + // If protocol STALL, End the STALL signalling. + if (USBD_EP_CR_REG(USBD_EP_0) & MASK_USBD_EP0CR_SDSTL) + { + // STALL end. + USBD_EP_CR_REG(USBD_EP_0) = USBD_EP_CR_REG(USBD_EP_0) & + (~MASK_USBD_EP0CR_SDSTL); + // Clear STALL send. + USBD_EP_SR_REG(USBD_EP_0) = MASK_USBD_EP0SR_STALL; + } + + // Host has sent a SETUP packet. Recieve this into the setup packet store. + _ft90x_dusb_out(USBD_EP_0, (uint8_t *)_ft90x_setup_packet, sizeof(USB_device_request)); + + // Send the packet to tinyusb. + dcd_event_setup_received(0, _ft90x_setup_packet, true); + + // Clear the interrupt that signals a SETUP packet is received. + USBD_EP_SR_REG(USBD_EP_0) = (MASK_USBD_EP0SR_SETUP); + + // Allow new transfers on the control endpoint. + ep_xfer[USBD_EP_0].valid = 0; + return; + } + else + { + // Check for a complete or partially complete transfers on EP0. + if (ep_xfer[USBD_EP_0].valid) + { + xfer_bytes = (uint16_t)ep_xfer[USBD_EP_0].total_size; + + // Transfer incoming data from an OUT packet to the buffer supplied. + if (ep_xfer[USBD_EP_0].dir == TUSB_DIR_OUT) + { + xfer_bytes = _ft90x_edpt_xfer_out(USBD_EP_0, (uint8_t *)ep_xfer[USBD_EP_0].buff_ptr, xfer_bytes); + } + // Now signal completion of data packet. + dcd_event_xfer_complete(0, (ep_xfer[USBD_EP_0].dir ? TUSB_DIR_IN_MASK : 0), xfer_bytes, XFER_RESULT_SUCCESS, true); + + // Allow new transfers on the control endpoint. + ep_xfer[USBD_EP_0].valid = 0; + } + } + } + else // !(epif & MASK_USBD_EPIF_EP0IRQ) + { + // Mask out currently disabled endpoints. + epif &= USBD_REG(epie); + + // Handle complete and partially complete transfers for each endpoint. + for (uint8_t ep_number = 1; ep_number < USBD_MAX_ENDPOINT_COUNT; ep_number++) + { + if ((epif & MASK_USBD_EPIF_IRQ(ep_number)) == 0) + { + // No pending interrupt for this endpoint. + continue; + } + + if (ep_xfer[ep_number].valid) + { + xfer_bytes = 0; + uint8_t ep_dirmask = (ep_xfer[ep_number].dir ? TUSB_DIR_IN_MASK : 0); + + // Clear interrupt register for this endpoint. + USBD_REG(epif) = MASK_USBD_EPIF_IRQ(ep_number); + + // Start or continue an OUT transfer. + if (ep_xfer[ep_number].dir == TUSB_DIR_OUT) + { + xfer_bytes = _ft90x_edpt_xfer_out(ep_number, + (uint8_t *)ep_xfer[ep_number].buff_ptr, + (uint16_t)ep_xfer[ep_number].remain_size); + + ep_xfer[ep_number].buff_ptr += xfer_bytes; + ep_xfer[ep_number].remain_size -= xfer_bytes; + } + // continue an IN transfer + else // if (ep_xfer[ep_number].dir == TUSB_DIR_IN) + { + if (ep_xfer[ep_number].remain_size > 0) + { + xfer_bytes = _ft90x_edpt_xfer_in(ep_number, + (uint8_t *)ep_xfer[ep_number].buff_ptr, + (uint16_t)ep_xfer[ep_number].remain_size); + + ep_xfer[ep_number].buff_ptr += xfer_bytes; + ep_xfer[ep_number].remain_size -= xfer_bytes; + } + } + + // When the transfer is complete... + if (ep_xfer[ep_number].remain_size == 0) + { + // Signal tinyUSB. + dcd_event_xfer_complete(0, ep_number | ep_dirmask, ep_xfer[ep_number].total_size, XFER_RESULT_SUCCESS, true); + + // Allow new transfers on this endpoint. + ep_xfer[ep_number].valid = 0; + + // Disable the interrupt for this endpoint now it is complete. + USBD_REG(epie) = USBD_REG(epie) & (~(1 << ep_number)); + } + } + } + } + } +} + +// Power management interrupt handler. +// This handles USB device related power management interrupts only. +void ft90x_usbd_pm_ISR(void) +{ + uint16_t pmcfg = SYS->PMCFG_H; + + // Main interrupt handler is responible for + if (pmcfg & MASK_SYS_PMCFG_DEV_CONN_DEV) + { + // Signal connection interrupt + SYS->PMCFG_H = MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND; + dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); + } + + if (pmcfg & MASK_SYS_PMCFG_DEV_DIS_DEV) + { + // Signal disconnection interrupt + SYS->PMCFG_H = MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND; + dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, true); + } + + if (pmcfg & MASK_SYS_PMCFG_HOST_RST_DEV) + { + // Signal Host Reset interrupt + SYS->PMCFG_H = MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND; + dcd_event_bus_signal(0, DCD_EVENT_BUS_RESET, true); + } + + if (pmcfg & MASK_SYS_PMCFG_HOST_RESUME_DEV) + { + // Signal Host Resume interrupt + SYS->PMCFG_H = MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND; + if (!(SYS->MSC0CFG & MASK_SYS_MSC0CFG_DEV_RMWAKEUP)) + { + // If we are driving K-state on Device USB port; + // We must maintain the 1ms requirement before resuming the phy + dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); + } + } +} + +#endif diff --git a/src/tusb_option.h b/src/tusb_option.h index a00f3489f..d04cb54f0 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -126,6 +126,10 @@ // GigaDevice #define OPT_MCU_GD32VF103 1600 ///< GigaDevice GD32VF103 +// BridgeTek +#define OPT_MCU_FT90X 1700 ///< BridgeTek FT90x +#define OPT_MCU_FT93X 1701 ///< BridgeTek FT93x + //--------------------------------------------------------------------+ // Supported OS //--------------------------------------------------------------------+ From bcecbfdc29f58ac019a36099a8c398650cd27191 Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Wed, 6 Oct 2021 09:15:33 +0100 Subject: [PATCH 002/504] Modify cdc_msc example for Bridgetek FT90x/FT93x Add in endpoint definitions for the Bridgetek devices in usb_descriptors.c and allow high speed in tusb_config.h. --- examples/device/cdc_msc/src/tusb_config.h | 3 ++- examples/device/cdc_msc/src/usb_descriptors.c | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/examples/device/cdc_msc/src/tusb_config.h b/examples/device/cdc_msc/src/tusb_config.h index bf6af06bc..2bf5248bf 100644 --- a/examples/device/cdc_msc/src/tusb_config.h +++ b/examples/device/cdc_msc/src/tusb_config.h @@ -48,7 +48,8 @@ // Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed #ifndef BOARD_DEVICE_RHPORT_SPEED #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ - CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56 || CFG_TUSB_MCU == OPT_MCU_SAMX7X) + CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56 || CFG_TUSB_MCU == OPT_MCU_SAMX7X || \ + CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X ) #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED #else #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED diff --git a/examples/device/cdc_msc/src/usb_descriptors.c b/examples/device/cdc_msc/src/usb_descriptors.c index 1a89ce561..565a5d60c 100644 --- a/examples/device/cdc_msc/src/usb_descriptors.c +++ b/examples/device/cdc_msc/src/usb_descriptors.c @@ -116,6 +116,16 @@ enum #define EPNUM_MSC_OUT 0x05 #define EPNUM_MSC_IN 0x84 +#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X + // FT9XX don't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_CDC_NOTIF 0x81 + #define EPNUM_CDC_OUT 0x02 + #define EPNUM_CDC_IN 0x83 + + #define EPNUM_MSC_OUT 0x04 + #define EPNUM_MSC_IN 0x85 + #else #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 From 37c5eeb51de532dfbd46ae528d4d99220932d6bd Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Wed, 6 Oct 2021 16:50:55 +0100 Subject: [PATCH 003/504] Rename directories to indicate that FT930 and FT900 devices are both covered by the same SDK and src/portable code. Board makefile includes __FT900__ macro for FT90x and __FT930__ macro for boards with FT93x. --- hw/bsp/brtmm90x/family.c | 6 +++--- hw/bsp/brtmm90x/family.mk | 14 +++++++------- hw/mcu/bridgetek/{ft90x => ft9xx}/Readme.md | 7 ++++--- .../{ft90x => ft9xx}/hardware/scripts/crt0.S | 0 .../{ft90x => ft9xx}/hardware/scripts/ldscript.ld | 0 .../{ft90x/dcd_ft90x.c => ft9xx/dcd_ft9xx.c} | 2 -- 6 files changed, 14 insertions(+), 15 deletions(-) rename hw/mcu/bridgetek/{ft90x => ft9xx}/Readme.md (52%) rename hw/mcu/bridgetek/{ft90x => ft9xx}/hardware/scripts/crt0.S (100%) rename hw/mcu/bridgetek/{ft90x => ft9xx}/hardware/scripts/ldscript.ld (100%) rename src/portable/bridgetek/{ft90x/dcd_ft90x.c => ft9xx/dcd_ft9xx.c} (99%) diff --git a/hw/bsp/brtmm90x/family.c b/hw/bsp/brtmm90x/family.c index 010704d92..6352f2324 100644 --- a/hw/bsp/brtmm90x/family.c +++ b/hw/bsp/brtmm90x/family.c @@ -28,7 +28,6 @@ #include #include "bsp/board.h" #include "board.h" -//#include "src/device/dcd.h" #if TUSB_OPT_DEVICE_ENABLED int8_t board_ft90x_vbus(void); // Board specific implementation of VBUS detection for USB device. @@ -67,16 +66,17 @@ void board_init(void) #if 1 gpio_function(GPIO_ETH_LED0, pad_gpio4); /* ETH LED0 */ gpio_dir(GPIO_ETH_LED0, pad_dir_open_drain); - gpio_function(GPIO_ETH_LED1, pad_gpio5); /* ETH LED0 */ + gpio_function(GPIO_ETH_LED1, pad_gpio5); /* ETH LED1 */ gpio_dir(GPIO_ETH_LED1, pad_dir_output); #endif + sys_enable(sys_device_timer_wdt); - interrupt_attach(interrupt_timers, (int8_t)interrupt_timers, timer_ISR); /* Timer A = 1ms */ timer_prescaler(timer_select_a, 1000); timer_init(timer_select_a, 100, timer_direction_down, timer_prescaler_select_on, timer_mode_continuous); timer_enable_interrupt(timer_select_a); timer_start(timer_select_a); + interrupt_attach(interrupt_timers, (int8_t)interrupt_timers, timer_ISR); // Setup VBUS detect GPIO. If the device is connected then this // will set the MASK_SYS_PMCFG_DEV_DETECT_EN bit in PMCFG. diff --git a/hw/bsp/brtmm90x/family.mk b/hw/bsp/brtmm90x/family.mk index 57a141506..42769c254 100644 --- a/hw/bsp/brtmm90x/family.mk +++ b/hw/bsp/brtmm90x/family.mk @@ -1,10 +1,10 @@ CROSS_COMPILE = ft32-elf- -DEPS_SUBMODULES += hw/mcu/bridgetek/ft90x/hardware +DEPS_SUBMODULES += hw/mcu/bridgetek/ft9xx/hardware SKIP_NANOLIB = 1 # This is installed at "C:/Program Files(x86)/Bridgetek/FT9xx Toolchain/Toolchain/hardware" -FT90X_SDK = $(TOP)/hw/mcu/bridgetek/ft90x/hardware +FT9XX_SDK = $(TOP)/hw/mcu/bridgetek/ft9xx/hardware CFLAGS += \ -D__FT900__ \ @@ -19,17 +19,17 @@ CFLAGS += -Wno-error=shadow CFLAGS:=$(filter-out -Wcast-function-type,$(CFLAGS)) # All source paths should be relative to the top level. -LDINC += $(FT90X_SDK)/lib/Release +LDINC += $(FT9XX_SDK)/lib/Release LIBS += -lft900 -LD_FILE = hw/mcu/bridgetek/ft90x/hardware/scripts/ldscript.ld +LD_FILE = hw/mcu/bridgetek/ft9xx/hardware/scripts/ldscript.ld LDFLAGS += $(addprefix -L,$(LDINC)) \ -Xlinker --entry=_start \ -Wl,-lc -SRC_C += src/portable/bridgetek/ft90x/dcd_ft90x.c +SRC_C += src/portable/bridgetek/ft9xx/dcd_ft9xx.c -#SRC_S += hw/mcu/bridgetek/ft90x/hardware/scripts/crt0.S +#SRC_S += hw/mcu/bridgetek/ft9xx/hardware/scripts/crt0.S INC += \ - $(FT90X_SDK)/include \ + $(FT9XX_SDK)/include \ $(TOP)/$(BOARD_PATH) diff --git a/hw/mcu/bridgetek/ft90x/Readme.md b/hw/mcu/bridgetek/ft9xx/Readme.md similarity index 52% rename from hw/mcu/bridgetek/ft90x/Readme.md rename to hw/mcu/bridgetek/ft9xx/Readme.md index e197f182e..1db91058c 100644 --- a/hw/mcu/bridgetek/ft90x/Readme.md +++ b/hw/mcu/bridgetek/ft9xx/Readme.md @@ -1,6 +1,7 @@ # BridgeTek FT9xx MCU **BridgeTek** provides a hardware abstraction library with software source code for the SDKs for FT9xx software family. -The pre-built libraries and the source code can be redistributed. -Registers definition files `/include/registers/ft900_registers.h` and included peripheral register definition files have licenses that allow for redistribution. -Whole SDK repository is installed as part of the FT9xx Toolchain and can be downloaded from BridgeTek web page `https://www.brtchip.com` + +Whole SDK repository is installed as part of the FT9xx Toolchain and can be downloaded from BridgeTek web page `https://www.brtchip.com`. + +Registers definition files, and included peripheral register definition files have licenses that allow for redistribution. diff --git a/hw/mcu/bridgetek/ft90x/hardware/scripts/crt0.S b/hw/mcu/bridgetek/ft9xx/hardware/scripts/crt0.S similarity index 100% rename from hw/mcu/bridgetek/ft90x/hardware/scripts/crt0.S rename to hw/mcu/bridgetek/ft9xx/hardware/scripts/crt0.S diff --git a/hw/mcu/bridgetek/ft90x/hardware/scripts/ldscript.ld b/hw/mcu/bridgetek/ft9xx/hardware/scripts/ldscript.ld similarity index 100% rename from hw/mcu/bridgetek/ft90x/hardware/scripts/ldscript.ld rename to hw/mcu/bridgetek/ft9xx/hardware/scripts/ldscript.ld diff --git a/src/portable/bridgetek/ft90x/dcd_ft90x.c b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c similarity index 99% rename from src/portable/bridgetek/ft90x/dcd_ft90x.c rename to src/portable/bridgetek/ft9xx/dcd_ft9xx.c index ac13f11d1..69b51fac7 100644 --- a/src/portable/bridgetek/ft90x/dcd_ft90x.c +++ b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c @@ -524,8 +524,6 @@ void dcd_init(uint8_t rhport) _dcd_ft90x_attach(); - //_ft90x_reset_edpts(void);//tu_memclr(ep_xfer, sizeof(ep_xfer)); - interrupt_attach(interrupt_usb_device, (int8_t)interrupt_usb_device, _ft90x_usbd_ISR); dcd_connect(rhport); From 9966b8a5d6d755c6b92140d617122acb39948f20 Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Wed, 6 Oct 2021 16:54:52 +0100 Subject: [PATCH 004/504] Change author in header to Bridgetek Pte Ltd. --- hw/bsp/brtmm90x/boards/mm900ev1b/board.h | 2 +- hw/bsp/brtmm90x/family.c | 2 +- src/portable/bridgetek/ft9xx/dcd_ft9xx.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/bsp/brtmm90x/boards/mm900ev1b/board.h b/hw/bsp/brtmm90x/boards/mm900ev1b/board.h index dfb566289..67f61237f 100644 --- a/hw/bsp/brtmm90x/boards/mm900ev1b/board.h +++ b/hw/bsp/brtmm90x/boards/mm900ev1b/board.h @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2021, Ha Thach (tinyusb.org) + * Copyright 2021 Bridgetek Pte Ltd * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/hw/bsp/brtmm90x/family.c b/hw/bsp/brtmm90x/family.c index 6352f2324..3bd16b817 100644 --- a/hw/bsp/brtmm90x/family.c +++ b/hw/bsp/brtmm90x/family.c @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright 2019 Sony Semiconductor Solutions Corporation + * Copyright 2021 Bridgetek Pte Ltd * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c index 69b51fac7..6dbef1614 100644 --- a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c +++ b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2018, hathach (tinyusb.org) + * Copyright 2021 Bridgetek Pte Ltd * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal From 8c40a74f295d93a62a0e7c8a873b6d7abcce19b1 Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Wed, 6 Oct 2021 17:13:44 +0100 Subject: [PATCH 005/504] Sort out board settings. --- .../boards/{mm900ev1b => mm900evxb}/board.h | 14 ++++---------- hw/bsp/brtmm90x/family.c | 6 +++--- src/portable/bridgetek/ft9xx/dcd_ft9xx.c | 3 ++- 3 files changed, 9 insertions(+), 14 deletions(-) rename hw/bsp/brtmm90x/boards/{mm900ev1b => mm900evxb}/board.h (85%) diff --git a/hw/bsp/brtmm90x/boards/mm900ev1b/board.h b/hw/bsp/brtmm90x/boards/mm900evxb/board.h similarity index 85% rename from hw/bsp/brtmm90x/boards/mm900ev1b/board.h rename to hw/bsp/brtmm90x/boards/mm900evxb/board.h index 67f61237f..57936fda5 100644 --- a/hw/bsp/brtmm90x/boards/mm900ev1b/board.h +++ b/hw/bsp/brtmm90x/boards/mm900evxb/board.h @@ -27,27 +27,21 @@ #ifndef BOARD_H_ #define BOARD_H_ +// Note: This definition file covers all MM900EV1B, MM900EV2B, and MM900EV3B boards. +// Each of these boards has an FT900 device. + #ifdef __cplusplus extern "C" { #endif -#if defined(__FT900__) #define GPIO_UART0_TX 48 #define GPIO_UART0_RX 49 #define GPIO_ETH_LED0 61 #define GPIO_ETH_LED1 62 #define GPIO_REMOTE_WAKEUP_PIN 18 #define USBD_VBUS_DTC_PIN 3 -#elif defined(__FT930__) -#define GPIO_UART0_TX 23 -#define GPIO_UART0_RX 22 -#define GPIO_ETH_LED0 4 -#define GPIO_ETH_LED1 5 -#define GPIO_REMOTE_WAKEUP_PIN 12 -#define USBD_VBUS_DTC_PIN 39 -#endif -//#define GPIO_REMOTE_WAKEUP +#define GPIO_REMOTE_WAKEUP #ifdef __cplusplus } diff --git a/hw/bsp/brtmm90x/family.c b/hw/bsp/brtmm90x/family.c index 3bd16b817..ed169655e 100644 --- a/hw/bsp/brtmm90x/family.c +++ b/hw/bsp/brtmm90x/family.c @@ -24,10 +24,10 @@ * This file is part of the TinyUSB stack. */ +#include "board.h" +#include "bsp/board.h" #include #include -#include "bsp/board.h" -#include "board.h" #if TUSB_OPT_DEVICE_ENABLED int8_t board_ft90x_vbus(void); // Board specific implementation of VBUS detection for USB device. @@ -42,7 +42,7 @@ volatile unsigned int timer_ms = 0; void board_pm_ISR(void); #define WELCOME_MSG "\x1B[2J\x1B[H" \ - "MM900EV1B board\r\n" + "MM900EVxB board\r\n" // Initialize on-board peripherals : led, button, uart and USB void board_init(void) diff --git a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c index 6dbef1614..9b08702ed 100644 --- a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c +++ b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c @@ -24,8 +24,9 @@ * This file is part of the TinyUSB stack. */ -#include "tusb_option.h" +#include "board.h" #include "bsp/board.h" +#include "tusb_option.h" #if TUSB_OPT_DEVICE_ENABLED && CFG_TUSB_MCU == OPT_MCU_FT90X From 5e6edecaa3594980198d8f687b3d97979ae85092 Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Thu, 7 Oct 2021 17:00:28 +0100 Subject: [PATCH 006/504] Streamline settings for board. --- hw/bsp/brtmm90x/family.mk | 2 +- src/portable/bridgetek/ft9xx/dcd_ft9xx.c | 54 +++++++++++++----------- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/hw/bsp/brtmm90x/family.mk b/hw/bsp/brtmm90x/family.mk index 42769c254..211f97f1b 100644 --- a/hw/bsp/brtmm90x/family.mk +++ b/hw/bsp/brtmm90x/family.mk @@ -12,7 +12,7 @@ CFLAGS += \ -fvar-tracking-assignments \ -fmessage-length=0 \ -ffunction-sections \ - -DCFG_TUSB_MCU=OPT_MCU_FT90X + -DCFG_TUSB_MCU=OPT_MCU_FT90X # lwip/src/core/raw.c:334:43: error: declaration of 'recv' shadows a global declaration CFLAGS += -Wno-error=shadow diff --git a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c index 9b08702ed..09ca2904f 100644 --- a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c +++ b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c @@ -24,11 +24,17 @@ * This file is part of the TinyUSB stack. */ +/* + * Contains code adapted from Bridgetek Pte Ltd via license terms stated + * in https://brtchip.com/BRTSourceCodeLicenseAgreement + */ + #include "board.h" #include "bsp/board.h" #include "tusb_option.h" -#if TUSB_OPT_DEVICE_ENABLED && CFG_TUSB_MCU == OPT_MCU_FT90X +#if TUSB_OPT_DEVICE_ENABLED && \ + (CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X) #define USBD_USE_STREAMS @@ -250,12 +256,12 @@ static void _dcd_ft90x_attach(void) CRITICAL_SECTION_BEGIN // Turn off the device enable bit. -#if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED +#if BOARD_DEVICE_RHPORT_SPEED == OPT_MODE_HIGH_SPEED USBD_REG(fctrl) = 0; -#else +#else // BOARD_DEVICE_RHPORT_SPEED == OPT_MODE_FULL_SPEED //Set the full speed only bit if required. USBD_REG(fctrl) = MASK_USBD_FCTRL_MODE_FS_ONLY; -#endif +#endif // BOARD_DEVICE_RHPORT_SPEED // Clear first reset and suspend interrupts. do @@ -301,7 +307,7 @@ static void _dcd_ft90x_detach(void) delayms(1); // Disable USB PHY - dcd_disconnect(0); + dcd_disconnect(BOARD_DEVICE_RHPORT_NUM); delayms(1); // Disable Chip USB device clock/PM configuration. @@ -333,7 +339,7 @@ static void _ft90x_usb_speed(void) delayus(200); } -#if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED +#if BOARD_DEVICE_RHPORT_SPEED == OPT_MODE_HIGH_SPEED /* Detect high or full speed */ fctrl_val = MASK_USBD_FCTRL_USB_DEV_EN; @@ -357,11 +363,11 @@ static void _ft90x_usb_speed(void) delayus(125 + 5); _speed = (USBD_REG(cmif) & MASK_USBD_CMIF_SOFIRQ) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL; - dcd_event_bus_reset(0, _speed, true); + dcd_event_bus_reset(BOARD_DEVICE_RHPORT_NUM, _speed, true); #endif /* !__FT930__ */ -#else /* CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED */ +#else // BOARD_DEVICE_RHPORT_SPEED == OPT_MODE_FULL_SPEED /* User force set to full speed */ _speed = TUSB_SPEED_FULL; @@ -374,10 +380,10 @@ static void _ft90x_usb_speed(void) } #endif USBD_REG(fctrl) = fctrl_val; - dcd_event_bus_reset(0, _speed, true); + dcd_event_bus_reset(BOARD_DEVICE_RHPORT_NUM, _speed, true); return; -#endif /* CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED */ +#endif // BOARD_DEVICE_RHPORT_SPEED } // Send a buffer to the USB IN FIFO. @@ -557,7 +563,7 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) (void)dev_addr; // Respond with status. There is no checking that the address is in range. - dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); + dcd_edpt_xfer(rhport, tu_edpt_addr(USBD_EP_0, TUSB_DIR_IN), NULL, 0); // Set the update bit for the address register. dev_addr |= 0x80; @@ -603,7 +609,7 @@ void dcd_remote_wakeup(uint8_t rhport) SYS->MSC0CFG &= ~MASK_SYS_MSC0CFG_DEV_RMWAKEUP; // Enable USB PHY and determine current bus speed. - dcd_connect(0); + dcd_connect(rhport); } // Connect by enabling internal pull-up resistor on D+/D- @@ -882,7 +888,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) void _ft90x_usbd_ISR(void) { - tud_int_handler(0); // Resolves to dcd_int_handler(). + tud_int_handler(BOARD_DEVICE_RHPORT_NUM); // Resolves to dcd_int_handler(). } void dcd_int_handler(uint8_t rhport) @@ -920,19 +926,19 @@ void dcd_int_handler(uint8_t rhport) { // Reset endpoints to default state. _ft90x_reset_edpts(); - dcd_event_bus_reset(0, _speed, true); + dcd_event_bus_reset(BOARD_DEVICE_RHPORT_NUM, _speed, true); } if (cmif & MASK_USBD_CMIF_SUSIRQ) //Handle Suspend interrupt { - dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); + dcd_event_bus_signal(BOARD_DEVICE_RHPORT_NUM, DCD_EVENT_SUSPEND, true); } if (cmif & MASK_USBD_CMIF_RESIRQ) //Handle Resume interrupt { - dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); + dcd_event_bus_signal(BOARD_DEVICE_RHPORT_NUM, DCD_EVENT_RESUME, true); } if (cmif & MASK_USBD_CMIF_SOFIRQ) //Handle SOF interrupt { - dcd_event_bus_signal(0, DCD_EVENT_SOF, true); + dcd_event_bus_signal(BOARD_DEVICE_RHPORT_NUM, DCD_EVENT_SOF, true); } } // Handle endpoint interrupts. @@ -963,7 +969,7 @@ void dcd_int_handler(uint8_t rhport) _ft90x_dusb_out(USBD_EP_0, (uint8_t *)_ft90x_setup_packet, sizeof(USB_device_request)); // Send the packet to tinyusb. - dcd_event_setup_received(0, _ft90x_setup_packet, true); + dcd_event_setup_received(BOARD_DEVICE_RHPORT_NUM, _ft90x_setup_packet, true); // Clear the interrupt that signals a SETUP packet is received. USBD_EP_SR_REG(USBD_EP_0) = (MASK_USBD_EP0SR_SETUP); @@ -985,7 +991,7 @@ void dcd_int_handler(uint8_t rhport) xfer_bytes = _ft90x_edpt_xfer_out(USBD_EP_0, (uint8_t *)ep_xfer[USBD_EP_0].buff_ptr, xfer_bytes); } // Now signal completion of data packet. - dcd_event_xfer_complete(0, (ep_xfer[USBD_EP_0].dir ? TUSB_DIR_IN_MASK : 0), xfer_bytes, XFER_RESULT_SUCCESS, true); + dcd_event_xfer_complete(BOARD_DEVICE_RHPORT_NUM, (ep_xfer[USBD_EP_0].dir ? TUSB_DIR_IN_MASK : 0), xfer_bytes, XFER_RESULT_SUCCESS, true); // Allow new transfers on the control endpoint. ep_xfer[USBD_EP_0].valid = 0; @@ -1042,7 +1048,7 @@ void dcd_int_handler(uint8_t rhport) if (ep_xfer[ep_number].remain_size == 0) { // Signal tinyUSB. - dcd_event_xfer_complete(0, ep_number | ep_dirmask, ep_xfer[ep_number].total_size, XFER_RESULT_SUCCESS, true); + dcd_event_xfer_complete(BOARD_DEVICE_RHPORT_NUM, ep_number | ep_dirmask, ep_xfer[ep_number].total_size, XFER_RESULT_SUCCESS, true); // Allow new transfers on this endpoint. ep_xfer[ep_number].valid = 0; @@ -1067,21 +1073,21 @@ void ft90x_usbd_pm_ISR(void) { // Signal connection interrupt SYS->PMCFG_H = MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND; - dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); + dcd_event_bus_signal(BOARD_DEVICE_RHPORT_NUM, DCD_EVENT_RESUME, true); } if (pmcfg & MASK_SYS_PMCFG_DEV_DIS_DEV) { // Signal disconnection interrupt SYS->PMCFG_H = MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND; - dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, true); + dcd_event_bus_signal(BOARD_DEVICE_RHPORT_NUM, DCD_EVENT_UNPLUGGED, true); } if (pmcfg & MASK_SYS_PMCFG_HOST_RST_DEV) { // Signal Host Reset interrupt SYS->PMCFG_H = MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND; - dcd_event_bus_signal(0, DCD_EVENT_BUS_RESET, true); + dcd_event_bus_signal(BOARD_DEVICE_RHPORT_NUM, DCD_EVENT_BUS_RESET, true); } if (pmcfg & MASK_SYS_PMCFG_HOST_RESUME_DEV) @@ -1092,7 +1098,7 @@ void ft90x_usbd_pm_ISR(void) { // If we are driving K-state on Device USB port; // We must maintain the 1ms requirement before resuming the phy - dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); + dcd_event_bus_signal(BOARD_DEVICE_RHPORT_NUM, DCD_EVENT_RESUME, true); } } } From 6a658007a5145147bd7435346f3617a7cda589b7 Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Wed, 27 Oct 2021 12:30:51 +0100 Subject: [PATCH 007/504] Changes to use ft90x-sdk as submodule or installed SDK from toolchain. --- hw/bsp/brtmm90x/family.mk | 57 ++++++++++++++----- .../ft9xx/{hardware => }/scripts/crt0.S | 0 .../ft9xx/{hardware => }/scripts/ldscript.ld | 1 + src/portable/bridgetek/ft9xx/dcd_ft9xx.c | 11 ++-- 4 files changed, 50 insertions(+), 19 deletions(-) rename hw/mcu/bridgetek/ft9xx/{hardware => }/scripts/crt0.S (100%) rename hw/mcu/bridgetek/ft9xx/{hardware => }/scripts/ldscript.ld (97%) diff --git a/hw/bsp/brtmm90x/family.mk b/hw/bsp/brtmm90x/family.mk index 211f97f1b..d47f4820c 100644 --- a/hw/bsp/brtmm90x/family.mk +++ b/hw/bsp/brtmm90x/family.mk @@ -1,11 +1,28 @@ - +# GCC prefix for FT90X compile tools. CROSS_COMPILE = ft32-elf- -DEPS_SUBMODULES += hw/mcu/bridgetek/ft9xx/hardware SKIP_NANOLIB = 1 -# This is installed at "C:/Program Files(x86)/Bridgetek/FT9xx Toolchain/Toolchain/hardware" -FT9XX_SDK = $(TOP)/hw/mcu/bridgetek/ft9xx/hardware +# Set to use FT90X prebuilt libraries. +FT90X_PREBUILT_LIBS = 1 +ifeq ($(FT90X_PREBUILT_LIBS),1) +# If the FT90X toolchain is installed on Windows systems then the SDK +# include files and prebuilt libraries are at: %FT90X_TOOLCHAIN%/hardware +FT9XX_SDK = $(FT90X_TOOLCHAIN)/hardware +else +# The submodule BRTSG-FOSS/ft90x-sdk contains header files and source +# code for the Bridgetek SDK. This can be used instead of the prebuilt +# library. +DEPS_SUBMODULES += hw/mcu/bridgetek/ft9xx/hardware +# The SDK can be used to load specific files from the Bridgetek SDK. +FT9XX_SDK = hw/mcu/bridgetek/ft9xx/hardware/Source +endif +# Add include files which are within the TinyUSB directory structure. +INC += \ + $(TOP)/hw/mcu/bridgetek/ft9xx/hardware/Source/include \ + $(TOP)/$(BOARD_PATH) + +# Add required C Compiler flags for FT90X. CFLAGS += \ -D__FT900__ \ -fvar-tracking \ @@ -16,20 +33,34 @@ CFLAGS += \ # lwip/src/core/raw.c:334:43: error: declaration of 'recv' shadows a global declaration CFLAGS += -Wno-error=shadow -CFLAGS:=$(filter-out -Wcast-function-type,$(CFLAGS)) -# All source paths should be relative to the top level. -LDINC += $(FT9XX_SDK)/lib/Release -LIBS += -lft900 -LD_FILE = hw/mcu/bridgetek/ft9xx/hardware/scripts/ldscript.ld +# Add include files outside the TinyUSB structure that are added manually. +CFLAGS += -I"$(FT9XX_SDK)/include" + +# Set Linker flags. +LD_FILE = hw/mcu/bridgetek/ft9xx/scripts/ldscript.ld LDFLAGS += $(addprefix -L,$(LDINC)) \ -Xlinker --entry=_start \ -Wl,-lc +# Additional Source files for FT90X. SRC_C += src/portable/bridgetek/ft9xx/dcd_ft9xx.c -#SRC_S += hw/mcu/bridgetek/ft9xx/hardware/scripts/crt0.S +# Linker library. +ifneq ($(FT90X_PREBUILT_LIBS),1) +# Optionally add in files from the Bridgetek SDK instead of the prebuilt +# library. These are the minimum required. +SRC_C += $(FT9XX_SDK)/src/sys.c +SRC_C += $(FT9XX_SDK)/src/interrupt.c +SRC_C += $(FT9XX_SDK)/src/delay.c +SRC_C += $(FT9XX_SDK)/src/timers.c +SRC_C += $(FT9XX_SDK)/src/uart_simple.c +SRC_C += $(FT9XX_SDK)/src/gpio.c +else +# Or if using the prebuilt libraries add them. +LDFLAGS += -L"$(FT9XX_SDK)/lib" +LIBS += -lft900 +endif -INC += \ - $(FT9XX_SDK)/include \ - $(TOP)/$(BOARD_PATH) +# Not required crt0 file for FT90X. Use compiler built-in file. +#SRC_S += hw/mcu/bridgetek/ft9xx/scripts/crt0.S diff --git a/hw/mcu/bridgetek/ft9xx/hardware/scripts/crt0.S b/hw/mcu/bridgetek/ft9xx/scripts/crt0.S similarity index 100% rename from hw/mcu/bridgetek/ft9xx/hardware/scripts/crt0.S rename to hw/mcu/bridgetek/ft9xx/scripts/crt0.S diff --git a/hw/mcu/bridgetek/ft9xx/hardware/scripts/ldscript.ld b/hw/mcu/bridgetek/ft9xx/scripts/ldscript.ld similarity index 97% rename from hw/mcu/bridgetek/ft9xx/hardware/scripts/ldscript.ld rename to hw/mcu/bridgetek/ft9xx/scripts/ldscript.ld index d1b4d46cd..987c2b2ba 100644 --- a/hw/mcu/bridgetek/ft9xx/hardware/scripts/ldscript.ld +++ b/hw/mcu/bridgetek/ft9xx/scripts/ldscript.ld @@ -9,6 +9,7 @@ MEMORY { flash (rx) : ORIGIN = 0, LENGTH = __PMSIZE ram (rw!x) : ORIGIN = 0x800000, LENGTH = __RAMSIZE + ehci_mmap (rw!x) : ORIGIN = 0x811000, LENGTH = 2K } SECTIONS { diff --git a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c index 09ca2904f..3235d0ef1 100644 --- a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c +++ b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c @@ -29,20 +29,19 @@ * in https://brtchip.com/BRTSourceCodeLicenseAgreement */ +#include +#include +#include + #include "board.h" #include "bsp/board.h" #include "tusb_option.h" #if TUSB_OPT_DEVICE_ENABLED && \ - (CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X) + (CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X) #define USBD_USE_STREAMS -#include -#include -#include -#include - #include "device/dcd.h" //--------------------------------------------------------------------+ From ba76b2e3395ca3cb5033d70e34a6fa9a6ff7373c Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Mon, 22 Nov 2021 10:33:07 +0000 Subject: [PATCH 008/504] Add submodule for ft90x SDK Add Bridgetek FT90x SDK as submodule. --- .gitmodules | 3 +++ hw/mcu/bridgetek/ft9xx/ft90x-sdk | 1 + 2 files changed, 4 insertions(+) create mode 160000 hw/mcu/bridgetek/ft9xx/ft90x-sdk diff --git a/.gitmodules b/.gitmodules index 4c86fd55c..e87b8750f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -127,3 +127,6 @@ [submodule "hw/mcu/gd/nuclei-sdk"] path = hw/mcu/gd/nuclei-sdk url = https://github.com/Nuclei-Software/nuclei-sdk.git +[submodule "hw/mcu/bridgetek/ft9xx/ft90x-sdk"] + path = hw/mcu/bridgetek/ft9xx/ft90x-sdk + url = https://github.com/BRTSG-FOSS/ft90x-sdk diff --git a/hw/mcu/bridgetek/ft9xx/ft90x-sdk b/hw/mcu/bridgetek/ft9xx/ft90x-sdk new file mode 160000 index 000000000..a94bec485 --- /dev/null +++ b/hw/mcu/bridgetek/ft9xx/ft90x-sdk @@ -0,0 +1 @@ +Subproject commit a94bec4856b7e0f1dfda57307b66e3edb2c5a3c7 From edf3f3501656b010ad4a9e1d0a0d62573dd0b3fb Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Mon, 22 Nov 2021 12:38:04 +0000 Subject: [PATCH 009/504] Update ft90x-sdk Update submodule for FT90X SDK to point to the v2.5.0 release code currently in main. --- hw/mcu/bridgetek/ft9xx/ft90x-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/mcu/bridgetek/ft9xx/ft90x-sdk b/hw/mcu/bridgetek/ft9xx/ft90x-sdk index a94bec485..e8122eb6b 160000 --- a/hw/mcu/bridgetek/ft9xx/ft90x-sdk +++ b/hw/mcu/bridgetek/ft9xx/ft90x-sdk @@ -1 +1 @@ -Subproject commit a94bec4856b7e0f1dfda57307b66e3edb2c5a3c7 +Subproject commit e8122eb6bd6286a1fe31f175a3e3eb0e7770c3e3 From a994540860306e7da80a6925633f1ac8486fbfd9 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 23 Nov 2021 09:36:28 +0700 Subject: [PATCH 010/504] fix nrf easy dma race condition --- src/class/cdc/cdc_device.c | 10 +- src/portable/nordic/nrf5x/dcd_nrf5x.c | 128 +++++++++++++------------- 2 files changed, 71 insertions(+), 67 deletions(-) diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 74c116192..08f2af253 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -80,7 +80,7 @@ typedef struct //--------------------------------------------------------------------+ CFG_TUSB_MEM_SECTION static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; -static void _prep_out_transaction (cdcd_interface_t* p_cdc) +static bool _prep_out_transaction (cdcd_interface_t* p_cdc) { uint8_t const rhport = TUD_OPT_RHPORT; uint16_t available = tu_fifo_remaining(&p_cdc->rx_ff); @@ -89,21 +89,23 @@ static void _prep_out_transaction (cdcd_interface_t* p_cdc) // 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 >= sizeof(p_cdc->epout_buf), ); + TU_VERIFY(available >= sizeof(p_cdc->epout_buf)); // claim endpoint - TU_VERIFY(usbd_edpt_claim(rhport, p_cdc->ep_out), ); + TU_VERIFY(usbd_edpt_claim(rhport, p_cdc->ep_out)); // fifo can be changed before endpoint is claimed available = tu_fifo_remaining(&p_cdc->rx_ff); if ( available >= sizeof(p_cdc->epout_buf) ) { - usbd_edpt_xfer(rhport, p_cdc->ep_out, p_cdc->epout_buf, sizeof(p_cdc->epout_buf)); + return usbd_edpt_xfer(rhport, p_cdc->ep_out, p_cdc->epout_buf, sizeof(p_cdc->epout_buf)); }else { // Release endpoint since we don't make any transfer usbd_edpt_release(rhport, p_cdc->ep_out); + + return false; } } diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 9d7db11b2..b10a29083 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -63,7 +63,7 @@ typedef struct uint8_t* buffer; uint16_t total_len; volatile uint16_t actual_len; - uint16_t mps; // max packet size + uint16_t mps; // max packet size // nRF will auto accept OUT packet after DMA is done // indicate packet is already ACK @@ -84,8 +84,6 @@ static struct // Number of pending DMA that is started but not handled yet by dcd_int_handler(). // Since nRF can only carry one DMA can run at a time, this value is normally be either 0 or 1. - // However, in critical section with interrupt disabled, the DMA can be finished and added up - // until handled by dcd_int_handler() when exiting critical section. volatile uint8_t dma_pending; }_dcd; @@ -115,67 +113,68 @@ TU_ATTR_ALWAYS_INLINE static inline bool is_in_isr(void) } // helper to start DMA +static void start_dma(volatile uint32_t* reg_startep) +{ + _dcd.dma_pending = true; + + (*reg_startep) = 1; + __ISB(); __DSB(); + + // TASKS_EP0STATUS, TASKS_EP0RCVOUT seem to need EasyDMA to be available + // However these don't trigger any DMA transfer and got ENDED event subsequently + // Therefore dma_pending is corrected right away + if ( (reg_startep == &NRF_USBD->TASKS_EP0STATUS) || (reg_startep == &NRF_USBD->TASKS_EP0RCVOUT) ) + { + _dcd.dma_pending = false; + } +} + +// only 1 EasyDMA can be active at any time // TODO use Cortex M4 LDREX and STREX command (atomic) to have better mutex access to EasyDMA // since current implementation does not 100% guarded against race condition static void edpt_dma_start(volatile uint32_t* reg_startep) { - // Only one dma can be active - if ( _dcd.dma_pending ) + // Called in critical section i.e within USB ISR, or USB/Global interrupt disabled + if ( is_in_isr() || __get_PRIMASK() || !NVIC_GetEnableIRQ(USBD_IRQn) ) { - if (is_in_isr()) + if (_dcd.dma_pending) { - // Called within ISR, use usbd task to defer later + //use usbd task to defer later usbd_defer_func((osal_task_func_t) edpt_dma_start, (void*) (uintptr_t) reg_startep, true); - return; - } - else + }else { - if ( __get_PRIMASK() || !NVIC_GetEnableIRQ(USBD_IRQn) ) - { - // Called in critical section with interrupt disabled. We have to manually check - // for the DMA complete by comparing current pending DMA with number of ENDED Events - uint32_t ended = 0; + start_dma(reg_startep); + } + }else + { + // Called in non-critical thread-mode, should be 99% of the time. + // Should be safe to blocking wait until previous DMA transfer complete + uint8_t const rhport = 0; + bool started = false; + while(!started) + { + // LDREX/STREX may be needed in form of std atomic (required C11) or + // use osal mutex to guard against multiple core MCUs such as nRF53 + dcd_int_disable(rhport); - while ( _dcd.dma_pending > ((uint8_t) ended) ) - { - ended = NRF_USBD->EVENTS_ENDISOIN + NRF_USBD->EVENTS_ENDISOOUT; - - for (uint8_t i=0; iEVENTS_ENDEPIN[i] + NRF_USBD->EVENTS_ENDEPOUT[i]; - } - } - }else + if ( !_dcd.dma_pending ) { - // Called in non-critical thread-mode, should be 99% of the time. - // Should be safe to blocking wait until previous DMA transfer complete - while ( _dcd.dma_pending ) { } + start_dma(reg_startep); + started = true; } + + dcd_int_enable(rhport); + + // osal_yield(); } } - - _dcd.dma_pending++; - - (*reg_startep) = 1; - __ISB(); __DSB(); } // DMA is complete static void edpt_dma_end(void) { TU_ASSERT(_dcd.dma_pending, ); - _dcd.dma_pending = 0; -} - -// helper to set TASKS_EP0STATUS / TASKS_EP0RCVOUT since they also need EasyDMA -// However TASKS_EP0STATUS doesn't trigger any DMA transfer and got ENDED event subsequently -// Therefore dma_running state will be corrected right away -void start_ep0_task(volatile uint32_t* reg_task) -{ - edpt_dma_start(reg_task); - - // correct the dma_running++ in dma start - if (_dcd.dma_pending) _dcd.dma_pending--; + _dcd.dma_pending = false; } // helper getting td @@ -194,7 +193,10 @@ static void xact_out_dma(uint8_t epnum) { xact_len = NRF_USBD->SIZE.ISOOUT; // If ZERO bit is set, ignore ISOOUT length - if (xact_len & USBD_SIZE_ISOOUT_ZERO_Msk) xact_len = 0; + if (xact_len & USBD_SIZE_ISOOUT_ZERO_Msk) + { + xact_len = 0; + } else { // Trigger DMA move data from Endpoint -> SRAM @@ -216,8 +218,8 @@ static void xact_out_dma(uint8_t epnum) edpt_dma_start(&NRF_USBD->TASKS_STARTEPOUT[epnum]); } - xfer->buffer += xact_len; - xfer->actual_len += xact_len; +// xfer->buffer += xact_len; +// xfer->actual_len += xact_len; } // Prepare for a CBI transaction IN, call at the start @@ -232,7 +234,7 @@ static void xact_in_dma(uint8_t epnum) NRF_USBD->EPIN[epnum].PTR = (uint32_t) xfer->buffer; NRF_USBD->EPIN[epnum].MAXCNT = xact_len; - xfer->buffer += xact_len; + //xfer->buffer += xact_len; edpt_dma_start(&NRF_USBD->TASKS_STARTEPIN[epnum]); } @@ -242,6 +244,7 @@ static void xact_in_dma(uint8_t epnum) //--------------------------------------------------------------------+ void dcd_init (uint8_t rhport) { + TU_LOG1("dcd init\r\n"); (void) rhport; } @@ -466,7 +469,7 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t if ( control_status ) { // Status Phase also requires EasyDMA has to be available as well !!!! - start_ep0_task(&NRF_USBD->TASKS_EP0STATUS); + edpt_dma_start(&NRF_USBD->TASKS_EP0STATUS); // The nRF doesn't interrupt on status transmit so we queue up a success response. dcd_event_xfer_complete(0, ep_addr, 0, XFER_RESULT_SUCCESS, is_in_isr()); @@ -476,7 +479,7 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t if ( epnum == 0 ) { // Accept next Control Out packet. TASKS_EP0RCVOUT also require EasyDMA - start_ep0_task(&NRF_USBD->TASKS_EP0RCVOUT); + edpt_dma_start(&NRF_USBD->TASKS_EP0RCVOUT); }else { if ( xfer->data_received ) @@ -522,7 +525,6 @@ void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) // There maybe data in endpoint fifo already, we need to pull it out if ( (dir == TUSB_DIR_OUT) && xfer->data_received ) { - TU_LOG_LOCATION(); xfer->data_received = false; xact_out_dma(epnum); } @@ -717,7 +719,8 @@ void dcd_int_handler(uint8_t rhport) if ( int_status & EDPT_END_ALL_MASK ) { - // DMA complete move data from SRAM -> Endpoint + // DMA complete move data from SRAM <-> Endpoint + // Must before endpoint transfer handling edpt_dma_end(); } @@ -732,7 +735,7 @@ void dcd_int_handler(uint8_t rhport) * - Host -> Endpoint * EPDATA (or EP0DATADONE) interrupted, check EPDATASTATUS.EPOUT[i] * to start DMA. For Bulk/Interrupt, this step can occur automatically (without sw), - * which means data may or may not be ready (data_received flag). + * which means data may or may not be ready (out_received flag). * - Endpoint -> RAM * ENDEPOUT[i] interrupted, transaction complete, sw prepare next transaction * @@ -764,20 +767,16 @@ void dcd_int_handler(uint8_t rhport) xfer_td_t* xfer = get_td(epnum, TUSB_DIR_OUT); uint8_t const xact_len = NRF_USBD->EPOUT[epnum].AMOUNT; + xfer->buffer += xact_len; + xfer->actual_len += xact_len; + // Transfer complete if transaction len < Max Packet Size or total len is transferred if ( (epnum != EP_ISO_NUM) && (xact_len == xfer->mps) && (xfer->actual_len < xfer->total_len) ) { if ( epnum == 0 ) { // Accept next Control Out packet. TASKS_EP0RCVOUT also require EasyDMA - if ( _dcd.dma_pending ) - { - // use usbd task to defer later - usbd_defer_func((osal_task_func_t) start_ep0_task, (void*) (uintptr_t) &NRF_USBD->TASKS_EP0RCVOUT, true); - }else - { - start_ep0_task(&NRF_USBD->TASKS_EP0RCVOUT); - } + edpt_dma_start(&NRF_USBD->TASKS_EP0RCVOUT); }else { // nRF auto accept next Bulk/Interrupt OUT packet @@ -814,8 +813,10 @@ void dcd_int_handler(uint8_t rhport) if ( tu_bit_test(data_status, epnum) || (epnum == 0 && is_control_in) ) { xfer_td_t* xfer = get_td(epnum, TUSB_DIR_IN); + uint8_t const xact_len = NRF_USBD->EPIN[epnum].AMOUNT; // MAXCNT - xfer->actual_len += NRF_USBD->EPIN[epnum].MAXCNT; + xfer->buffer += xact_len; + xfer->actual_len += xact_len; if ( xfer->actual_len < xfer->total_len ) { @@ -842,6 +843,7 @@ void dcd_int_handler(uint8_t rhport) }else { // Data overflow !!! Nah, nRF will auto accept next Bulk/Interrupt OUT packet + // If USBD is already queued this // Mark this endpoint with data received xfer->data_received = true; } From 0fc11746c0e6d9f64750e02d1d46d901c11e0373 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 23 Nov 2021 09:46:45 +0700 Subject: [PATCH 011/504] clean up --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index b10a29083..bee9fc0b6 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -217,9 +217,6 @@ static void xact_out_dma(uint8_t epnum) edpt_dma_start(&NRF_USBD->TASKS_STARTEPOUT[epnum]); } - -// xfer->buffer += xact_len; -// xfer->actual_len += xact_len; } // Prepare for a CBI transaction IN, call at the start @@ -234,8 +231,6 @@ static void xact_in_dma(uint8_t epnum) NRF_USBD->EPIN[epnum].PTR = (uint32_t) xfer->buffer; NRF_USBD->EPIN[epnum].MAXCNT = xact_len; - //xfer->buffer += xact_len; - edpt_dma_start(&NRF_USBD->TASKS_STARTEPIN[epnum]); } @@ -813,7 +808,7 @@ void dcd_int_handler(uint8_t rhport) if ( tu_bit_test(data_status, epnum) || (epnum == 0 && is_control_in) ) { xfer_td_t* xfer = get_td(epnum, TUSB_DIR_IN); - uint8_t const xact_len = NRF_USBD->EPIN[epnum].AMOUNT; // MAXCNT + uint8_t const xact_len = NRF_USBD->EPIN[epnum].AMOUNT; xfer->buffer += xact_len; xfer->actual_len += xact_len; @@ -843,7 +838,6 @@ void dcd_int_handler(uint8_t rhport) }else { // Data overflow !!! Nah, nRF will auto accept next Bulk/Interrupt OUT packet - // If USBD is already queued this // Mark this endpoint with data received xfer->data_received = true; } From c9e9f4785f68c9f9e99c4832af8615847c5fae92 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 23 Nov 2021 09:52:11 +0700 Subject: [PATCH 012/504] more clean up --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index bee9fc0b6..2bcd56b8a 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -82,9 +82,8 @@ static struct // +1 for ISO endpoints xfer_td_t xfer[EP_CBI_COUNT + 1][2]; - // Number of pending DMA that is started but not handled yet by dcd_int_handler(). - // Since nRF can only carry one DMA can run at a time, this value is normally be either 0 or 1. - volatile uint8_t dma_pending; + // nRF can only carry one DMA at a time, this is used to guard the access to EasyDMA + volatile bool dma_running; }_dcd; /*------------------------------------------------------------------*/ @@ -115,7 +114,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool is_in_isr(void) // helper to start DMA static void start_dma(volatile uint32_t* reg_startep) { - _dcd.dma_pending = true; + _dcd.dma_running = true; (*reg_startep) = 1; __ISB(); __DSB(); @@ -125,7 +124,7 @@ static void start_dma(volatile uint32_t* reg_startep) // Therefore dma_pending is corrected right away if ( (reg_startep == &NRF_USBD->TASKS_EP0STATUS) || (reg_startep == &NRF_USBD->TASKS_EP0RCVOUT) ) { - _dcd.dma_pending = false; + _dcd.dma_running = false; } } @@ -137,7 +136,7 @@ static void edpt_dma_start(volatile uint32_t* reg_startep) // Called in critical section i.e within USB ISR, or USB/Global interrupt disabled if ( is_in_isr() || __get_PRIMASK() || !NVIC_GetEnableIRQ(USBD_IRQn) ) { - if (_dcd.dma_pending) + if (_dcd.dma_running) { //use usbd task to defer later usbd_defer_func((osal_task_func_t) edpt_dma_start, (void*) (uintptr_t) reg_startep, true); @@ -157,7 +156,7 @@ static void edpt_dma_start(volatile uint32_t* reg_startep) // use osal mutex to guard against multiple core MCUs such as nRF53 dcd_int_disable(rhport); - if ( !_dcd.dma_pending ) + if ( !_dcd.dma_running ) { start_dma(reg_startep); started = true; @@ -173,8 +172,8 @@ static void edpt_dma_start(volatile uint32_t* reg_startep) // DMA is complete static void edpt_dma_end(void) { - TU_ASSERT(_dcd.dma_pending, ); - _dcd.dma_pending = false; + TU_ASSERT(_dcd.dma_running, ); + _dcd.dma_running = false; } // helper getting td From 225e7182707510bc57fb433271a41ccd13c55624 Mon Sep 17 00:00:00 2001 From: Mengsk Date: Thu, 25 Nov 2021 17:20:51 +0100 Subject: [PATCH 013/504] Update iar project template. --- tools/iar_template.ipcf | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/tools/iar_template.ipcf b/tools/iar_template.ipcf index b8e50a1d2..ba54fe057 100644 --- a/tools/iar_template.ipcf +++ b/tools/iar_template.ipcf @@ -41,7 +41,8 @@ $TUSB_DIR$/src/class/msc/msc_host.c - $TUSB_DIR$/src/class/net/net_device.c + $TUSB_DIR$/src/class/net/ecm_rndis_device.c + $TUSB_DIR$/src/class/net/ncm_device.c $TUSB_DIR$/src/class/usbtmc/usbtmc_device.c @@ -58,6 +59,9 @@ $TUSB_DIR$/src/host/usbh.c $TUSB_DIR$/src/host/usbh_control.c + + $TUSB_DIR$/src/portable/synopsys/dwc2/dcd_dwc2.c + $TUSB_DIR$/src/portable/dialog/da146xx/dcd_da146xx.c @@ -67,6 +71,9 @@ $TUSB_DIR$/src/portable/espressif/esp32sx/dcd_esp32sx.c + + $TUSB_DIR$/src/portable/mentor/musb/dcd_musb.c + $TUSB_DIR$/src/portable/microchip/samd/dcd_samd.c @@ -116,21 +123,12 @@ $TUSB_DIR$/src/portable/renesas/usba/dcd_usba.c - - $TUSB_DIR$/src/portable/silabs/efm32/dcd_efm32.c - $TUSB_DIR$/src/portable/sony/cxd56/dcd_cxd56.c $TUSB_DIR$/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c - - $TUSB_DIR$/src/portable/st/synopsys/dcd_synopsys.c - - - $TUSB_DIR$/src/portable/template/dcd_template.c - $TUSB_DIR$/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c From 7413b6b02074d806ee2290b53c46ceaa3e76ef42 Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Sat, 27 Nov 2021 10:25:39 +0900 Subject: [PATCH 014/504] Add a compile condition for dcd --- src/portable/mentor/musb/dcd_musb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 4b4c2f9b2..0464eea19 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -26,7 +26,8 @@ #include "tusb_option.h" -#if TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) +#if TUSB_OPT_DEVICE_ENABLED && \ + TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) #if __GNUC__ > 8 && defined(__ARM_FEATURE_UNALIGNED) /* GCC warns that an address may be unaligned, even though From b50cf856b323c4948883a9834d289fe5dd7f67ff Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Sun, 28 Nov 2021 16:49:27 +0900 Subject: [PATCH 015/504] Add hcd_musb.c --- src/portable/mentor/musb/hcd_musb.c | 858 ++++++++++++++++++++++++++++ 1 file changed, 858 insertions(+) create mode 100644 src/portable/mentor/musb/hcd_musb.c diff --git a/src/portable/mentor/musb/hcd_musb.c b/src/portable/mentor/musb/hcd_musb.c new file mode 100644 index 000000000..b4931a793 --- /dev/null +++ b/src/portable/mentor/musb/hcd_musb.c @@ -0,0 +1,858 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 Koji KITAYAMA + * + * 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 TUSB_OPT_HOST_ENABLED && \ + TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) + +#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 "host/hcd.h" + +#if TU_CHECK_MCU(OPT_MCU_MSP432E4) + #include "musb_msp432e.h" + +#elif TU_CHECK_MCU(OPT_MCU_TM4C123, OPT_MCU_TM4C129) + #include "musb_tm4c.h" + + // HACK generalize later + #include "musb_type.h" + #define FIFO0_WORD FIFO0 + +#else + #error "Unsupported MCUs" +#endif + +#ifndef HCD_ATTR_ENDPOINT_MAX +# define HCD_ATTR_ENDPOINT_MAX 8 +#endif + +/*------------------------------------------------------------------ + * MACRO TYPEDEF CONSTANT ENUM DECLARATION + *------------------------------------------------------------------*/ +#define REQUEST_TYPE_INVALID (0xFFu) + +typedef struct { + uint_fast16_t beg; /* offset of including first element */ + uint_fast16_t end; /* offset of excluding the last element */ +} free_block_t; + +typedef struct TU_ATTR_PACKED { + uint8_t TXFUNCADDR; + uint8_t RESERVED0; + uint8_t TXHUBADDR; + uint8_t TXHUBPORT; + uint8_t RXFUNCADDR; + uint8_t RESERVED1; + uint8_t RXHUBADDR; + uint8_t RXHUBPORT; +} hw_addr_t; + +typedef struct TU_ATTR_PACKED { + uint16_t TXMAXP; + uint8_t TXCSRL; + uint8_t TXCSRH; + uint16_t RXMAXP; + uint8_t RXCSRL; + uint8_t RXCSRH; + uint16_t RXCOUNT; + uint8_t TXTYPE; + uint8_t TXINTERVAL; + uint8_t RXTYPE; + uint8_t RXINTERVAL; + uint16_t RESERVED; +} hw_endpoint_t; + +typedef union { + uint8_t u8; + uint16_t u16; + uint32_t u32; +} hw_fifo_t; + +typedef struct TU_ATTR_PACKED +{ + void *buf; /* the start address of a transfer data buffer */ + uint16_t length; /* the number of bytes in the buffer */ + uint16_t remaining; /* the number of bytes remaining in the buffer */ +} pipe_state_t; + +typedef struct TU_ATTR_PACKED +{ + uint8_t dev; + uint8_t ep; +} pipe_addr_t; + +typedef struct +{ + bool need_reset; /* The device has not been reset after connection. */ + uint8_t bmRequestType; + uint8_t ctl_mps[7]; /* EP0 max packet size for each device */ + pipe_state_t pipe0; + pipe_state_t pipe[7][2]; /* pipe[pipe number - 1][direction 0:RX 1:TX] */ + pipe_addr_t addr[7][2]; /* addr[pipe number - 1][direction 0:RX 1:TX] */ +} hcd_data_t; + +/*------------------------------------------------------------------ + * INTERNAL OBJECT & FUNCTION DECLARATION + *------------------------------------------------------------------*/ +static hcd_data_t _hcd; + +static inline free_block_t *find_containing_block(free_block_t *beg, free_block_t *end, uint_fast16_t addr) +{ + free_block_t *cur = beg; + for (; cur < end && ((addr < cur->beg) || (cur->end <= addr)); ++cur) ; + return cur; +} + +static inline int update_free_block_list(free_block_t *blks, unsigned num, uint_fast16_t addr, uint_fast16_t size) +{ + free_block_t *p = find_containing_block(blks, blks + num, addr); + TU_ASSERT(p != blks + num, -2); + if (p->beg == addr) { + /* Shrink block */ + p->beg = addr + size; + if (p->beg != p->end) return 0; + /* remove block */ + free_block_t *end = blks + num; + while (p + 1 < end) { + *p = *(p + 1); + ++p; + } + return -1; + } else { + /* Split into 2 blocks */ + free_block_t tmp = { + .beg = addr + size, + .end = p->end + }; + p->end = addr; + if (p->beg == p->end) { + if (tmp.beg != tmp.end) { + *p = tmp; + return 0; + } + /* remove block */ + free_block_t *end = blks + num; + while (p + 1 < end) { + *p = *(p + 1); + ++p; + } + return -1; + } + if (tmp.beg == tmp.end) return 0; + blks[num] = tmp; + return 1; + } +} + +static inline unsigned free_block_size(free_block_t const *blk) +{ + return blk->end - blk->beg; +} + +static unsigned find_free_memory(uint_fast16_t size_in_log2_minus3) +{ + free_block_t free_blocks[2 * (HCD_ATTR_ENDPOINT_MAX - 1)]; + unsigned num_blocks = 1; + + /* Initialize free memory block list */ + free_blocks[0].beg = 64 / 8; + free_blocks[0].end = (4 << 10) / 8; /* 4KiB / 8 bytes */ + for (int i = 1; i < HCD_ATTR_ENDPOINT_MAX; ++i) { + uint_fast16_t addr; + int num; + USB0->EPIDX = i; + addr = USB0->TXFIFOADD; + if (addr) { + unsigned sz = USB0->TXFIFOSZ; + unsigned sft = (sz & USB_TXFIFOSZ_SIZE_M) + ((sz & USB_TXFIFOSZ_DPB) ? 1: 0); + num = update_free_block_list(free_blocks, num_blocks, addr, 1 << sft); + TU_ASSERT(-2 < num, 0); + num_blocks += num; + } + addr = USB0->RXFIFOADD; + if (addr) { + unsigned sz = USB0->RXFIFOSZ; + unsigned sft = (sz & USB_RXFIFOSZ_SIZE_M) + ((sz & USB_RXFIFOSZ_DPB) ? 1: 0); + num = update_free_block_list(free_blocks, num_blocks, addr, 1 << sft); + TU_ASSERT(-2 < num, 0); + num_blocks += num; + } + } + + /* Find the best fit memory block */ + uint_fast16_t size_in_8byte_unit = 1 << size_in_log2_minus3; + free_block_t const *min = NULL; + uint_fast16_t min_sz = 0xFFFFu; + free_block_t const *end = &free_blocks[num_blocks]; + for (free_block_t const *cur = &free_blocks[0]; cur < end; ++cur) { + uint_fast16_t sz = free_block_size(cur); + if (sz < size_in_8byte_unit) continue; + if (size_in_8byte_unit == sz) return cur->beg; + if (sz < min_sz) min = cur; + } + TU_ASSERT(min, 0); + return min->beg; +} + +static inline volatile hw_endpoint_t* edpt_regs(unsigned epnum_minus1) +{ + volatile hw_endpoint_t *regs = (volatile hw_endpoint_t*)((uintptr_t)&USB0->TXMAXP1); + return regs + epnum_minus1; +} + +static unsigned find_pipe(uint_fast8_t dev_addr, uint_fast8_t ep_addr) +{ + unsigned const dir_tx = tu_edpt_dir(ep_addr) ? 0: 1; + pipe_addr_t const *p = &_hcd.addr[0][dir_tx]; + for (unsigned i = 0; i < sizeof(_hcd.addr)/sizeof(_hcd.addr[0]); ++i, p += 2) { + if ((dev_addr == p->dev) && (ep_addr == p->ep)) + return i + 1; + } + return 0; +} + +static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) +{ + volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; + uintptr_t addr = (uintptr_t)buf; + while (len >= 4) { + reg->u32 = *(uint32_t const *)addr; + addr += 4; + len -= 4; + } + if (len >= 2) { + reg->u16 = *(uint16_t const *)addr; + addr += 2; + len -= 2; + } + if (len) { + reg->u8 = *(uint8_t const *)addr; + } +} + +static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len) +{ + volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; + uintptr_t addr = (uintptr_t)buf; + while (len >= 4) { + *(uint32_t *)addr = reg->u32; + addr += 4; + len -= 4; + } + if (len >= 2) { + *(uint32_t *)addr = reg->u16; + addr += 2; + len -= 2; + } + if (len) { + *(uint32_t *)addr = reg->u8; + } +} + +static bool edpt0_xfer_out(void) +{ + pipe_state_t *pipe = &_hcd.pipe0; + unsigned const rem = pipe->remaining; + if (!rem) { + pipe->buf = NULL; + return true; + } + unsigned const dev_addr = USB0->TXFUNCADDR0; + unsigned const mps = _hcd.ctl_mps[dev_addr]; + unsigned const len = TU_MIN(rem, mps); + void *buf = pipe->buf; + if (len) { + pipe_write_packet(buf, &USB0->FIFO0_WORD, len); + pipe->buf = (uint8_t*)buf + len; + } + pipe->remaining = rem - len; + USB0->CSRL0 = USB_CSRL0_TXRDY; + return false; +} + +static bool edpt0_xfer_in(void) +{ + pipe_state_t *pipe = &_hcd.pipe0; + unsigned const rem = pipe->remaining; + unsigned const dev_addr = USB0->TXFUNCADDR0; + unsigned const mps = _hcd.ctl_mps[dev_addr]; + unsigned const vld = USB0->COUNT0; + unsigned const len = TU_MIN(TU_MIN(rem, mps), vld); + void *buf = pipe->buf; + if (len) { + pipe_read_packet(buf, &USB0->FIFO0_WORD, len); + pipe->buf = (uint8_t*)buf + len; + } + pipe->remaining = rem - len; + if ((len < mps) || (rem == len)) { + pipe->buf = NULL; + return true; + } + USB0->CSRL0 = USB_CSRL0_REQPKT; + return false; +} + +static bool edpt0_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen) +{ + (void)rhport; + + const unsigned req = _hcd.bmRequestType; + TU_ASSERT(req != REQUEST_TYPE_INVALID); + TU_ASSERT(dev_addr < sizeof(_hcd.ctl_mps)); + + USB0->TXFUNCADDR0 = dev_addr; + const unsigned dir_in = tu_edpt_dir(ep_addr); + if (tu_edpt_dir(req) == dir_in) { /* DATA stage */ + TU_ASSERT(buffer); + _hcd.pipe0.buf = buffer; + _hcd.pipe0.length = buflen; + _hcd.pipe0.remaining = buflen; + if (dir_in) + USB0->CSRL0 = USB_CSRL0_REQPKT; + else + edpt0_xfer_out(); + } else { /* STATUS stage */ + _hcd.pipe0.buf = NULL; + _hcd.pipe0.length = 0; + _hcd.pipe0.remaining = 0; + USB0->CSRL0 = USB_CSRL0_STATUS | (dir_in ? USB_CSRL0_REQPKT: USB_CSRL0_TXRDY); + } + return true; +} + +static bool pipe_xfer_out(uint_fast8_t pipenum) +{ + pipe_state_t *pipe = &_hcd.pipe[pipenum - 1][1]; + unsigned const rem = pipe->remaining; + if (!rem) { + pipe->buf = NULL; + return true; + } + hw_endpoint_t volatile *regs = edpt_regs(pipenum - 1); + unsigned const mps = regs->TXMAXP; + unsigned const len = TU_MIN(rem, mps); + void *buf = pipe->buf; + if (len) { + pipe_write_packet(buf, &USB0->FIFO0_WORD + pipenum, len); + pipe->buf = (uint8_t*)buf + len; + } + pipe->remaining = rem - len; + regs->TXCSRL = USB_TXCSRL1_TXRDY; + return false; +} + +static bool pipe_xfer_in(uint_fast8_t pipenum) +{ + pipe_state_t *pipe = &_hcd.pipe[pipenum - 1][0]; + volatile hw_endpoint_t *regs = edpt_regs(pipenum - 1); + + TU_ASSERT(regs->RXCSRL & USB_RXCSRL1_RXRDY); + + const unsigned mps = regs->RXMAXP; + const unsigned rem = pipe->remaining; + const unsigned vld = regs->RXCOUNT; + const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); + void *buf = pipe->buf; + if (len) { + pipe_read_packet(buf, &USB0->FIFO0_WORD + pipenum, len); + pipe->buf = buf + len; + pipe->remaining = rem - len; + } + if ((len < mps) || (rem == len)) { + pipe->buf = NULL; + return NULL != buf; + } + regs->RXCSRL = USB_RXCSRL1_REQPKT; + return false; +} + +static bool edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen) +{ + (void)rhport; + unsigned const pipenum = find_pipe(dev_addr, ep_addr); + unsigned const dir_tx = tu_edpt_dir(ep_addr) ? 0: 1; + pipe_state_t *pipe = &_hcd.pipe[pipenum - 1][dir_tx]; + pipe->buf = buffer; + pipe->length = buflen; + pipe->remaining = buflen; + if (dir_tx) { + pipe_xfer_out(pipenum); + } else { + volatile hw_endpoint_t *regs = edpt_regs(pipenum - 1); + regs->RXCSRL = USB_RXCSRL1_REQPKT; + } + return true; +} + +static void process_ep0(uint8_t rhport) +{ + (void)rhport; + + uint_fast8_t csrl = USB0->CSRL0; + // TU_LOG1(" EP0 CSRL = %x\n", csrl); + + unsigned const dev_addr = USB0->TXFUNCADDR0; + unsigned const req = _hcd.bmRequestType; + if (csrl & (USB_CSRL0_ERROR | USB_CSRL0_NAKTO | USB_CSRL0_STALLED)) { + /* No response / NAK timed out / Stall received */ + if (csrl & (USB_CSRL0_RXRDY | USB_CSRL0_TXRDY)) + USB0->CSRH0 = USB_CSRH0_FLUSH; + USB0->CSRL0 = 0; + _hcd.bmRequestType = REQUEST_TYPE_INVALID; + uint8_t result = (csrl & USB_CSRL0_STALLED) ? XFER_RESULT_STALLED: XFER_RESULT_FAILED; + if (REQUEST_TYPE_INVALID == req) { /* SETUP */ + uint8_t const ep_addr = tu_edpt_addr(0, TUSB_DIR_OUT); + hcd_event_xfer_complete(dev_addr, ep_addr, + _hcd.pipe0.length - _hcd.pipe0.remaining, + result, true); + } else if (csrl & USB_CSRL0_STATUS) { /* STATUS */ + uint8_t const ep_addr = tu_edpt_dir(req) ? + tu_edpt_addr(0, TUSB_DIR_OUT): tu_edpt_addr(0, TUSB_DIR_IN); + hcd_event_xfer_complete(dev_addr, ep_addr, + _hcd.pipe0.length - _hcd.pipe0.remaining, + result, true); + } else { /* DATA */ + uint8_t const ep_addr = tu_edpt_dir(req) ? + tu_edpt_addr(0, TUSB_DIR_IN): tu_edpt_addr(0, TUSB_DIR_OUT); + hcd_event_xfer_complete(dev_addr, ep_addr, + _hcd.pipe0.length - _hcd.pipe0.remaining, + result, true); + } + return; + } + if (csrl & USB_CSRL0_STATUS) { + /* STATUS IN */ + TU_ASSERT(USB_CSRL0_RXRDY == (csrl & USB_CSRL0_RXRDY),); + TU_ASSERT(0 == USB0->COUNT0,); + USB0->CSRL0 = 0; + _hcd.bmRequestType = REQUEST_TYPE_INVALID; + hcd_event_xfer_complete(dev_addr, tu_edpt_addr(0, TUSB_DIR_IN), + 0, XFER_RESULT_SUCCESS, true); + return; + } + if (csrl & USB_CSRL0_RXRDY) { + /* DATA IN */ + TU_ASSERT(REQUEST_TYPE_INVALID != req,); + TU_ASSERT(_hcd.pipe0.buf,); + if (edpt0_xfer_in()) { + hcd_event_xfer_complete(dev_addr, tu_edpt_addr(0, TUSB_DIR_IN), + _hcd.pipe0.length - _hcd.pipe0.remaining, + XFER_RESULT_SUCCESS, true); + } + return; + } + + /* When CSRL0 is zero, it means that completion of sending a any length packet. */ + if (!_hcd.pipe0.buf) { + /* STATUS OUT */ + TU_ASSERT(REQUEST_TYPE_INVALID != req,); + _hcd.bmRequestType = REQUEST_TYPE_INVALID; + /* EP address is the reverse direction of DATA stage */ + uint8_t const ep_addr = tu_edpt_dir(req) ? + tu_edpt_addr(0, TUSB_DIR_OUT): tu_edpt_addr(0, TUSB_DIR_IN); + hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_SUCCESS, true); + return; + } + if (REQUEST_TYPE_INVALID == req) { + /* SETUP */ + _hcd.bmRequestType = *(uint8_t*)_hcd.pipe0.buf; + _hcd.pipe0.buf = NULL; + hcd_event_xfer_complete(dev_addr, tu_edpt_addr(0, TUSB_DIR_OUT), + 8, XFER_RESULT_SUCCESS, true); + return; + } + + /* DATA OUT */ + if (edpt0_xfer_out()) { + hcd_event_xfer_complete(dev_addr, tu_edpt_addr(0, TUSB_DIR_OUT), + _hcd.pipe0.length - _hcd.pipe0.remaining, + XFER_RESULT_SUCCESS, true); + } +} + +static void process_pipe_tx(uint8_t rhport, uint_fast8_t pipenum) +{ + (void)rhport; + bool completed; + uint8_t result; + + volatile hw_endpoint_t *regs = edpt_regs(pipenum - 1); + unsigned const csrl = regs->TXCSRL; + // TU_LOG1(" TXCSRL%d = %x\n", pipenum, csrl); + if (csrl & (USB_TXCSRL1_STALLED | USB_TXCSRL1_ERROR)) { + if (csrl & USB_TXCSRL1_TXRDY) + regs->TXCSRL = (csrl & ~(USB_TXCSRL1_STALLED | USB_TXCSRL1_ERROR)) | USB_TXCSRL1_FLUSH; + else + regs->TXCSRL = csrl & ~(USB_TXCSRL1_STALLED | USB_TXCSRL1_ERROR); + completed = true; + result = (csrl & USB_TXCSRL1_STALLED) ? XFER_RESULT_STALLED: XFER_RESULT_FAILED; + } else { + completed = pipe_xfer_out(pipenum); + result = XFER_RESULT_SUCCESS; + } + if (completed) { + pipe_addr_t *addr = &_hcd.addr[pipenum - 1][1]; + pipe_state_t *pipe = &_hcd.pipe[pipenum - 1][1]; + hcd_event_xfer_complete(addr->dev, addr->ep, + pipe->length - pipe->remaining, + result, true); + } +} + +static void process_pipe_rx(uint8_t rhport, uint_fast8_t pipenum) +{ + (void)rhport; + bool completed; + uint8_t result; + + volatile hw_endpoint_t *regs = edpt_regs(pipenum - 1); + unsigned const csrl = regs->RXCSRL; + // TU_LOG1(" RXCSRL%d = %x\n", pipenum, csrl); + if (csrl & (USB_RXCSRL1_STALLED | USB_RXCSRL1_ERROR)) { + if (csrl & USB_RXCSRL1_RXRDY) + regs->RXCSRL = (csrl & ~(USB_RXCSRL1_STALLED | USB_RXCSRL1_ERROR)) | USB_RXCSRL1_FLUSH; + else + regs->RXCSRL = csrl & ~(USB_RXCSRL1_STALLED | USB_RXCSRL1_ERROR); + completed = true; + result = (csrl & USB_RXCSRL1_STALLED) ? XFER_RESULT_STALLED: XFER_RESULT_FAILED; + } else { + completed = pipe_xfer_in(pipenum); + result = XFER_RESULT_SUCCESS; + } + if (completed) { + pipe_addr_t *addr = &_hcd.addr[pipenum - 1][0]; + pipe_state_t *pipe = &_hcd.pipe[pipenum - 1][0]; + hcd_event_xfer_complete(addr->dev, addr->ep, + pipe->length - pipe->remaining, + result, true); + } +} + +/*------------------------------------------------------------------ + * Host API + *------------------------------------------------------------------*/ + +bool hcd_init(uint8_t rhport) +{ + (void)rhport; + + NVIC_ClearPendingIRQ(USB0_IRQn); + _hcd.bmRequestType = REQUEST_TYPE_INVALID; + USB0->DEVCTL |= USB_DEVCTL_SESSION; + USB0->IE = USB_IE_DISCON | USB_IE_CONN | USB_IE_BABBLE | USB_IE_RESUME; + return true; +} + +void hcd_int_enable(uint8_t rhport) +{ + (void)rhport; + NVIC_EnableIRQ(USB0_IRQn); +} + +void hcd_int_disable(uint8_t rhport) +{ + (void)rhport; + NVIC_DisableIRQ(USB0_IRQn); +} + +uint32_t hcd_frame_number(uint8_t rhport) +{ + (void)rhport; + /* The device must be reset at least once after connection + * in order to start the frame counter. */ + if (_hcd.need_reset) hcd_port_reset(rhport); + return USB0->FRAME; +} + +//--------------------------------------------------------------------+ +// Port API +//--------------------------------------------------------------------+ + +bool hcd_port_connect_status(uint8_t rhport) +{ + (void)rhport; + unsigned devctl = USB0->DEVCTL; + if (!(devctl & USB_DEVCTL_HOST)) return false; + if (devctl & (USB_DEVCTL_LSDEV | USB_DEVCTL_FSDEV)) return true; + return false; +} + +void hcd_port_reset(uint8_t rhport) +{ + (void)rhport; + USB0->POWER |= USB_POWER_HSENAB | USB_POWER_RESET; + unsigned cnt = SystemCoreClock / 1000 * 20; + while (cnt--) __NOP(); + USB0->POWER &= ~USB_POWER_RESET; + _hcd.need_reset = false; +} + +tusb_speed_t hcd_port_speed_get(uint8_t rhport) +{ + (void)rhport; + unsigned devctl = USB0->DEVCTL; + if (devctl & USB_DEVCTL_LSDEV) return TUSB_SPEED_LOW; + if (!(devctl & USB_DEVCTL_FSDEV)) return TUSB_SPEED_INVALID; + if (USB0->POWER & USB_POWER_HSMODE) return TUSB_SPEED_HIGH; + return TUSB_SPEED_FULL; +} + +void hcd_device_close(uint8_t rhport, uint8_t dev_addr) +{ + (void)rhport; + if (sizeof(_hcd.ctl_mps) <= dev_addr) return; + + unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn); + NVIC_DisableIRQ(USB0_IRQn); + _hcd.ctl_mps[dev_addr] = 0; + if (!dev_addr) return; + + pipe_addr_t *p = &_hcd.addr[0][0]; + for (unsigned i = 0; i < sizeof(_hcd.addr)/sizeof(_hcd.addr[0]); ++i) { + for (unsigned j = 0; j < 2; ++j, ++p) { + if (dev_addr != p->dev) continue; + hw_addr_t volatile *fadr = (hw_addr_t volatile*)&USB0->TXFUNCADDR0 + i + 1; + hw_endpoint_t volatile *regs = edpt_regs(i); + USB0->EPIDX = i + 1; + if (j) { + USB0->TXIE &= ~TU_BIT(i + 1); + if (regs->TXCSRL & USB_TXCSRL1_TXRDY) + regs->TXCSRL = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; + else + regs->TXCSRL = USB_TXCSRL1_CLRDT; + regs->TXMAXP = 0; + regs->TXTYPE = 0; + regs->TXINTERVAL = 0; + fadr->TXFUNCADDR = 0; + fadr->TXHUBADDR = 0; + fadr->TXHUBPORT = 0; + USB0->TXFIFOADD = 0; + USB0->TXFIFOSZ = 0; + } else { + USB0->RXIE &= ~TU_BIT(i + 1); + if (regs->RXCSRL & USB_RXCSRL1_RXRDY) + regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; + else + regs->RXCSRL = USB_RXCSRL1_CLRDT; + regs->RXMAXP = 0; + regs->RXTYPE = 0; + regs->RXINTERVAL = 0; + fadr->RXFUNCADDR = 0; + fadr->RXHUBADDR = 0; + fadr->RXHUBPORT = 0; + USB0->RXFIFOADD = 0; + USB0->RXFIFOSZ = 0; + } + p->dev = 0; + p->ep = 0; + pipe_state_t *pipe = &_hcd.pipe[i][j]; + pipe->buf = NULL; + pipe->length = 0; + pipe->remaining = 0; + } + } + if (ie) NVIC_EnableIRQ(USB0_IRQn); +} + +//--------------------------------------------------------------------+ +// Endpoints API +//--------------------------------------------------------------------+ + +bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) +{ + (void)rhport; + pipe_write_packet((void*)(uintptr_t)setup_packet, &USB0->FIFO0_WORD, 8); + _hcd.pipe0.buf = (void*)(uintptr_t)setup_packet; + _hcd.pipe0.length = 8; + _hcd.pipe0.remaining = 0; + _hcd.bmRequestType = REQUEST_TYPE_INVALID; + USB0->TXFUNCADDR0 = dev_addr; + USB0->CSRL0 = USB_CSRL0_TXRDY | USB_CSRL0_SETUP; + return true; +} + +bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) +{ + if (sizeof(_hcd.ctl_mps) <= dev_addr) return false; + unsigned const ep_addr = ep_desc->bEndpointAddress; + unsigned const epn = tu_edpt_number(ep_addr); + if (0 == epn) { + _hcd.ctl_mps[dev_addr] = ep_desc->wMaxPacketSize; + return true; + } + + unsigned const dir_tx = tu_edpt_dir(ep_addr) ? 0: 1; + /* Find a free pipe */ + unsigned pipenum = 0; + pipe_addr_t *p = &_hcd.addr[0][dir_tx]; + for (unsigned i = 0; i < sizeof(_hcd.addr)/sizeof(_hcd.addr[0]); ++i, p += 2) { + if (0 == p->ep) { + p->dev = dev_addr; + p->ep = ep_addr; + pipenum = i + 1; + break; + } + } + if (!pipenum) return false; + + unsigned const xfer = ep_desc->bmAttributes.xfer; + unsigned const mps = tu_edpt_packet_size(ep_desc); + + pipe_state_t *pipe = &_hcd.pipe[pipenum - 1][dir_tx]; + pipe->buf = NULL; + pipe->length = 0; + pipe->remaining = 0; + + uint8_t pipe_type = 0; + switch (hcd_port_speed_get(rhport)) { + default: return false; + case TUSB_SPEED_LOW: pipe_type |= USB_TXTYPE1_SPEED_LOW; break; + case TUSB_SPEED_FULL: pipe_type |= USB_TXTYPE1_SPEED_FULL; break; + case TUSB_SPEED_HIGH: pipe_type |= USB_TXTYPE1_SPEED_HIGH; break; + } + switch (xfer) { + default: return false; + case TUSB_XFER_BULK: pipe_type |= USB_TXTYPE1_PROTO_BULK; break; + case TUSB_XFER_INTERRUPT: pipe_type |= USB_TXTYPE1_PROTO_INT; break; + case TUSB_XFER_ISOCHRONOUS: pipe_type |= USB_TXTYPE1_PROTO_ISOC; break; + } + + hw_addr_t volatile *fadr = (hw_addr_t volatile*)&USB0->TXFUNCADDR0 + pipenum; + hw_endpoint_t volatile *regs = edpt_regs(pipenum - 1); + if (dir_tx) { + fadr->TXFUNCADDR = dev_addr; + regs->TXMAXP = mps; + regs->TXTYPE = pipe_type | epn; + regs->TXINTERVAL = ep_desc->bInterval; + if (regs->TXCSRL & USB_TXCSRL1_TXRDY) + regs->TXCSRL = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; + else + regs->TXCSRL = USB_TXCSRL1_CLRDT; + USB0->TXIE |= TU_BIT(pipenum); + } else { + fadr->RXFUNCADDR = dev_addr; + regs->RXMAXP = mps; + regs->RXTYPE = pipe_type | epn; + regs->RXINTERVAL = ep_desc->bInterval; + if (regs->RXCSRL & USB_RXCSRL1_RXRDY) + regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; + else + regs->RXCSRL = USB_RXCSRL1_CLRDT; + USB0->RXIE |= TU_BIT(pipenum); + } + + /* Setup FIFO */ + int size_in_log2_minus3 = 28 - TU_MIN(28, __CLZ((uint32_t)mps)); + if ((8u << size_in_log2_minus3) < mps) ++size_in_log2_minus3; + unsigned addr = find_free_memory(size_in_log2_minus3); + TU_ASSERT(addr); + + USB0->EPIDX = pipenum; + if (dir_tx) { + USB0->TXFIFOADD = addr; + USB0->TXFIFOSZ = size_in_log2_minus3; + } else { + USB0->RXFIFOADD = addr; + USB0->RXFIFOSZ = size_in_log2_minus3; + } + return true; +} + +bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen) +{ + (void)rhport; + bool ret = false; + if (0 == tu_edpt_number(ep_addr)) { + ret = edpt0_xfer(rhport, dev_addr, ep_addr, buffer, buflen); + } else { + ret = edpt_xfer(rhport, dev_addr, ep_addr, buffer, buflen); + } + return ret; +} + +// clear stall, data toggle is also reset to DATA0 +bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) +{ + unsigned const pipenum = find_pipe(dev_addr, ep_addr); + if (!pipenum) return false; + hw_endpoint_t volatile *regs = edpt_regs(pipenum - 1); + unsigned const dir_tx = tu_edpt_dir(ep_addr) ? 0: 1; + if (dir_tx) + regs->TXCSRL = USB_TXCSRL1_CLRDT; + else + regs->RXCSRL = USB_RXCSRL1_CLRDT; + return true; +} + +/*------------------------------------------------------------------- + * ISR + *-------------------------------------------------------------------*/ +void hcd_int_handler(uint8_t rhport) +{ + uint_fast8_t is, txis, rxis; + + is = USB0->IS; /* read and clear interrupt status */ + txis = USB0->TXIS; /* read and clear interrupt status */ + rxis = USB0->RXIS; /* read and clear interrupt status */ + // TU_LOG1("D%2x T%2x R%2x\n", is, txis, rxis); + + is &= USB0->IE; /* Clear disabled interrupts */ + if (is & USB_IS_RESUME) { + } + if (is & USB_IS_CONN) { + _hcd.need_reset = true; + hcd_event_device_attach(rhport, true); + } + if (is & USB_IS_DISCON) { + hcd_event_device_remove(rhport, true); + } + if (is & USB_IS_BABBLE) { + } + txis &= USB0->TXIE; /* Clear disabled interrupts */ + if (txis & USB_TXIE_EP0) { + process_ep0(rhport); + txis &= ~TU_BIT(0); + } + while (txis) { + unsigned const num = __builtin_ctz(txis); + process_pipe_tx(rhport, num); + txis &= ~TU_BIT(num); + } + rxis &= USB0->RXIE; /* Clear disabled interrupts */ + while (rxis) { + unsigned const num = __builtin_ctz(rxis); + process_pipe_rx(rhport, num); + rxis &= ~TU_BIT(num); + } +} + +#endif From b3dddc77eb4527372640e1712c9e248b60dd8869 Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Mon, 29 Nov 2021 00:40:23 +0900 Subject: [PATCH 016/504] Add initialization sequence as a HOST --- hw/bsp/msp432e4/family.c | 49 +++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/hw/bsp/msp432e4/family.c b/hw/bsp/msp432e4/family.c index 7114da693..262dc1d30 100644 --- a/hw/bsp/msp432e4/family.c +++ b/hw/bsp/msp432e4/family.c @@ -33,7 +33,12 @@ //--------------------------------------------------------------------+ void USB0_IRQHandler(void) { +#if TUSB_OPT_HOST_ENABLED + tuh_int_handler(0); +#endif +#if TUSB_OPT_DEVICE_ENABLED tud_int_handler(0); +#endif } //--------------------------------------------------------------------+ @@ -42,6 +47,7 @@ void USB0_IRQHandler(void) void board_init(void) { + unsigned bits; /* Turn off power domains that unused peripherals belong to */ SYSCTL->PCCAN = 0u; #ifdef __MCU_HAS_LCD0__ @@ -80,20 +86,23 @@ void board_init(void) #endif /* USR_LED1 ON1 */ - SYSCTL->RCGCGPIO |= TU_BIT(CLK_LED); - while (!(SYSCTL->PRGPIO & TU_BIT(CLK_LED))) ; + bits = TU_BIT(CLK_LED); + SYSCTL->RCGCGPIO |= bits; + while (bits != (SYSCTL->RCGCGPIO & bits)) ; GPIO_LED->DIR = TU_BIT(GPIO_LED_PIN); GPIO_LED->DEN = TU_BIT(GPIO_LED_PIN); /* USR_SW1 PJ0 */ - SYSCTL->RCGCGPIO |= TU_BIT(CLK_BUTTON); - while (!(SYSCTL->PRGPIO & TU_BIT(CLK_BUTTON))) ; + bits = TU_BIT(CLK_BUTTON); + SYSCTL->RCGCGPIO |= bits; + while (bits != (SYSCTL->RCGCGPIO & bits)) ; GPIO_BUTTON->PUR = TU_BIT(GPIO_BUTTON_PIN); GPIO_BUTTON->DEN = TU_BIT(GPIO_BUTTON_PIN); /* UART PA0,1 */ - SYSCTL->RCGCGPIO |= 1u << 0; - while (!(SYSCTL->PRGPIO & (1u << 0))) ; + bits = TU_BIT(0); + SYSCTL->RCGCGPIO |= bits; + while (bits != (SYSCTL->RCGCGPIO & bits)) ; GPIOA->AFSEL = 3u; GPIOA->PCTL = 0x11u; GPIOA->DEN = 3u; @@ -107,11 +116,22 @@ void board_init(void) UART0->CC = UART_CC_CS_PIOSC; /* Set the baud clock to PIOSC */ UART0->CTL = UART_CTL_RXE | UART_CTL_TXE | UART_CTL_UARTEN; - /* USB PB1(VBUS) PL6,7(DP,DM) */ - SYSCTL->RCGCGPIO |= (1u << 1) | (1u << 10); - while (((1u << 1) | (1u << 10)) != (SYSCTL->PRGPIO & ((1u << 1) | (1u << 10)))) ; - GPIOB->AMSEL = 1u << 1; - GPIOL->AMSEL = (1u << 6) | (1u << 7); + /* USB PB0(ID) PB1(VBUS) PL6,7(DP,DM) */ + bits = TU_BIT(1) | TU_BIT(10); + SYSCTL->RCGCGPIO |= bits; + while (bits != (SYSCTL->RCGCGPIO & bits)) ; + GPIOB->AMSEL = TU_BIT(0) | TU_BIT(1); + GPIOL->AMSEL = TU_BIT(6) | TU_BIT(7); + +#if TUSB_OPT_HOST_ENABLED + /* USB PD6(EPEN) */ + bits = TU_BIT(3); + SYSCTL->RCGCGPIO |= bits; + while (bits != (SYSCTL->RCGCGPIO & bits)) ; + GPIOD->AFSEL = TU_BIT(6); + GPIOD->PCTL = 0x05000000u; + GPIOD->DEN = TU_BIT(6); +#endif SYSCTL->RCGCUSB = 1u; /* Open the clock gate for SYSCLK */ while (!(SYSCTL->PRUSB & (1u << 0))) ; @@ -124,6 +144,13 @@ void board_init(void) USB0->CC = USB_CC_CLKEN | (3u << USB_CC_CLKDIV_S); /* 60MHz = 240MHz / 4 */ __DMB(); /* Wait for completion of opening of the clock gate */ +#if TUSB_OPT_HOST_ENABLED + USB0->GPCS = USB_GPCS_DEVMOD_OTG; + USB0->EPC = USB_EPC_EPENDE | USB_EPC_EPEN_HIGH; +#endif +#if TUSB_OPT_DEVICE_ENABLED + USB0->GPCS = USB_GPCS_DEVMOD_DEVVBUS; +#endif } //--------------------------------------------------------------------+ From ae9a39ec1fec596a7578a137a392b48cdab5ac39 Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Mon, 29 Nov 2021 00:42:18 +0900 Subject: [PATCH 017/504] Add musb driver --- examples/host/cdc_msc_hid/Makefile | 3 ++- examples/host/hid_controller/Makefile | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/host/cdc_msc_hid/Makefile b/examples/host/cdc_msc_hid/Makefile index 0ad9dd856..fd68a7849 100644 --- a/examples/host/cdc_msc_hid/Makefile +++ b/examples/host/cdc_msc_hid/Makefile @@ -23,6 +23,7 @@ SRC_C += \ src/portable/ehci/ehci.c \ src/portable/ohci/ohci.c \ src/portable/nxp/transdimension/hcd_transdimension.c \ - src/portable/nxp/lpc17_40/hcd_lpc17_40.c + src/portable/nxp/lpc17_40/hcd_lpc17_40.c \ + src/portable/mentor/musb/hcd_musb.c include ../../rules.mk diff --git a/examples/host/hid_controller/Makefile b/examples/host/hid_controller/Makefile index 2595ec4a7..776cfcb88 100644 --- a/examples/host/hid_controller/Makefile +++ b/examples/host/hid_controller/Makefile @@ -9,7 +9,7 @@ INC += \ EXAMPLE_SOURCE += \ src/hid_app.c \ src/main.c - + SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) # TODO: suppress warning caused by host stack @@ -26,6 +26,7 @@ SRC_C += \ src/portable/ehci/ehci.c \ src/portable/ohci/ohci.c \ src/portable/nxp/transdimension/hcd_transdimension.c \ - src/portable/nxp/lpc17_40/hcd_lpc17_40.c + src/portable/nxp/lpc17_40/hcd_lpc17_40.c \ + src/portable/mentor/musb/hcd_musb.c include ../../rules.mk From 24614de419f5a7c5871bf6bbd78ec4d01bdca31b Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Mon, 29 Nov 2021 00:45:57 +0900 Subject: [PATCH 018/504] Fix build errors --- examples/host/hid_controller/src/hid_app.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/host/hid_controller/src/hid_app.c b/examples/host/hid_controller/src/hid_app.c index bbfea8182..582e01959 100644 --- a/examples/host/hid_controller/src/hid_app.c +++ b/examples/host/hid_controller/src/hid_app.c @@ -138,6 +138,8 @@ void hid_app_task(void) // therefore report_desc = NULL, desc_len = 0 void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len) { + (void)desc_report; + (void)desc_len; uint16_t vid, pid; tuh_vid_pid_get(dev_addr, &vid, &pid); From ab223eb1df187b0fd845fec17b6bf5365216e4f2 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 29 Nov 2021 13:07:46 +0700 Subject: [PATCH 019/504] correct 32 button in gamepad hid descriptor template --- src/class/hid/hid_device.h | 64 +++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index 7f67fa9cf..078b67349 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -310,8 +310,8 @@ static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y HID_COLLECTION_END \ // Gamepad Report Descriptor Template -// with 16 buttons, 2 joysticks and 1 hat/dpad with following layout -// | X | Y | Z | Rz | Rx | Ry (1 byte each) | hat/DPAD (1 byte) | Button Map (2 bytes) | +// with 32 buttons, 2 joysticks and 1 hat/dpad with following layout +// | X | Y | Z | Rz | Rx | Ry (1 byte each) | hat/DPAD (1 byte) | Button Map (4 bytes) | #define TUD_HID_REPORT_DESC_GAMEPAD(...) \ HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ HID_USAGE ( HID_USAGE_DESKTOP_GAMEPAD ) ,\ @@ -319,37 +319,37 @@ static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y /* Report ID if any */\ __VA_ARGS__ \ /* 8 bit X, Y, Z, Rz, Rx, Ry (min -127, max 127 ) */ \ - HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ - HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\ - HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\ - HID_USAGE ( HID_USAGE_DESKTOP_Z ) ,\ - HID_USAGE ( HID_USAGE_DESKTOP_RZ ) ,\ - HID_USAGE ( HID_USAGE_DESKTOP_RX ) ,\ - HID_USAGE ( HID_USAGE_DESKTOP_RY ) ,\ - HID_LOGICAL_MIN ( 0x81 ) ,\ - HID_LOGICAL_MAX ( 0x7f ) ,\ - HID_REPORT_COUNT ( 6 ) ,\ - HID_REPORT_SIZE ( 8 ) ,\ - HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ + HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_Z ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_RZ ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_RX ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_RY ) ,\ + HID_LOGICAL_MIN ( 0x81 ) ,\ + HID_LOGICAL_MAX ( 0x7f ) ,\ + HID_REPORT_COUNT ( 6 ) ,\ + HID_REPORT_SIZE ( 8 ) ,\ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ /* 8 bit DPad/Hat Button Map */ \ - HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ - HID_USAGE ( HID_USAGE_DESKTOP_HAT_SWITCH ) ,\ - HID_LOGICAL_MIN ( 1 ) ,\ - HID_LOGICAL_MAX ( 8 ) ,\ - HID_PHYSICAL_MIN ( 0 ) ,\ - HID_PHYSICAL_MAX_N ( 315, 2 ) ,\ - HID_REPORT_COUNT ( 1 ) ,\ - HID_REPORT_SIZE ( 8 ) ,\ - HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ - /* 16 bit Button Map */ \ - HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\ - HID_USAGE_MIN ( 1 ) ,\ - HID_USAGE_MAX ( 32 ) ,\ - HID_LOGICAL_MIN ( 0 ) ,\ - HID_LOGICAL_MAX ( 1 ) ,\ - HID_REPORT_COUNT ( 32 ) ,\ - HID_REPORT_SIZE ( 1 ) ,\ - HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ + HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_HAT_SWITCH ) ,\ + HID_LOGICAL_MIN ( 1 ) ,\ + HID_LOGICAL_MAX ( 8 ) ,\ + HID_PHYSICAL_MIN ( 0 ) ,\ + HID_PHYSICAL_MAX_N ( 315, 2 ) ,\ + HID_REPORT_COUNT ( 1 ) ,\ + HID_REPORT_SIZE ( 8 ) ,\ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ + /* 32 bit Button Map */ \ + HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\ + HID_USAGE_MIN ( 1 ) ,\ + HID_USAGE_MAX ( 32 ) ,\ + HID_LOGICAL_MIN ( 0 ) ,\ + HID_LOGICAL_MAX ( 1 ) ,\ + HID_REPORT_COUNT ( 32 ) ,\ + HID_REPORT_SIZE ( 1 ) ,\ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ HID_COLLECTION_END \ // HID Generic Input & Output From 7ad0af64cc172331413aa634aa28002171fe31ab Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 29 Nov 2021 13:24:10 +0700 Subject: [PATCH 020/504] use 4k stack for example with esp32sx --- examples/device/cdc_msc_freertos/src/main.c | 14 ++++++-------- examples/device/hid_composite_freertos/src/main.c | 14 +++++++------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/examples/device/cdc_msc_freertos/src/main.c b/examples/device/cdc_msc_freertos/src/main.c index 2d3426f1d..0a1c964ae 100644 --- a/examples/device/cdc_msc_freertos/src/main.c +++ b/examples/device/cdc_msc_freertos/src/main.c @@ -38,12 +38,17 @@ #include "freertos/queue.h" #include "freertos/task.h" #include "freertos/timers.h" + + #define USBD_STACK_SIZE 4096 #else #include "FreeRTOS.h" #include "semphr.h" #include "queue.h" #include "task.h" #include "timers.h" + + // Increase stack size when debug log is enabled + #define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) #endif //--------------------------------------------------------------------+ @@ -65,14 +70,7 @@ enum { StaticTimer_t blinky_tmdef; TimerHandle_t blinky_tm; -// static task for usbd -// Increase stack size when debug log is enabled -#if CFG_TUSB_DEBUG - #define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE) -#else - #define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) -#endif - +// static task StackType_t usb_device_stack[USBD_STACK_SIZE]; StaticTask_t usb_device_taskdef; diff --git a/examples/device/hid_composite_freertos/src/main.c b/examples/device/hid_composite_freertos/src/main.c index 336f5d426..1695f968c 100644 --- a/examples/device/hid_composite_freertos/src/main.c +++ b/examples/device/hid_composite_freertos/src/main.c @@ -39,12 +39,18 @@ #include "freertos/queue.h" #include "freertos/task.h" #include "freertos/timers.h" + + #define USBD_STACK_SIZE 4096 + #else #include "FreeRTOS.h" #include "semphr.h" #include "queue.h" #include "task.h" #include "timers.h" + + // Increase stack size when debug log is enabled + #define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) #endif //--------------------------------------------------------------------+ @@ -66,13 +72,7 @@ enum { StaticTimer_t blinky_tmdef; TimerHandle_t blinky_tm; -// static task for usbd -#if CFG_TUSB_DEBUG - #define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE) -#else - #define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) -#endif - +// static task StackType_t usb_device_stack[USBD_STACK_SIZE]; StaticTask_t usb_device_taskdef; From 33506675c51e11f3b04cc7a0a4f11af244a0ba11 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 30 Nov 2021 00:33:55 +0700 Subject: [PATCH 021/504] update supported doc --- README.rst | 10 +- docs/reference/supported.rst | 234 +++++++++++++++++++---------------- 2 files changed, 131 insertions(+), 113 deletions(-) diff --git a/README.rst b/README.rst index 60df78ca4..a8ce9399c 100644 --- a/README.rst +++ b/README.rst @@ -32,8 +32,10 @@ Supported MCUs The stack supports the following MCUs: +- **Broadcom:** BCM2837, BCM2711 - **Dialog:** DA1469x - **Espressif:** ESP32-S2, ESP32-S3 +- **GigaDevice:** GD32VF103 - **Infineon:** XMC4500 - **MicroChip:** SAMD11, SAMD21, SAMD51, SAME5x, SAMG55, SAML21, SAML22, SAME7x - **NordicSemi:** nRF52833, nRF52840, nRF5340 @@ -41,15 +43,15 @@ The stack supports the following MCUs: - **NXP:** - iMX RT Series: RT1011, RT1015, RT1021, RT1052, RT1062, RT1064 - - Kinetis: KL25, K32L2Bxx + - Kinetis: KL25, K32L2 - LPC Series: 11u, 13, 15, 17, 18, 40, 43, 51u, 54, 55 - **Raspberry Pi:** RP2040 -- **Renesas:** RX63N, RX65N +- **Renesas:** RX63N, RX65N, RX72N - **Silabs:** EFM32GG - **Sony:** CXD56 -- **ST:** STM32 series: L0, L1, L4, L4+, F0, F1, F2, F3, F4, F7, H7 -- **TI:** MSP430 +- **ST:** STM32 series: F0, F1, F2, F3, F4, F7, H7, L0, L1, L4, L4+ +- **TI:** MSP430, MSP432E4, TM4C123 - **ValentyUSB:** eptri Here is the list of `Supported Devices`_ that can be used with provided examples. diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index 1d2b4db51..254a0d95d 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -11,117 +11,120 @@ Supported MCUs This table is a WIP! the data is not correct, tho if a device is listed, it likely works as a usb full speed device at the least. -+--------------+--------------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| Manufacturer | Family | Device | Host | FS | HS | Known Issues | -+==============+====================+===================+====================+===================+===================+==============+ -| Dialog | DA1469x | |:green_square:| | |:x:| | |:green_square:| | |:x:| | | -+--------------+--------------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| Espressif | ESP32-S2 | |:green_square:| | |:x:| | |:green_square:| | |:x:| | | -| +--------------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | ESP32-S3 | |:green_square:| | |:x:| | |:green_square:| | |:x:| | | -+--------------+--------------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| MicroChip | SAMD11 | |:green_square:| | |:x:| | |:green_square:| | |:x:| | | -| +--------------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | SAMD21 | |:green_square:| | |:x:| | |:green_square:| | |:x:| | | -| +--------------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | SAMD51 | |:green_square:| | |:x:| | |:green_square:| | |:x:| | | -| +--------------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | SAME5x | |:green_square:| | |:x:| | |:green_square:| | |:x:| | | -| +--------------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | SAMG55 | |:green_square:| | |:x:| | |:green_square:| | |:x:| | | -| +--------------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | SAML21 | |:green_square:| | |:x:| | |:green_square:| | |:x:| | | -| +--------------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | SAML22 | |:green_square:| | |:x:| | |:green_square:| | |:x:| | | -| +--------------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | SAME70,S70,V70,V71 | |:green_square:| | |:red_square:| | |:green_square:| | |:green_square:| | | -+--------------+--------------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| NordicSemi | nRF52833 | |:green_square:| | |:x:| | |:green_square:| | |:x:| | | -| +--------------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | nRF52840 | |:green_square:| | |:x:| | |:green_square:| | |:x:| | | -+--------------+--------------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| Nuvoton | NUC120 | |:green_square:| | |:x:| | |:green_square:| | |:x:| | | -| +--------------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | NUC121/NUC125 | |:green_square:| | |:x:| | |:green_square:| | |:x:| | | -| +--------------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | NUC126 | |:green_square:| | |:x:| | |:green_square:| | |:x:| | | -| +--------------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | NUC505 | |:green_square:| | |:x:| | |:green_square:| | |:x:| | | -+--------------+-------+------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| NXP | iMX | RT1011 | |:green_square:| | |:yellow_square:| | |:green_square:| | |:x:| | | -| | +------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | | RT1015 | |:green_square:| | |:yellow_square:| | |:green_square:| | |:x:| | | -| | +------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | | RT1021 | |:green_square:| | |:yellow_square:| | |:green_square:| | |:x:| | | -| | +------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | | RT1052 | |:green_square:| | |:yellow_square:| | |:green_square:| | |:x:| | | -| | +------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | | RT1062 | |:green_square:| | |:yellow_square:| | |:green_square:| | |:x:| | | -| | +------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | | RT1064 | |:green_square:| | |:yellow_square:| | |:green_square:| | |:x:| | | -| +-------+------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | Kinetis KL25 | |:green_square:| | |:x:| | |:green_square:| | |:x:| | | -| +-------+------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | LPC | 11u | |:green_square:| | |:x:| | |:green_square:| | |:x:| | | -| | +------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | | 13 | |:green_square:| | |:x:| | |:green_square:| | |:x:| | | -| | +------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | | 15 | |:green_square:| | |:x:| | |:green_square:| | |:x:| | | -| | +------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | | 17 | |:green_square:| | |:x:| | |:green_square:| | |:x:| | | -| | +------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | | 18 | | |:yellow_square:| | |:green_square:| | |:x:| | | -| | +------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | | 40 | | |:x:| | |:green_square:| | |:x:| | | -| | +------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | | 43 | |:green_square:| | |:yellow_square:| | |:green_square:| | |:x:| | | -| | +------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | | 51u | |:green_square:| | |:x:| | |:green_square:| | |:x:| | | -| | +------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | | 54 | |:green_square:| | |:x:| | |:green_square:| | |:x:| | | -| | +------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | | 55 | |:green_square:| | |:x:| | |:green_square:| | | | -+--------------+-------+------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| Raspberry Pi | RP2040 | |:green_square:| | |:x:| | |:green_square:| | | | -+--------------+--------------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| Renesas | RX63N | |:green_square:| | | |:green_square:| | |:x:| | | -| +--------------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | RX65N | |:green_square:| | | |:green_square:| | |:x:| | | -+--------------+--------------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| Silabs | EFM32GG12 | |:green_square:| | |:x:| | |:green_square:| | |:x:| | | -+--------------+--------------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| Sony | CXD56 | |:green_square:| | |:x:| | |:green_square:| | |:x:| | | -+--------------+-------+------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| ST | STM32 | L0 | |:green_square:| | | |:green_square:| | | | -| | +------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | | F0 | |:green_square:| | | |:green_square:| | | | -| | +------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | | F1 | |:green_square:| | | |:green_square:| | | | -| | +------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | | F2 | |:green_square:| | | |:green_square:| | | | -| | +------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | | F3 | |:green_square:| | | |:green_square:| | | | -| | +------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | | F4 | |:green_square:| | | |:green_square:| | | | -| | +------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | | F7 | |:green_square:| | | |:green_square:| | | | -| | +------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| | | H7 | |:green_square:| | | |:green_square:| | |:green_square:| | | -+--------------+-------+------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| TI | MSP430 | |:green_square:| | | |:green_square:| | | | -+--------------+--------------------+-------------------+--------------------+-------------------+-------------------+--------------+ -| ValentyUSB | eptri | |:green_square:| | | |:green_square:| | | | -+--------------+--------------------+-------------------+--------------------+-------------------+-------------------+--------------+ ++--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| Manufacturer | Family | Device | Host | Highspeed | Driver | Note | ++==============+=======================+======================+======================+======================+=================+==============+ +| Broadcom | BCM2711, BCM2837 | |:heavy_check_mark:| | | |:heavy_check_mark:| | dwc2 | | ++--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| Dialog | DA1469x | |:heavy_check_mark:| | |:x:| | |:x:| | da146xx | | ++--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| Espressif | ESP32 S2, S3 | |:heavy_check_mark:| | | |:x:| | dwc2 or esp32sx | | ++--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| GigaDevice | GD32VF103 | |:heavy_check_mark:| | | |:x:| | dwc2 | | ++--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| Infineon | XMC4500 | |:heavy_check_mark:| | | |:x:| | dwc2 | | ++--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| MicroChip | SAM D11, D21 | |:heavy_check_mark:| | | |:x:| | samd | | +| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | SAM D51, E5x | |:heavy_check_mark:| | | |:x:| | samd | | +| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | SAM G55 | |:heavy_check_mark:| | | |:x:| | samg | | +| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | SAM L21, L22 | |:heavy_check_mark:| | | |:x:| | samd | | +| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | SAM E70,S70,V70,V71 | |:heavy_check_mark:| | | |:heavy_check_mark:| | samx7x | | ++--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| NordicSemi | nRF52833, nRF52840 | |:heavy_check_mark:| | |:x:| | |:x:| | nrf5x | | +| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | nRF5340 | |:heavy_check_mark:| | |:x:| | |:x:| | nrf5x | | ++--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| Nuvoton | NUC120 | |:heavy_check_mark:| | |:x:| | |:x:| | | | +| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | NUC121/NUC125 | |:heavy_check_mark:| | |:x:| | |:x:| | | | +| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | NUC126 | |:heavy_check_mark:| | |:x:| | |:x:| | | | +| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | NUC505 | |:heavy_check_mark:| | | |:heavy_check_mark:| | | | ++--------------+---------+-------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| NXP | iMXRT | RT1011 | |:heavy_check_mark:| | |:heavy_check_mark:| | |:heavy_check_mark:| | | | +| | +-------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | | RT1015 | |:heavy_check_mark:| | |:heavy_check_mark:| | |:heavy_check_mark:| | | | +| | +-------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | | RT1021 | |:heavy_check_mark:| | |:heavy_check_mark:| | |:heavy_check_mark:| | | | +| | +-------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | | RT1052 | |:heavy_check_mark:| | |:heavy_check_mark:| | |:heavy_check_mark:| | | | +| | +-------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | | RT1062 | |:heavy_check_mark:| | |:heavy_check_mark:| | |:heavy_check_mark:| | | | +| | +-------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | | RT1064 | |:heavy_check_mark:| | |:heavy_check_mark:| | |:heavy_check_mark:| | | | +| +---------+-------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | Kinetis | KL25 | |:heavy_check_mark:| | | |:x:| | | | +| | +-------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | | K32L2 | |:heavy_check_mark:| | | |:x:| | | | +| +---------+-------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | LPC | 11u, 13, 15 | |:heavy_check_mark:| | |:x:| | |:x:| | lpc_ip3511 | | +| | +-------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | | 17, 40 | |:heavy_check_mark:| | |:construction:| | |:x:| | lpc17_40 | | +| | +-------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | | 18, 43 | |:heavy_check_mark:| | |:heavy_check_mark:| | |:x:| | | | +| | +-------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | | 51u | |:heavy_check_mark:| | |:x:| | |:x:| | lpc_ip3511 | | +| | +-------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | | 54 | |:heavy_check_mark:| | | |:heavy_check_mark:| | lpc_ip3511 | | +| | +-------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | | 55 | |:heavy_check_mark:| | | |:heavy_check_mark:| | lpc_ip3511 | | ++--------------+---------+-------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| Raspberry Pi | RP2040 | |:heavy_check_mark:| | |:heavy_check_mark:| | |:x:| | rp2040 | | ++--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| Renesas | RX 63N, 65N, 72N | |:heavy_check_mark:| | |:x:| | |:x:| | usba | | ++--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| Silabs | EFM32GG12 | |:heavy_check_mark:| | | |:x:| | dwc2 | | ++--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| Sony | CXD56 | |:heavy_check_mark:| | |:x:| | |:heavy_check_mark:| | cxd56 | | ++--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| ST STM32 | F0 | |:heavy_check_mark:| | |:x:| | |:x:| | stm32_fsdev | | +| +----+------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | F1 | 102, 103 | |:heavy_check_mark:| | |:x:| | |:x:| | stm32_fsdev | | +| | +------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | | 105, 107 | |:heavy_check_mark:| | | |:x:| | dwc2 | | +| +----+------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | F2 | |:heavy_check_mark:| | | |:heavy_check_mark:| | dwc2 | | +| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | F3 | |:heavy_check_mark:| | |:x:| | |:x:| | stm32_fsdev | | +| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | F4 | |:heavy_check_mark:| | | |:heavy_check_mark:| | dwc2 | | +| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | F7 | |:heavy_check_mark:| | | |:heavy_check_mark:| | dwc2 | | +| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | H7 | |:heavy_check_mark:| | | |:heavy_check_mark:| | dwc2 | | +| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | L0, L1 | |:heavy_check_mark:| | |:x:| | |:x:| | stm32_fsdev | | +| +----+------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | L4 | 4x2, 4x3 | |:heavy_check_mark:| | |:x:| | |:x:| | stm32_fsdev | | +| | +------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | | 4x5, 4x6 | |:heavy_check_mark:| | | | dwc2 | | +| +----+------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | L4+ | |:heavy_check_mark:| | | | dwc2 | | +| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | U5 | |:construction:| | | | dwc2 | | ++--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| TI | MSP430 | |:heavy_check_mark:| | |:x:| | |:x:| | msp430x5xx | | +| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | MSP432E4 | |:heavy_check_mark:| | | |:x:| | musb | | +| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| | TM4C123 | |:heavy_check_mark:| | | |:x:| | musb | | ++--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ +| ValentyUSB | eptri | |:heavy_check_mark:| | |:x:| | |:x:| | eptri | | ++--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ Table Legend ------------ -================= =================== -|:x:| Not available -|:red_square:| Not supported -|:yellow_square:| WIP/partial support -|:green_square:| Supported -================= =================== +==================== =================== +|:heavy_check_mark:| Supported +|:construction:| WIP/partial support +|:x:| Not supported +==================== =================== Supported Boards ================ @@ -134,6 +137,11 @@ The board support code is only used for self-contained examples and testing. It The following boards are supported (sorted alphabetically): +Broadcom +-------- + +- `Raspberry Pi CM4 `__ + Dialog DA146xx -------------- @@ -143,12 +151,17 @@ Dialog DA146xx Espressif ESP32-S2 ------------------ -- Adafruit Feather ESP32-S2 +- `Adafruit Feather ESP32-S2 `__ - `Adafruit Magtag 2.9" E-Ink WiFi Display `__ - `Adafruit Metro ESP32-S2 `__ - `ESP32-S2-Kaluga-1 `__ - `ESP32-S2-Saola-1 `__ +GigaDevice +---------- + +- `Sipeed Longan Nano `__ + Infineon --------- @@ -243,7 +256,8 @@ iMX RT Kinetis ^^^^^^^ -- `FRDM-KL25Z `__ +- `Freedom FRDM-KL25Z `__ +- `Freedom FRDM-K32L2B3 `__ LPC 11-13-15 ^^^^^^^^^^^^ @@ -374,6 +388,8 @@ TI -- - `MSP430F5529 USB LaunchPad Evaluation Kit `__ +- `MSP-EXP432E401Y LaunchPad Evaluation Kit `__ +- `TM4C123GXL LaunchPad Evaluation Kit `__ Tomu ---- From 4678a4142e8dff8c0c7b959dd6862eeb9e9d62f1 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 30 Nov 2021 00:35:39 +0700 Subject: [PATCH 022/504] remove warnings --- docs/reference/supported.rst | 5 ----- 1 file changed, 5 deletions(-) diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index 254a0d95d..dfaffe6e3 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -6,11 +6,6 @@ Supported Devices Supported MCUs ============== -.. admonition:: Warning - :class: warning - - This table is a WIP! the data is not correct, tho if a device is listed, it likely works as a usb full speed device at the least. - +--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ | Manufacturer | Family | Device | Host | Highspeed | Driver | Note | +==============+=======================+======================+======================+======================+=================+==============+ From dba59217da489dc497cbe2b573e7e144d085c869 Mon Sep 17 00:00:00 2001 From: Yunhao Tian Date: Tue, 30 Nov 2021 17:10:53 +0800 Subject: [PATCH 023/504] usbd: supress "statement is unreachable" warning on ARMCC --- src/device/usbd.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/device/usbd.c b/src/device/usbd.c index 6a5210b34..0e31f47c7 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -44,6 +44,11 @@ #define CFG_TUD_TASK_QUEUE_SZ 16 #endif +#ifdef __ARMCC_VERSION +// Supress "statement is unreachable" warning +#pragma diag_suppress 111 +#endif + //--------------------------------------------------------------------+ // Device Data //--------------------------------------------------------------------+ From ac20605e3f098687ce40349bbecc9266333d951b Mon Sep 17 00:00:00 2001 From: Yunhao Tian Date: Tue, 30 Nov 2021 17:11:09 +0800 Subject: [PATCH 024/504] Ignore certain compiler options on ARMCC ARMCC also sets __GNU__ macro, but doesn't support GCC diagnostic pragmas. --- src/common/tusb_compiler.h | 4 +++- src/device/dcd.h | 4 ++-- src/osal/osal.h | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h index d3284c62a..38e6a16d0 100644 --- a/src/common/tusb_compiler.h +++ b/src/common/tusb_compiler.h @@ -137,9 +137,11 @@ #define TU_BSWAP16(u16) (__builtin_bswap16(u16)) #define TU_BSWAP32(u32) (__builtin_bswap32(u32)) + #ifndef __ARMCC_VERSION // List of obsolete callback function that is renamed and should not be defined. // Put it here since only gcc support this pragma - #pragma GCC poison tud_vendor_control_request_cb + #pragma GCC poison tud_vendor_control_request_cb + #endif #elif defined(__TI_COMPILER_VERSION__) #define TU_ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes))) diff --git a/src/device/dcd.h b/src/device/dcd.h index c042cc708..fbcef40d4 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -106,12 +106,12 @@ typedef struct TU_ATTR_ALIGNED(4) void dcd_init (uint8_t rhport); // Interrupt Handler -#if __GNUC__ +#if __GNUC__ && !defined(__ARMCC_VERSION) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wredundant-decls" #endif void dcd_int_handler(uint8_t rhport); -#if __GNUC__ +#if __GNUC__ && !defined(__ARMCC_VERSION) #pragma GCC diagnostic pop #endif diff --git a/src/osal/osal.h b/src/osal/osal.h index c8131d19d..9194f80d5 100644 --- a/src/osal/osal.h +++ b/src/osal/osal.h @@ -67,7 +67,7 @@ typedef void (*osal_task_func_t)( void * ); // OSAL Porting API //--------------------------------------------------------------------+ -#if __GNUC__ +#if __GNUC__ && !defined(__ARMCC_VERSION) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wredundant-decls" #endif @@ -88,7 +88,7 @@ static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef); static inline bool osal_queue_receive(osal_queue_t qhdl, void* data); static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr); static inline bool osal_queue_empty(osal_queue_t qhdl); -#if __GNUC__ +#if __GNUC__ && !defined(__ARMCC_VERSION) #pragma GCC diagnostic pop #endif From a6929cf03eabe9f4fc0404d7c15b04ee2761945c Mon Sep 17 00:00:00 2001 From: Yunhao Tian Date: Tue, 30 Nov 2021 17:11:14 +0800 Subject: [PATCH 025/504] Add support for Keil RTX4 OS abstraction layer --- src/osal/osal.h | 2 + src/osal/osal_rtx4.h | 169 +++++++++++++++++++++++++++++++++++++++++++ src/tusb_option.h | 1 + 3 files changed, 172 insertions(+) create mode 100644 src/osal/osal_rtx4.h diff --git a/src/osal/osal.h b/src/osal/osal.h index 9194f80d5..b2943cc79 100644 --- a/src/osal/osal.h +++ b/src/osal/osal.h @@ -57,6 +57,8 @@ typedef void (*osal_task_func_t)( void * ); #include "osal_pico.h" #elif CFG_TUSB_OS == OPT_OS_RTTHREAD #include "osal_rtthread.h" +#elif CFG_TUSB_OS == OPT_OS_RTX4 + #include "osal_rtx4.h" #elif CFG_TUSB_OS == OPT_OS_CUSTOM #include "tusb_os_custom.h" // implemented by application #else diff --git a/src/osal/osal_rtx4.h b/src/osal/osal_rtx4.h new file mode 100644 index 000000000..93d1a7a28 --- /dev/null +++ b/src/osal/osal_rtx4.h @@ -0,0 +1,169 @@ +/* + * 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_RTX4_H_ +#define _TUSB_OSAL_RTX4_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +//--------------------------------------------------------------------+ +// TASK API +//--------------------------------------------------------------------+ +static inline void osal_task_delay(uint32_t msec) +{ + uint16_t hi = msec >> 16; + uint16_t lo = msec; + while (hi--) { + os_dly_wait(0xFFFE); + } + os_dly_wait(lo); +} + +static inline uint16_t msec2wait(uint32_t msec) { + if (msec == OSAL_TIMEOUT_WAIT_FOREVER) + return 0xFFFF; + else if (msec >= 0xFFFE) + return 0xFFFE; + else + return msec; +} + +//--------------------------------------------------------------------+ +// Semaphore API +//--------------------------------------------------------------------+ +typedef OS_SEM osal_semaphore_def_t; +typedef OS_ID osal_semaphore_t; + +static inline OS_ID osal_semaphore_create(osal_semaphore_def_t* semdef) { + os_sem_init(semdef, 0); + return semdef; +} + +static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { + if ( !in_isr ) { + os_sem_send(sem_hdl); + } else { + isr_sem_send(sem_hdl); + } + return true; +} + +static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) { + return os_sem_wait(sem_hdl, msec2wait(msec)) != OS_R_TMO; +} + +static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) { + // TODO: implement +} + +//--------------------------------------------------------------------+ +// MUTEX API (priority inheritance) +//--------------------------------------------------------------------+ +typedef OS_MUT osal_mutex_def_t; +typedef OS_ID osal_mutex_t; + +static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) +{ + os_mut_init(mdef); + return mdef; +} + +static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) +{ + return os_mut_wait(mutex_hdl, msec2wait(msec)) != OS_R_TMO; +} + +static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) +{ + return os_mut_release(mutex_hdl) == OS_R_OK; +} + +//--------------------------------------------------------------------+ +// QUEUE API +//--------------------------------------------------------------------+ + +// role device/host is used by OS NONE for mutex (disable usb isr) only +#define OSAL_QUEUE_DEF(_role, _name, _depth, _type) \ + os_mbx_declare(_name##__mbox, _depth); \ + _declare_box(_name##__pool, sizeof(_type), _depth); \ + osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .pool = _name##__pool, .mbox = _name##__mbox }; + + +typedef struct +{ + uint16_t depth; + uint16_t item_sz; + U32* pool; + U32* mbox; +}osal_queue_def_t; + +typedef osal_queue_def_t* osal_queue_t; + +static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) +{ + os_mbx_init(qdef->mbox, (qdef->depth + 4) * 4); + _init_box(qdef->pool, ((qdef->item_sz+3)/4)*(qdef->depth) + 3, qdef->item_sz); + return qdef; +} + +static inline bool osal_queue_receive(osal_queue_t qhdl, void* data) +{ + void* buf; + os_mbx_wait(qhdl->mbox, &buf, 0xFFFF); + memcpy(data, buf, qhdl->item_sz); + _free_box(qhdl->pool, buf); + return true; +} + +static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) +{ + void* buf = _alloc_box(qhdl->pool); + memcpy(buf, data, qhdl->item_sz); + if ( !in_isr ) + { + os_mbx_send(qhdl->mbox, buf, 0xFFFF); + } + else + { + isr_mbx_send(qhdl->mbox, buf); + } + return true; +} + +static inline bool osal_queue_empty(osal_queue_t qhdl) +{ + return os_mbx_check(qhdl->mbox) == qhdl->depth; +} + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_OSAL_FREERTOS_H_ */ diff --git a/src/tusb_option.h b/src/tusb_option.h index 2edd310fa..dcf1c4614 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -151,6 +151,7 @@ #define OPT_OS_CUSTOM 4 ///< Custom OS is implemented by application #define OPT_OS_PICO 5 ///< Raspberry Pi Pico SDK #define OPT_OS_RTTHREAD 6 ///< RT-Thread +#define OPT_OS_RTX4 7 ///< Keil RTX 4 // Allow to use command line to change the config name/location #ifdef CFG_TUSB_CONFIG_FILE From 06f99c220ef4f53677c5e5354a309cad3b4d11ef Mon Sep 17 00:00:00 2001 From: rppicomidi Date: Fri, 12 Nov 2021 14:58:51 -0800 Subject: [PATCH 026/504] implement hcd device close --- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 36 ++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 768cccc86..97dae480d 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -64,6 +64,8 @@ enum { USB_SIE_CTRL_PULLDOWN_EN_BITS | USB_SIE_CTRL_EP0_INT_1BUF_BITS }; +enum { ADDR_INVALID = 0xFFu }; + static struct hw_endpoint *get_dev_ep(uint8_t dev_addr, uint8_t ep_addr) { uint8_t num = tu_edpt_number(ep_addr); @@ -346,6 +348,21 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t } } +// return struct hw_endpoint* pointing to the endpoint in the pool or NULL if the dev_addr is not found +static struct hw_endpoint *_hw_find_first_endpoint(uint8_t dev_addr) +{ + struct hw_endpoint *ep = NULL; + for (uint i = 1; i < TU_ARRAY_SIZE(ep_pool); i++) + { + ep = &ep_pool[i]; + if (ep->dev_addr == dev_addr && ep->configured) + { + return ep; + } + } + return NULL; +} + //--------------------------------------------------------------------+ // HCD API //--------------------------------------------------------------------+ @@ -412,9 +429,24 @@ tusb_speed_t hcd_port_speed_get(uint8_t rhport) // Close all opened endpoint belong to this device void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { - (void) rhport; - (void) dev_addr; + assert(rhport == 0); + if (dev_addr == 0) + return; + struct hw_endpoint *ep = _hw_find_first_endpoint(dev_addr); + while (ep) + { + // in case it is an interrupt endpoint, disable it + usb_hw_clear->int_ep_ctrl = (1 << (ep->interrupt_num + 1)); + usb_hw->int_ep_addr_ctrl[ep->interrupt_num] = 0; + // unconfigure the endpoint + ep->configured = false; + *ep->endpoint_control = 0; + *ep->buffer_control = 0; + hw_endpoint_reset_transfer(ep); + ep->dev_addr = ADDR_INVALID; // don't find this one again + ep = _hw_find_first_endpoint(dev_addr); + } pico_trace("hcd_device_close %d\n", dev_addr); } From 006522e4375d58bfe01b9745ff7df35fb3d48868 Mon Sep 17 00:00:00 2001 From: rppicomidi Date: Fri, 12 Nov 2021 14:59:19 -0800 Subject: [PATCH 027/504] on unplug release device endpoints --- src/host/usbh.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/host/usbh.c b/src/host/usbh.c index f74e7114c..eca72a1c5 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -546,6 +546,9 @@ void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port hcd_device_close(rhport, dev_addr); + // release all endpoints associated with the device + tu_memclr(dev->ep_status, sizeof(dev->ep_status)); + dev->state = TUSB_DEVICE_STATE_UNPLUG; } } From 3e3fe1e429aed7bd0000f49b1ef15f83eb815a19 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 30 Nov 2021 17:36:52 +0700 Subject: [PATCH 028/504] improve hcd_device_close() for rp2040 --- src/host/usbh.c | 5 +- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 52 +++++++------------- 2 files changed, 21 insertions(+), 36 deletions(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index eca72a1c5..b8439addc 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -541,12 +541,11 @@ void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port usbh_class_drivers[drv_id].close(dev_addr); } - memset(dev->itf2drv, DRVID_INVALID, sizeof(dev->itf2drv)); // invalid mapping - memset(dev->ep2drv , DRVID_INVALID, sizeof(dev->ep2drv )); // invalid mapping - hcd_device_close(rhport, dev_addr); // release all endpoints associated with the device + memset(dev->itf2drv, DRVID_INVALID, sizeof(dev->itf2drv)); // invalid mapping + memset(dev->ep2drv , DRVID_INVALID, sizeof(dev->ep2drv )); // invalid mapping tu_memclr(dev->ep_status, sizeof(dev->ep_status)); dev->state = TUSB_DEVICE_STATE_UNPLUG; diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 97dae480d..3e80dd872 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -64,8 +64,6 @@ enum { USB_SIE_CTRL_PULLDOWN_EN_BITS | USB_SIE_CTRL_EP0_INT_1BUF_BITS }; -enum { ADDR_INVALID = 0xFFu }; - static struct hw_endpoint *get_dev_ep(uint8_t dev_addr, uint8_t ep_addr) { uint8_t num = tu_edpt_number(ep_addr); @@ -348,21 +346,6 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t } } -// return struct hw_endpoint* pointing to the endpoint in the pool or NULL if the dev_addr is not found -static struct hw_endpoint *_hw_find_first_endpoint(uint8_t dev_addr) -{ - struct hw_endpoint *ep = NULL; - for (uint i = 1; i < TU_ARRAY_SIZE(ep_pool); i++) - { - ep = &ep_pool[i]; - if (ep->dev_addr == dev_addr && ep->configured) - { - return ep; - } - } - return NULL; -} - //--------------------------------------------------------------------+ // HCD API //--------------------------------------------------------------------+ @@ -429,25 +412,28 @@ tusb_speed_t hcd_port_speed_get(uint8_t rhport) // Close all opened endpoint belong to this device void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { - assert(rhport == 0); - if (dev_addr == 0) - return; + pico_trace("hcd_device_close %d\n", dev_addr); + (void) rhport; - struct hw_endpoint *ep = _hw_find_first_endpoint(dev_addr); - while (ep) + if (dev_addr == 0) return; + + for (size_t i = 1; i < TU_ARRAY_SIZE(ep_pool); i++) + { + hw_endpoint_t* ep = &ep_pool[i]; + + if (ep->dev_addr == dev_addr && ep->configured) { - // in case it is an interrupt endpoint, disable it - usb_hw_clear->int_ep_ctrl = (1 << (ep->interrupt_num + 1)); - usb_hw->int_ep_addr_ctrl[ep->interrupt_num] = 0; - // unconfigure the endpoint - ep->configured = false; - *ep->endpoint_control = 0; - *ep->buffer_control = 0; - hw_endpoint_reset_transfer(ep); - ep->dev_addr = ADDR_INVALID; // don't find this one again - ep = _hw_find_first_endpoint(dev_addr); + // in case it is an interrupt endpoint, disable it + usb_hw_clear->int_ep_ctrl = (1 << (ep->interrupt_num + 1)); + usb_hw->int_ep_addr_ctrl[ep->interrupt_num] = 0; + + // unconfigure the endpoint + ep->configured = false; + *ep->endpoint_control = 0; + *ep->buffer_control = 0; + hw_endpoint_reset_transfer(ep); } - pico_trace("hcd_device_close %d\n", dev_addr); + } } uint32_t hcd_frame_number(uint8_t rhport) From 9bccc8068baf6efef0bd040ec5238369c0a03c0f Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Tue, 30 Nov 2021 23:13:20 +0900 Subject: [PATCH 029/504] Add register settings to handle a HUB --- src/portable/mentor/musb/hcd_musb.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/portable/mentor/musb/hcd_musb.c b/src/portable/mentor/musb/hcd_musb.c index b4931a793..dc614d074 100644 --- a/src/portable/mentor/musb/hcd_musb.c +++ b/src/portable/mentor/musb/hcd_musb.c @@ -325,7 +325,7 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_ { (void)rhport; - const unsigned req = _hcd.bmRequestType; + unsigned const req = _hcd.bmRequestType; TU_ASSERT(req != REQUEST_TYPE_INVALID); TU_ASSERT(dev_addr < sizeof(_hcd.ctl_mps)); @@ -453,6 +453,7 @@ static void process_ep0(uint8_t rhport) /* STATUS IN */ TU_ASSERT(USB_CSRL0_RXRDY == (csrl & USB_CSRL0_RXRDY),); TU_ASSERT(0 == USB0->COUNT0,); + USB0->CSRH0 = USB_CSRH0_FLUSH; USB0->CSRL0 = 0; _hcd.bmRequestType = REQUEST_TYPE_INVALID; hcd_event_xfer_complete(dev_addr, tu_edpt_addr(0, TUSB_DIR_IN), @@ -694,7 +695,17 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet _hcd.pipe0.buf = (void*)(uintptr_t)setup_packet; _hcd.pipe0.length = 8; _hcd.pipe0.remaining = 0; - _hcd.bmRequestType = REQUEST_TYPE_INVALID; + + hcd_devtree_info_t devtree; + hcd_devtree_get_info(dev_addr, &devtree); + switch (devtree.speed) { + default: return false; + case TUSB_SPEED_LOW: USB0->TYPE0 = USB_TYPE0_SPEED_LOW; break; + case TUSB_SPEED_FULL: USB0->TYPE0 = USB_TYPE0_SPEED_FULL; break; + case TUSB_SPEED_HIGH: USB0->TYPE0 = USB_TYPE0_SPEED_HIGH; break; + } + USB0->TXHUBADDR0 = devtree.hub_addr; + USB0->TXHUBPORT0 = devtree.hub_port; USB0->TXFUNCADDR0 = dev_addr; USB0->CSRL0 = USB_CSRL0_TXRDY | USB_CSRL0_SETUP; return true; @@ -702,6 +713,7 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) { + (void)rhport; if (sizeof(_hcd.ctl_mps) <= dev_addr) return false; unsigned const ep_addr = ep_desc->bEndpointAddress; unsigned const epn = tu_edpt_number(ep_addr); @@ -733,7 +745,9 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const pipe->remaining = 0; uint8_t pipe_type = 0; - switch (hcd_port_speed_get(rhport)) { + hcd_devtree_info_t devtree; + hcd_devtree_get_info(dev_addr, &devtree); + switch (devtree.speed) { default: return false; case TUSB_SPEED_LOW: pipe_type |= USB_TXTYPE1_SPEED_LOW; break; case TUSB_SPEED_FULL: pipe_type |= USB_TXTYPE1_SPEED_FULL; break; @@ -750,6 +764,8 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const hw_endpoint_t volatile *regs = edpt_regs(pipenum - 1); if (dir_tx) { fadr->TXFUNCADDR = dev_addr; + fadr->TXHUBADDR = devtree.hub_addr; + fadr->TXHUBPORT = devtree.hub_port; regs->TXMAXP = mps; regs->TXTYPE = pipe_type | epn; regs->TXINTERVAL = ep_desc->bInterval; @@ -760,6 +776,8 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const USB0->TXIE |= TU_BIT(pipenum); } else { fadr->RXFUNCADDR = dev_addr; + fadr->RXHUBADDR = devtree.hub_addr; + fadr->RXHUBPORT = devtree.hub_port; regs->RXMAXP = mps; regs->RXTYPE = pipe_type | epn; regs->RXINTERVAL = ep_desc->bInterval; From 0612433eef6e6a7029b314a4a59ef591e72341f5 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 1 Dec 2021 12:14:44 +0700 Subject: [PATCH 030/504] add chipidea highspeed controller add warning to transdimension for the rename --- examples/host/cdc_msc_hid/Makefile | 2 - hw/bsp/lpc18/family.mk | 4 +- src/device/dcd_attr.h | 2 + src/portable/chipidea/ci_hs/ci_hs_type.h | 136 ++++ src/portable/chipidea/ci_hs/dcd_ci_hs.c | 662 ++++++++++++++++++ src/portable/chipidea/ci_hs/hcd_ci_hs.c | 117 ++++ .../nxp/transdimension/dcd_transdimension.c | 2 + .../nxp/transdimension/hcd_transdimension.c | 2 + 8 files changed, 924 insertions(+), 3 deletions(-) create mode 100644 src/portable/chipidea/ci_hs/ci_hs_type.h create mode 100644 src/portable/chipidea/ci_hs/dcd_ci_hs.c create mode 100644 src/portable/chipidea/ci_hs/hcd_ci_hs.c diff --git a/examples/host/cdc_msc_hid/Makefile b/examples/host/cdc_msc_hid/Makefile index 0ad9dd856..ce0dd1a40 100644 --- a/examples/host/cdc_msc_hid/Makefile +++ b/examples/host/cdc_msc_hid/Makefile @@ -20,9 +20,7 @@ SRC_C += \ src/host/hub.c \ src/host/usbh.c \ src/host/usbh_control.c \ - src/portable/ehci/ehci.c \ src/portable/ohci/ohci.c \ - src/portable/nxp/transdimension/hcd_transdimension.c \ src/portable/nxp/lpc17_40/hcd_lpc17_40.c include ../../rules.mk diff --git a/hw/bsp/lpc18/family.mk b/hw/bsp/lpc18/family.mk index 79a00cb2d..7aa36abc4 100644 --- a/hw/bsp/lpc18/family.mk +++ b/hw/bsp/lpc18/family.mk @@ -18,7 +18,9 @@ CFLAGS += -Wno-error=unused-parameter -Wno-error=strict-prototypes -Wno-error=ca MCU_DIR = hw/mcu/nxp/lpcopen/lpc18xx/lpc_chip_18xx SRC_C += \ - src/portable/nxp/transdimension/dcd_transdimension.c \ + src/portable/chipidea/ci_hs/dcd_ci_hs.c \ + src/portable/chipidea/ci_hs/hcd_ci_hs.c \ + src/portable/ehci/ehci.c \ $(MCU_DIR)/../gcc/cr_startup_lpc18xx.c \ $(MCU_DIR)/src/chip_18xx_43xx.c \ $(MCU_DIR)/src/clock_18xx_43xx.c \ diff --git a/src/device/dcd_attr.h b/src/device/dcd_attr.h index 73d592e5c..3c5dadaf4 100644 --- a/src/device/dcd_attr.h +++ b/src/device/dcd_attr.h @@ -44,6 +44,7 @@ #elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX) // TODO USB0 has 6, USB1 has 4 + #define DCD_ATTR_CONTROLLER_CHIPIDEA_HS #define DCD_ATTR_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_LPC51UXX) @@ -58,6 +59,7 @@ #define DCD_ATTR_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_MIMXRT10XX) + #define DCD_ATTR_CONTROLLER_CHIPIDEA_HS #define DCD_ATTR_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_MKL25ZXX, OPT_MCU_K32L2BXX) diff --git a/src/portable/chipidea/ci_hs/ci_hs_type.h b/src/portable/chipidea/ci_hs/ci_hs_type.h new file mode 100644 index 000000000..402c26334 --- /dev/null +++ b/src/portable/chipidea/ci_hs/ci_hs_type.h @@ -0,0 +1,136 @@ +/* + * 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. + */ + +#ifndef CI_HS_TYPE_H_ +#define CI_HS_TYPE_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// USBCMD +enum { + USBCMD_RUN_STOP = TU_BIT(0), + USBCMD_RESET = TU_BIT(1), + USBCMD_SETUP_TRIPWIRE = TU_BIT(13), + USBCMD_ADD_QTD_TRIPWIRE = TU_BIT(14) ///< This bit is used as a semaphore to ensure the to proper addition of a new dTD to an active (primed) endpoint’s linked list. This bit is set and cleared by software during the process of adding a new dTD +// Interrupt Threshold bit 23:16 +}; + +// PORTSC1 +#define PORTSC1_PORT_SPEED_POS 26 + +enum { + PORTSC1_CURRENT_CONNECT_STATUS = TU_BIT(0), + PORTSC1_FORCE_PORT_RESUME = TU_BIT(6), + PORTSC1_SUSPEND = TU_BIT(7), + PORTSC1_FORCE_FULL_SPEED = TU_BIT(24), + PORTSC1_PORT_SPEED = TU_BIT(26) | TU_BIT(27) +}; + +// OTGSC +enum { + OTGSC_VBUS_DISCHARGE = TU_BIT(0), + OTGSC_VBUS_CHARGE = TU_BIT(1), +// OTGSC_HWASSIST_AUTORESET = TU_BIT(2), + OTGSC_OTG_TERMINATION = TU_BIT(3), ///< Must set to 1 when OTG go to device mode + OTGSC_DATA_PULSING = TU_BIT(4), + OTGSC_ID_PULLUP = TU_BIT(5), +// OTGSC_HWASSIT_DATA_PULSE = TU_BIT(6), +// OTGSC_HWASSIT_BDIS_ACONN = TU_BIT(7), + OTGSC_ID = TU_BIT(8), ///< 0 = A device, 1 = B Device + OTGSC_A_VBUS_VALID = TU_BIT(9), + OTGSC_A_SESSION_VALID = TU_BIT(10), + OTGSC_B_SESSION_VALID = TU_BIT(11), + OTGSC_B_SESSION_END = TU_BIT(12), + OTGSC_1MS_TOGGLE = TU_BIT(13), + OTGSC_DATA_BUS_PULSING_STATUS = TU_BIT(14), +}; + +// USBMode +enum { + USBMODE_CM_DEVICE = 2, + USBMODE_CM_HOST = 3, + + USBMODE_SLOM = TU_BIT(3), + USBMODE_SDIS = TU_BIT(4), + + USBMODE_VBUS_POWER_SELECT = TU_BIT(5), // Need to be enabled for LPC18XX/43XX in host mode +}; + +// Device Registers +typedef struct +{ + //------------- ID + HW Parameter Registers-------------// + __I uint32_t TU_RESERVED[64]; ///< For iMX RT10xx, but not used by LPC18XX/LPC43XX + + //------------- Capability Registers-------------// + __I uint8_t CAPLENGTH; ///< Capability Registers Length + __I uint8_t TU_RESERVED[1]; + __I uint16_t HCIVERSION; ///< Host Controller Interface Version + + __I uint32_t HCSPARAMS; ///< Host Controller Structural Parameters + __I uint32_t HCCPARAMS; ///< Host Controller Capability Parameters + __I uint32_t TU_RESERVED[5]; + + __I uint16_t DCIVERSION; ///< Device Controller Interface Version + __I uint8_t TU_RESERVED[2]; + + __I uint32_t DCCPARAMS; ///< Device Controller Capability Parameters + __I uint32_t TU_RESERVED[6]; + + //------------- Operational Registers -------------// + __IO uint32_t USBCMD; ///< USB Command Register + __IO uint32_t USBSTS; ///< USB Status Register + __IO uint32_t USBINTR; ///< Interrupt Enable Register + __IO uint32_t FRINDEX; ///< USB Frame Index + __I uint32_t TU_RESERVED; + __IO uint32_t DEVICEADDR; ///< Device Address + __IO uint32_t ENDPTLISTADDR; ///< Endpoint List Address + __I uint32_t TU_RESERVED; + __IO uint32_t BURSTSIZE; ///< Programmable Burst Size + __IO uint32_t TXFILLTUNING; ///< TX FIFO Fill Tuning + uint32_t TU_RESERVED[4]; + __IO uint32_t ENDPTNAK; ///< Endpoint NAK + __IO uint32_t ENDPTNAKEN; ///< Endpoint NAK Enable + __I uint32_t TU_RESERVED; + __IO uint32_t PORTSC1; ///< Port Status & Control + __I uint32_t TU_RESERVED[7]; + __IO uint32_t OTGSC; ///< On-The-Go Status & control + __IO uint32_t USBMODE; ///< USB Device Mode + __IO uint32_t ENDPTSETUPSTAT; ///< Endpoint Setup Status + __IO uint32_t ENDPTPRIME; ///< Endpoint Prime + __IO uint32_t ENDPTFLUSH; ///< Endpoint Flush + __I uint32_t ENDPTSTAT; ///< Endpoint Status + __IO uint32_t ENDPTCOMPLETE; ///< Endpoint Complete + __IO uint32_t ENDPTCTRL[8]; ///< Endpoint Control 0 - 7 +} dcd_registers_t, hcd_registers_t; + +#ifdef __cplusplus + } +#endif + +#endif /* CI_HS_TYPE_H_ */ diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c new file mode 100644 index 000000000..e531cd842 --- /dev/null +++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c @@ -0,0 +1,662 @@ +/* + * 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. + */ + +#include "tusb_option.h" + +#if TUSB_OPT_DEVICE_ENABLED && \ + (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX) + +//--------------------------------------------------------------------+ +// INCLUDE +//--------------------------------------------------------------------+ +#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX + #include "fsl_device_registers.h" + #define INCLUDE_FSL_DEVICE_REGISTERS +#else + // LPCOpen for 18xx & 43xx + #include "chip.h" +#endif + +#include "common/tusb_common.h" +#include "device/dcd.h" +#include "ci_hs_type.h" + +#if defined(__CORTEX_M) && __CORTEX_M == 7 && __DCACHE_PRESENT == 1 + #define CleanInvalidateDCache_by_Addr SCB_CleanInvalidateDCache_by_Addr +#else + #define CleanInvalidateDCache_by_Addr(_addr, _dsize) +#endif + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ + +// ENDPTCTRL +enum { + ENDPTCTRL_STALL = TU_BIT(0), + ENDPTCTRL_TOGGLE_INHIBIT = TU_BIT(5), // used for test only + ENDPTCTRL_TOGGLE_RESET = TU_BIT(6), + ENDPTCTRL_ENABLE = TU_BIT(7) +}; + +enum { + ENDPTCTRL_TYPE_POS = 2, // Endpoint type is 2-bit field +}; + +// USBSTS, USBINTR +enum { + INTR_USB = TU_BIT(0), + INTR_ERROR = TU_BIT(1), + INTR_PORT_CHANGE = TU_BIT(2), + INTR_RESET = TU_BIT(6), + INTR_SOF = TU_BIT(7), + INTR_SUSPEND = TU_BIT(8), + INTR_NAK = TU_BIT(16) +}; + +// Queue Transfer Descriptor +typedef struct +{ + // Word 0: Next QTD Pointer + uint32_t next; ///< Next link pointer This field contains the physical memory address of the next dTD to be processed + + // Word 1: qTQ Token + uint32_t : 3 ; + volatile uint32_t xact_err : 1 ; + uint32_t : 1 ; + volatile uint32_t buffer_err : 1 ; + volatile uint32_t halted : 1 ; + volatile uint32_t active : 1 ; + uint32_t : 2 ; + uint32_t iso_mult_override : 2 ; ///< This field can be used for transmit ISOs to override the MULT field in the dQH. This field must be zero for all packet types that are not transmit-ISO. + uint32_t : 3 ; + uint32_t int_on_complete : 1 ; + volatile uint32_t total_bytes : 15 ; + uint32_t : 1 ; + + // Word 2-6: Buffer Page Pointer List, Each element in the list is a 4K page aligned, physical memory address. The lower 12 bits in each pointer are reserved (except for the first one) as each memory pointer must reference the start of a 4K page + uint32_t buffer[5]; ///< buffer1 has frame_n for TODO Isochronous + + //--------------------------------------------------------------------+ + // TD is 32 bytes aligned but occupies only 28 bytes + // Therefore there are 4 bytes padding that we can use. + //--------------------------------------------------------------------+ + uint16_t expected_bytes; + uint8_t reserved[2]; +} dcd_qtd_t; + +TU_VERIFY_STATIC( sizeof(dcd_qtd_t) == 32, "size is not correct"); + +// Queue Head +typedef struct +{ + // Word 0: Capabilities and Characteristics + uint32_t : 15 ; ///< Number of packets executed per transaction descriptor 00 - Execute N transactions as demonstrated by the USB variable length protocol where N is computed using Max_packet_length and the Total_bytes field in the dTD. 01 - Execute one transaction 10 - Execute two transactions 11 - Execute three transactions Remark: Non-isochronous endpoints must set MULT = 00. Remark: Isochronous endpoints must set MULT = 01, 10, or 11 as needed. + uint32_t int_on_setup : 1 ; ///< Interrupt on setup This bit is used on control type endpoints to indicate if USBINT is set in response to a setup being received. + uint32_t max_packet_size : 11 ; ///< Endpoint's wMaxPacketSize + uint32_t : 2 ; + uint32_t zero_length_termination : 1 ; ///< This bit is used for non-isochronous endpoints to indicate when a zero-length packet is received to terminate transfers in case the total transfer length is “multiple”. 0 - Enable zero-length packet to terminate transfers equal to a multiple of Max_packet_length (default). 1 - Disable zero-length packet on transfers that are equal in length to a multiple Max_packet_length. + uint32_t iso_mult : 2 ; ///< + + // Word 1: Current qTD Pointer + volatile uint32_t qtd_addr; + + // Word 2-9: Transfer Overlay + volatile dcd_qtd_t qtd_overlay; + + // Word 10-11: Setup request (control OUT only) + volatile tusb_control_request_t setup_request; + + //--------------------------------------------------------------------+ + // QHD is 64 bytes aligned but occupies only 48 bytes + // Therefore there are 16 bytes padding that we can use. + //--------------------------------------------------------------------+ + tu_fifo_t * ff; + uint8_t reserved[12]; +} dcd_qhd_t; + +TU_VERIFY_STATIC( sizeof(dcd_qhd_t) == 64, "size is not correct"); + +//--------------------------------------------------------------------+ +// Variables +//--------------------------------------------------------------------+ + +typedef struct +{ + dcd_registers_t* regs; // registers + const IRQn_Type irqnum; // IRQ number + const uint8_t ep_count; // Max bi-directional Endpoints +}dcd_controller_t; + +#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX + static const dcd_controller_t _dcd_controller[] = + { + // RT1010 and RT1020 only has 1 USB controller + #if FSL_FEATURE_SOC_USBHS_COUNT == 1 + { .regs = (dcd_registers_t*) USB_BASE , .irqnum = USB_OTG1_IRQn, .ep_count = 8 } + #else + { .regs = (dcd_registers_t*) USB1_BASE, .irqnum = USB_OTG1_IRQn, .ep_count = 8 }, + { .regs = (dcd_registers_t*) USB2_BASE, .irqnum = USB_OTG2_IRQn, .ep_count = 8 } + #endif + }; + +#else + static const dcd_controller_t _dcd_controller[] = + { + { .regs = (dcd_registers_t*) LPC_USB0_BASE, .irqnum = USB0_IRQn, .ep_count = 6 }, + { .regs = (dcd_registers_t*) LPC_USB1_BASE, .irqnum = USB1_IRQn, .ep_count = 4 } + }; +#endif + +#define QTD_NEXT_INVALID 0x01 + +typedef struct { + // Must be at 2K alignment + // Each endpoint with direction (IN/OUT) occupies a queue head + // for portability, TinyUSB only queue 1 TD for each Qhd + dcd_qhd_t qhd[DCD_ATTR_ENDPOINT_MAX][2] TU_ATTR_ALIGNED(64); + dcd_qtd_t qtd[DCD_ATTR_ENDPOINT_MAX][2] TU_ATTR_ALIGNED(32); +}dcd_data_t; + +CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(2048) +static dcd_data_t _dcd_data; + +//--------------------------------------------------------------------+ +// Controller API +//--------------------------------------------------------------------+ + +/// follows LPC43xx User Manual 23.10.3 +static void bus_reset(uint8_t rhport) +{ + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + + // The reset value for all endpoint types is the control endpoint. If one endpoint + // direction is enabled and the paired endpoint of opposite direction is disabled, then the + // endpoint type of the unused direction must be changed from the control type to any other + // type (e.g. bulk). Leaving an un-configured endpoint control will cause undefined behavior + // for the data PID tracking on the active endpoint. + for( uint8_t i=1; i < _dcd_controller[rhport].ep_count; i++) + { + dcd_reg->ENDPTCTRL[i] = (TUSB_XFER_BULK << ENDPTCTRL_TYPE_POS) | (TUSB_XFER_BULK << (16+ENDPTCTRL_TYPE_POS)); + } + + //------------- Clear All Registers -------------// + dcd_reg->ENDPTNAK = dcd_reg->ENDPTNAK; + dcd_reg->ENDPTNAKEN = 0; + dcd_reg->USBSTS = dcd_reg->USBSTS; + dcd_reg->ENDPTSETUPSTAT = dcd_reg->ENDPTSETUPSTAT; + dcd_reg->ENDPTCOMPLETE = dcd_reg->ENDPTCOMPLETE; + + while (dcd_reg->ENDPTPRIME) {} + dcd_reg->ENDPTFLUSH = 0xFFFFFFFF; + while (dcd_reg->ENDPTFLUSH) {} + + // read reset bit in portsc + + //------------- Queue Head & Queue TD -------------// + tu_memclr(&_dcd_data, sizeof(dcd_data_t)); + + //------------- Set up Control Endpoints (0 OUT, 1 IN) -------------// + _dcd_data.qhd[0][0].zero_length_termination = _dcd_data.qhd[0][1].zero_length_termination = 1; + _dcd_data.qhd[0][0].max_packet_size = _dcd_data.qhd[0][1].max_packet_size = CFG_TUD_ENDPOINT0_SIZE; + _dcd_data.qhd[0][0].qtd_overlay.next = _dcd_data.qhd[0][1].qtd_overlay.next = QTD_NEXT_INVALID; + + _dcd_data.qhd[0][0].int_on_setup = 1; // OUT only +} + +void dcd_init(uint8_t rhport) +{ + tu_memclr(&_dcd_data, sizeof(dcd_data_t)); + + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + + // Reset controller + dcd_reg->USBCMD |= USBCMD_RESET; + while( dcd_reg->USBCMD & USBCMD_RESET ) {} + + // Set mode to device, must be set immediately after reset + dcd_reg->USBMODE = USBMODE_CM_DEVICE; + dcd_reg->OTGSC = OTGSC_VBUS_DISCHARGE | OTGSC_OTG_TERMINATION; + +#if !TUD_OPT_HIGH_SPEED + dcd_reg->PORTSC1 = PORTSC1_FORCE_FULL_SPEED; +#endif + + CleanInvalidateDCache_by_Addr((uint32_t*) &_dcd_data, sizeof(dcd_data_t)); + + dcd_reg->ENDPTLISTADDR = (uint32_t) _dcd_data.qhd; // Endpoint List Address has to be 2K alignment + dcd_reg->USBSTS = dcd_reg->USBSTS; + dcd_reg->USBINTR = INTR_USB | INTR_ERROR | INTR_PORT_CHANGE | INTR_SUSPEND; + + dcd_reg->USBCMD &= ~0x00FF0000; // Interrupt Threshold Interval = 0 + dcd_reg->USBCMD |= USBCMD_RUN_STOP; // Connect +} + +void dcd_int_enable(uint8_t rhport) +{ + NVIC_EnableIRQ(_dcd_controller[rhport].irqnum); +} + +void dcd_int_disable(uint8_t rhport) +{ + NVIC_DisableIRQ(_dcd_controller[rhport].irqnum); +} + +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + // Response with status first before changing device address + dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); + + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + dcd_reg->DEVICEADDR = (dev_addr << 25) | TU_BIT(24); +} + +void dcd_remote_wakeup(uint8_t rhport) +{ + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + dcd_reg->PORTSC1 |= PORTSC1_FORCE_PORT_RESUME; +} + +void dcd_connect(uint8_t rhport) +{ + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + dcd_reg->USBCMD |= USBCMD_RUN_STOP; +} + +void dcd_disconnect(uint8_t rhport) +{ + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + dcd_reg->USBCMD &= ~USBCMD_RUN_STOP; +} + +//--------------------------------------------------------------------+ +// HELPER +//--------------------------------------------------------------------+ + +static void qtd_init(dcd_qtd_t* p_qtd, void * data_ptr, uint16_t total_bytes) +{ + // Force the CPU to flush the buffer. We increase the size by 31 because the call aligns the + // address to 32-byte boundaries. Buffer must be word aligned + CleanInvalidateDCache_by_Addr((uint32_t*) tu_align((uint32_t) data_ptr, 4), total_bytes + 31); + + tu_memclr(p_qtd, sizeof(dcd_qtd_t)); + + p_qtd->next = QTD_NEXT_INVALID; + p_qtd->active = 1; + p_qtd->total_bytes = p_qtd->expected_bytes = total_bytes; + p_qtd->int_on_complete = true; + + if (data_ptr != NULL) + { + p_qtd->buffer[0] = (uint32_t) data_ptr; + + uint32_t const bufend = p_qtd->buffer[0] + total_bytes; + for(uint8_t i=1; i<5; i++) + { + uint32_t const next_page = tu_align4k( p_qtd->buffer[i-1] ) + 4096; + if ( bufend <= next_page ) break; + + p_qtd->buffer[i] = next_page; + + // TODO page[1] FRAME_N for ISO transfer + } + } +} + +//--------------------------------------------------------------------+ +// DCD Endpoint Port +//--------------------------------------------------------------------+ +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + dcd_reg->ENDPTCTRL[epnum] |= ENDPTCTRL_STALL << (dir ? 16 : 0); + + // flush to abort any primed buffer + dcd_reg->ENDPTFLUSH = TU_BIT(epnum + (dir ? 16 : 0)); +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + // data toggle also need to be reset + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + dcd_reg->ENDPTCTRL[epnum] |= ENDPTCTRL_TOGGLE_RESET << ( dir ? 16 : 0 ); + dcd_reg->ENDPTCTRL[epnum] &= ~(ENDPTCTRL_STALL << ( dir ? 16 : 0)); +} + +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) +{ + uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); + uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); + + // Must not exceed max endpoint number + TU_ASSERT( epnum < _dcd_controller[rhport].ep_count ); + + //------------- Prepare Queue Head -------------// + dcd_qhd_t * p_qhd = &_dcd_data.qhd[epnum][dir]; + tu_memclr(p_qhd, sizeof(dcd_qhd_t)); + + p_qhd->zero_length_termination = 1; + p_qhd->max_packet_size = tu_edpt_packet_size(p_endpoint_desc); + if (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) + { + p_qhd->iso_mult = 1; + } + + p_qhd->qtd_overlay.next = QTD_NEXT_INVALID; + + CleanInvalidateDCache_by_Addr((uint32_t*) &_dcd_data, sizeof(dcd_data_t)); + + // Enable EP Control + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + + uint32_t const epctrl = (p_endpoint_desc->bmAttributes.xfer << ENDPTCTRL_TYPE_POS) | ENDPTCTRL_ENABLE | ENDPTCTRL_TOGGLE_RESET; + + if ( dir == TUSB_DIR_OUT ) + { + dcd_reg->ENDPTCTRL[epnum] = (dcd_reg->ENDPTCTRL[epnum] & 0xFFFF0000u) | epctrl; + }else + { + dcd_reg->ENDPTCTRL[epnum] = (dcd_reg->ENDPTCTRL[epnum] & 0x0000FFFFu) | (epctrl << 16); + } + + return true; +} + +void dcd_edpt_close_all (uint8_t rhport) +{ + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + + // Disable all non-control endpoints + for( uint8_t epnum=1; epnum < _dcd_controller[rhport].ep_count; epnum++) + { + _dcd_data.qhd[epnum][TUSB_DIR_OUT].qtd_overlay.halted = 1; + _dcd_data.qhd[epnum][TUSB_DIR_IN ].qtd_overlay.halted = 1; + + dcd_reg->ENDPTFLUSH = TU_BIT(epnum) | TU_BIT(epnum+16); + dcd_reg->ENDPTCTRL[epnum] = (TUSB_XFER_BULK << ENDPTCTRL_TYPE_POS) | (TUSB_XFER_BULK << (16+ENDPTCTRL_TYPE_POS)); + } +} + +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + + _dcd_data.qhd[epnum][dir].qtd_overlay.halted = 1; + + // Flush EP + uint32_t const flush_mask = TU_BIT(epnum + (dir ? 16 : 0)); + dcd_reg->ENDPTFLUSH = flush_mask; + while(dcd_reg->ENDPTFLUSH & flush_mask); + + // Clear EP enable + dcd_reg->ENDPTCTRL[epnum] &=~(ENDPTCTRL_ENABLE << (dir ? 16 : 0)); +} + +static void qhd_start_xfer(uint8_t rhport, uint8_t epnum, uint8_t dir) +{ + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + dcd_qhd_t* p_qhd = &_dcd_data.qhd[epnum][dir]; + dcd_qtd_t* p_qtd = &_dcd_data.qtd[epnum][dir]; + + p_qhd->qtd_overlay.halted = false; // clear any previous error + p_qhd->qtd_overlay.next = (uint32_t) p_qtd; // link qtd to qhd + + // flush cache + CleanInvalidateDCache_by_Addr((uint32_t*) &_dcd_data, sizeof(dcd_data_t)); + + if ( epnum == 0 ) + { + // follows UM 24.10.8.1.1 Setup packet handling using setup lockout mechanism + // wait until ENDPTSETUPSTAT before priming data/status in response TODO add time out + while(dcd_reg->ENDPTSETUPSTAT & TU_BIT(0)) {} + } + + // start transfer + dcd_reg->ENDPTPRIME = TU_BIT(epnum + (dir ? 16 : 0)); +} + +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + dcd_qhd_t* p_qhd = &_dcd_data.qhd[epnum][dir]; + dcd_qtd_t* p_qtd = &_dcd_data.qtd[epnum][dir]; + + // Prepare qtd + qtd_init(p_qtd, buffer, total_bytes); + + // Start qhd transfer + p_qhd->ff = NULL; + qhd_start_xfer(rhport, epnum, dir); + + return true; +} + +// fifo has to be aligned to 4k boundary +bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + dcd_qhd_t * p_qhd = &_dcd_data.qhd[epnum][dir]; + dcd_qtd_t * p_qtd = &_dcd_data.qtd[epnum][dir]; + + tu_fifo_buffer_info_t fifo_info; + + if (dir) + { + tu_fifo_get_read_info(ff, &fifo_info); + } else + { + tu_fifo_get_write_info(ff, &fifo_info); + } + + if ( fifo_info.len_lin >= total_bytes ) + { + // Linear length is enough for this transfer + qtd_init(p_qtd, fifo_info.ptr_lin, total_bytes); + } + else + { + // linear part is not enough + + // prepare TD up to linear length + qtd_init(p_qtd, fifo_info.ptr_lin, fifo_info.len_lin); + + if ( !tu_offset4k((uint32_t) fifo_info.ptr_wrap) && !tu_offset4k(tu_fifo_depth(ff)) ) + { + // If buffer is aligned to 4K & buffer size is multiple of 4K + // We can make use of buffer page array to also combine the linear + wrapped length + p_qtd->total_bytes = p_qtd->expected_bytes = total_bytes; + + for(uint8_t i = 1, page = 0; i < 5; i++) + { + // pick up buffer array where linear ends + if (p_qtd->buffer[i] == 0) + { + p_qtd->buffer[i] = (uint32_t) fifo_info.ptr_wrap + 4096 * page; + page++; + } + } + + CleanInvalidateDCache_by_Addr((uint32_t*) tu_align((uint32_t) fifo_info.ptr_wrap, 4), total_bytes - fifo_info.len_wrap + 31); + } + else + { + // TODO we may need to carry the wrapped length after the linear part complete + // for now only transfer up to linear part + } + } + + // Start qhd transfer + p_qhd->ff = ff; + qhd_start_xfer(rhport, epnum, dir); + + return true; +} + +//--------------------------------------------------------------------+ +// ISR +//--------------------------------------------------------------------+ + +static void process_edpt_complete_isr(uint8_t rhport, uint8_t epnum, uint8_t dir) +{ + dcd_qhd_t * p_qhd = &_dcd_data.qhd[epnum][dir]; + dcd_qtd_t * p_qtd = &_dcd_data.qtd[epnum][dir]; + + uint8_t result = p_qtd->halted ? XFER_RESULT_STALLED : + ( p_qtd->xact_err || p_qtd->buffer_err ) ? XFER_RESULT_FAILED : XFER_RESULT_SUCCESS; + + if ( result != XFER_RESULT_SUCCESS ) + { + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + // flush to abort error buffer + dcd_reg->ENDPTFLUSH = TU_BIT(epnum + (dir ? 16 : 0)); + } + + uint16_t const xferred_bytes = p_qtd->expected_bytes - p_qtd->total_bytes; + + if (p_qhd->ff) + { + if (dir == TUSB_DIR_IN) + { + tu_fifo_advance_read_pointer(p_qhd->ff, xferred_bytes); + } else + { + tu_fifo_advance_write_pointer(p_qhd->ff, xferred_bytes); + } + } + + // only number of bytes in the IOC qtd + dcd_event_xfer_complete(rhport, tu_edpt_addr(epnum, dir), xferred_bytes, result, true); +} + +void dcd_int_handler(uint8_t rhport) +{ + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + + uint32_t const int_enable = dcd_reg->USBINTR; + uint32_t const int_status = dcd_reg->USBSTS & int_enable; + dcd_reg->USBSTS = int_status; // Acknowledge handled interrupt + + // disabled interrupt sources + if (int_status == 0) return; + + // Set if the port controller enters the full or high-speed operational state. + // either from Bus Reset or Suspended state + if (int_status & INTR_PORT_CHANGE) + { + // TU_LOG2("PortChange %08lx\r\n", dcd_reg->PORTSC1); + + // Reset interrupt is not enabled, we manually check if Port Change is due + // to connection / disconnection + if ( dcd_reg->USBSTS & INTR_RESET ) + { + dcd_reg->USBSTS = INTR_RESET; + + if (dcd_reg->PORTSC1 & PORTSC1_CURRENT_CONNECT_STATUS) + { + uint32_t const speed = (dcd_reg->PORTSC1 & PORTSC1_PORT_SPEED) >> PORTSC1_PORT_SPEED_POS; + bus_reset(rhport); + dcd_event_bus_reset(rhport, (tusb_speed_t) speed, true); + }else + { + dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); + } + } + else + { + // Triggered by resuming from suspended state + if ( !(dcd_reg->PORTSC1 & PORTSC1_SUSPEND) ) + { + dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); + } + } + } + + if (int_status & INTR_SUSPEND) + { + // TU_LOG2("Suspend %08lx\r\n", dcd_reg->PORTSC1); + + if (dcd_reg->PORTSC1 & PORTSC1_SUSPEND) + { + // Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration. + // Skip suspend event if we are not addressed + if ((dcd_reg->DEVICEADDR >> 25) & 0x0f) + { + dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); + } + } + } + + if (int_status & INTR_USB) + { + // Make sure we read the latest version of _dcd_data. + CleanInvalidateDCache_by_Addr((uint32_t*) &_dcd_data, sizeof(dcd_data_t)); + + uint32_t const edpt_complete = dcd_reg->ENDPTCOMPLETE; + dcd_reg->ENDPTCOMPLETE = edpt_complete; // acknowledge + + if (dcd_reg->ENDPTSETUPSTAT) + { + //------------- Set up Received -------------// + // 23.10.10.2 Operational model for setup transfers + dcd_reg->ENDPTSETUPSTAT = dcd_reg->ENDPTSETUPSTAT; + + dcd_event_setup_received(rhport, (uint8_t*)(uintptr_t) &_dcd_data.qhd[0][0].setup_request, true); + } + + // 23.10.12.3 Failed QTD also get ENDPTCOMPLETE set + // nothing to do, we will submit xfer as error to usbd + // if (int_status & INTR_ERROR) { } + + if ( edpt_complete ) + { + for(uint8_t epnum = 0; epnum < DCD_ATTR_ENDPOINT_MAX; epnum++) + { + if ( tu_bit_test(edpt_complete, epnum) ) process_edpt_complete_isr(rhport, epnum, TUSB_DIR_OUT); + if ( tu_bit_test(edpt_complete, epnum+16) ) process_edpt_complete_isr(rhport, epnum, TUSB_DIR_IN); + } + } + } + + if (int_status & INTR_SOF) + { + dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); + } +} + +#endif diff --git a/src/portable/chipidea/ci_hs/hcd_ci_hs.c b/src/portable/chipidea/ci_hs/hcd_ci_hs.c new file mode 100644 index 000000000..a62ebf2a3 --- /dev/null +++ b/src/portable/chipidea/ci_hs/hcd_ci_hs.c @@ -0,0 +1,117 @@ +/* + * 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. + */ + +#include "tusb_option.h" + +// Chipidea Highspeed USB IP implement EHCI for host functionality + +#if TUSB_OPT_HOST_ENABLED && \ + (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX) + +//--------------------------------------------------------------------+ +// INCLUDE +//--------------------------------------------------------------------+ +#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX + #include "fsl_device_registers.h" +#else + // LPCOpen for 18xx & 43xx + #include "chip.h" +#endif + +#include "common/tusb_common.h" +#include "ci_hs_type.h" +#include "portable/ehci/ehci_api.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ + +// TODO can be merged with dcd_controller_t +typedef struct +{ + uint32_t regs_base; // registers base + const IRQn_Type irqnum; // IRQ number +}hcd_controller_t; + +#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX + static const hcd_controller_t _hcd_controller[] = + { + // RT1010 and RT1020 only has 1 USB controller + #if FSL_FEATURE_SOC_USBHS_COUNT == 1 + { .regs_base = USB_BASE , .irqnum = USB_OTG1_IRQn } + #else + { .regs_base = USB1_BASE, .irqnum = USB_OTG1_IRQn }, + { .regs_base = USB2_BASE, .irqnum = USB_OTG2_IRQn } + #endif + }; + +#else + static const hcd_controller_t _hcd_controller[] = + { + { .regs_base = LPC_USB0_BASE, .irqnum = USB0_IRQn }, + { .regs_base = LPC_USB1_BASE, .irqnum = USB1_IRQn } + }; +#endif + +//--------------------------------------------------------------------+ +// Controller API +//--------------------------------------------------------------------+ + +bool hcd_init(uint8_t rhport) +{ + hcd_registers_t* hcd_reg = (hcd_registers_t*) _hcd_controller[rhport].regs_base; + + // Reset controller + hcd_reg->USBCMD |= USBCMD_RESET; + while( hcd_reg->USBCMD & USBCMD_RESET ) {} + + // Set mode to device, 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; +#else + hcd_reg->USBMODE = USBMODE_CM_HOST; +#endif + + // FIXME force full speed, still have issue with Highspeed enumeration + hcd_reg->PORTSC1 |= PORTSC1_FORCE_FULL_SPEED; + + return ehci_init(rhport, (uint32_t) &hcd_reg->CAPLENGTH, (uint32_t) &hcd_reg->USBCMD); +} + +void hcd_int_enable(uint8_t rhport) +{ + NVIC_EnableIRQ(_hcd_controller[rhport].irqnum); +} + +void hcd_int_disable(uint8_t rhport) +{ + NVIC_DisableIRQ(_hcd_controller[rhport].irqnum); +} + +#endif diff --git a/src/portable/nxp/transdimension/dcd_transdimension.c b/src/portable/nxp/transdimension/dcd_transdimension.c index 5ac041fbf..f6433293d 100644 --- a/src/portable/nxp/transdimension/dcd_transdimension.c +++ b/src/portable/nxp/transdimension/dcd_transdimension.c @@ -29,6 +29,8 @@ #if TUSB_OPT_DEVICE_ENABLED && \ (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX) +#warning "transdimenion is renamed to chipidea (portable/chipidea/ci_hs) to match other opensource naming convention such as linux. This file will be removed in the future, please update your makefile accordingly" + //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ diff --git a/src/portable/nxp/transdimension/hcd_transdimension.c b/src/portable/nxp/transdimension/hcd_transdimension.c index d216f0728..81ad3152d 100644 --- a/src/portable/nxp/transdimension/hcd_transdimension.c +++ b/src/portable/nxp/transdimension/hcd_transdimension.c @@ -31,6 +31,8 @@ #if TUSB_OPT_HOST_ENABLED && \ (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX) +#warning "transdimenion is renamed to chipidea (portable/chipidea/ci_hs) to match other opensource naming convention such as linux. This file will be removed in the future, please update your makefile accordingly" + //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ From bb7d1fa3bacb08717e8eebc55f81fde7bf810e3a Mon Sep 17 00:00:00 2001 From: Yunhao Tian Date: Tue, 30 Nov 2021 17:12:56 +0800 Subject: [PATCH 031/504] Add support for Allwinner F1Cx00s family Allwinner F1Cx00s family is a series of SoCs with Mentor MUSB controller and HS phy. It comes with a slightly different register space layout, and some quirks, so it's not multiplexed with the existing musb support library. This library currently requires to be compiled with https://github.com/hongxuyao/F1C100s_with_Keil_RTX4_emWin5 --- src/device/dcd_attr.h | 4 + src/portable/sunxi/dcd_sunxi_musb.c | 1152 +++++++++++++++++++++++++++ src/portable/sunxi/musb_def.h | 615 ++++++++++++++ src/tusb_option.h | 3 + 4 files changed, 1774 insertions(+) create mode 100644 src/portable/sunxi/dcd_sunxi_musb.c create mode 100644 src/portable/sunxi/musb_def.h diff --git a/src/device/dcd_attr.h b/src/device/dcd_attr.h index 73d592e5c..0ea46ebe1 100644 --- a/src/device/dcd_attr.h +++ b/src/device/dcd_attr.h @@ -195,6 +195,10 @@ #elif TU_CHECK_MCU(OPT_MCU_XMC4000) #define DCD_ATTR_ENDPOINT_MAX 8 +//------------ Allwinner -------------// +#elif TU_CHECK_MCU(OPT_MCU_F1C100S) + #define DCD_ATTR_ENDPOINT_MAX 4 + #else #warning "DCD_ATTR_ENDPOINT_MAX is not defined for this MCU, default to 8" #define DCD_ATTR_ENDPOINT_MAX 8 diff --git a/src/portable/sunxi/dcd_sunxi_musb.c b/src/portable/sunxi/dcd_sunxi_musb.c new file mode 100644 index 000000000..bb39d3890 --- /dev/null +++ b/src/portable/sunxi/dcd_sunxi_musb.c @@ -0,0 +1,1152 @@ +#include +#include +#include + +#include +#include +#include "musb_def.h" + +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; + +#if !TU_CHECK_MCU(OPT_MCU_F1C100S) + #error "Only f1c100s is supported" +#endif + +#define REQUEST_TYPE_INVALID (0xFFu) + +typedef struct { + uint_fast16_t beg; /* offset of including first element */ + uint_fast16_t end; /* offset of excluding the last element */ +} free_block_t; + +typedef struct TU_ATTR_PACKED +{ + void *buf; /* the start address of a transfer data buffer */ + uint16_t length; /* the number of bytes in the buffer */ + uint16_t remaining; /* the number of bytes remaining in the buffer */ +} pipe_state_t; + +typedef struct +{ + tusb_control_request_t setup_packet; + uint16_t remaining_ctrl; /* The number of bytes remaining in data stage of control transfer. */ + int8_t status_out; + pipe_state_t pipe0; + pipe_state_t pipe[2][7]; /* pipe[direction][endpoint number - 1] */ + uint16_t pipe_buf_is_fifo[2]; /* Bitmap. Each bit means whether 1:TU_FIFO or 0:POD. */ +} dcd_data_t; + +/*------------------------------------------------------------------ + * SUNXI FUNCTION + *------------------------------------------------------------------*/ + +static void usb_phy_write(int addr, int data, int len) +{ + int j = 0, usbc_bit = 0; + void *dest = (void *)USBC_REG_CSR(USBC0_BASE); + + usbc_bit = 1 << (0 * 2); + for (j = 0; j < len; j++) + { + /* set the bit address to be written */ + USBC_ClrBit_Mask_l(dest, 0xff << 8); + USBC_SetBit_Mask_l(dest, (addr + j) << 8); + + USBC_ClrBit_Mask_l(dest, usbc_bit); + /* set data bit */ + if (data & 0x1) + USBC_SetBit_Mask_l(dest, 1 << 7); + else + USBC_ClrBit_Mask_l(dest, 1 << 7); + + USBC_SetBit_Mask_l(dest, usbc_bit); + + USBC_ClrBit_Mask_l(dest, usbc_bit); + + data >>= 1; + } +} + +static void USBC_HardwareReset(void) +{ + // Reset phy and controller + USBC_REG_set_bit_l(USBPHY_CLK_RST_BIT, USBPHY_CLK_REG); + USBC_REG_set_bit_l(BUS_RST_USB_BIT, BUS_CLK_RST_REG); + osal_task_delay(2); + + USBC_REG_set_bit_l(USBPHY_CLK_GAT_BIT, USBPHY_CLK_REG); + USBC_REG_set_bit_l(USBPHY_CLK_RST_BIT, USBPHY_CLK_REG); + + USBC_REG_set_bit_l(BUS_CLK_USB_BIT, BUS_CLK_GATE0_REG); + USBC_REG_set_bit_l(BUS_RST_USB_BIT, BUS_CLK_RST_REG); +} + +static void USBC_PhyConfig() +{ + /* Regulation 45 ohms */ + usb_phy_write(0x0c, 0x01, 1); + + /* adjust PHY's magnitude and rate */ + usb_phy_write(0x20, 0x14, 5); + + /* threshold adjustment disconnect */ + usb_phy_write(0x2a, 3, 2); + + return; +} + +static void USBC_ConfigFIFO_Base() +{ + u32 reg_value; + + /* config usb fifo, 8kb mode */ + reg_value = USBC_Readl(SUNXI_SRAMC_BASE + 0x04); + reg_value &= ~(0x03 << 0); + reg_value |= (1 << 0); + USBC_Writel(reg_value, SUNXI_SRAMC_BASE + 0x04); +} + +static unsigned int USBC_WakeUp_ClearChangeDetect(unsigned int reg_val) +{ + unsigned int temp = reg_val; + /* vbus, id, dpdm, these bit is set 1 to clear, so we clear these bit when operate other bits */ + temp &= ~(1 << USBC_BP_ISCR_VBUS_CHANGE_DETECT); + temp &= ~(1 << USBC_BP_ISCR_ID_CHANGE_DETECT); + temp &= ~(1 << USBC_BP_ISCR_DPDM_CHANGE_DETECT); + + return temp; +} + +static void USBC_EnableDpDmPullUp(void) +{ + u32 reg_val = USBC_Readl(USBC_REG_ISCR(USBC0_BASE)); + reg_val |= (1 << USBC_BP_ISCR_DPDM_PULLUP_EN); + reg_val |= 3<beg) || (cur->end <= addr)); ++cur) ; + return cur; +} + +static inline int update_free_block_list(free_block_t *blks, unsigned num, uint_fast16_t addr, uint_fast16_t size) +{ + free_block_t *p = find_containing_block(blks, blks + num, addr); + TU_ASSERT(p != blks + num, -2); + if (p->beg == addr) { + /* Shrink block */ + p->beg = addr + size; + if (p->beg != p->end) return 0; + /* remove block */ + free_block_t *end = blks + num; + while (p + 1 < end) { + *p = *(p + 1); + ++p; + } + return -1; + } else { + /* Split into 2 blocks */ + free_block_t tmp = { + .beg = addr + size, + .end = p->end + }; + p->end = addr; + if (p->beg == p->end) { + if (tmp.beg != tmp.end) { + *p = tmp; + return 0; + } + /* remove block */ + free_block_t *end = blks + num; + while (p + 1 < end) { + *p = *(p + 1); + ++p; + } + return -1; + } + if (tmp.beg == tmp.end) return 0; + blks[num] = tmp; + return 1; + } +} + +static inline unsigned free_block_size(free_block_t const *blk) +{ + return blk->end - blk->beg; +} + +#if 0 +static inline void print_block_list(free_block_t const *blk, unsigned num) +{ + TU_LOG1("*************\n"); + for (unsigned i = 0; i < num; ++i) { + TU_LOG1(" Blk%u %u %u\n", i, blk->beg, blk->end); + ++blk; + } +} +#else +#define print_block_list(a,b) +#endif + +static unsigned find_free_memory(uint_fast16_t size_in_log2_minus3) +{ + free_block_t free_blocks[2 * (DCD_ATTR_ENDPOINT_MAX - 1)]; + unsigned num_blocks = 1; + + /* Initialize free memory block list */ + free_blocks[0].beg = 64 / 8; + free_blocks[0].end = (4 << 10) / 8; /* 4KiB / 8 bytes */ + for (int i = 1; i < DCD_ATTR_ENDPOINT_MAX; ++i) { + uint_fast16_t addr; + int num; + USBC_SelectActiveEp(i); + addr = USBC_Readw(USBC_REG_TXFIFOAD(USBC0_BASE)); + if (addr) { + unsigned sz = USBC_Readb(USBC_REG_TXFIFOSZ(USBC0_BASE)); + unsigned sft = (sz & USB_TXFIFOSZ_SIZE_M) + ((sz & USB_TXFIFOSZ_DPB) ? 1: 0); + num = update_free_block_list(free_blocks, num_blocks, addr, 1 << sft); + TU_ASSERT(-2 < num, 0); + num_blocks += num; + print_block_list(free_blocks, num_blocks); + } + addr = USBC_Readw(USBC_REG_RXFIFOAD(USBC0_BASE)); + if (addr) { + unsigned sz = USBC_Readb(USBC_REG_RXFIFOSZ(USBC0_BASE)); + unsigned sft = (sz & USB_RXFIFOSZ_SIZE_M) + ((sz & USB_RXFIFOSZ_DPB) ? 1: 0); + num = update_free_block_list(free_blocks, num_blocks, addr, 1 << sft); + TU_ASSERT(-2 < num, 0); + num_blocks += num; + print_block_list(free_blocks, num_blocks); + } + } + print_block_list(free_blocks, num_blocks); + + /* Find the best fit memory block */ + uint_fast16_t size_in_8byte_unit = 1 << size_in_log2_minus3; + free_block_t const *min = NULL; + uint_fast16_t min_sz = 0xFFFFu; + free_block_t const *end = &free_blocks[num_blocks]; + for (free_block_t const *cur = &free_blocks[0]; cur < end; ++cur) { + uint_fast16_t sz = free_block_size(cur); + if (sz < size_in_8byte_unit) continue; + if (size_in_8byte_unit == sz) return cur->beg; + if (sz < min_sz) min = cur; + } + TU_ASSERT(min, 0); + return min->beg; +} + +static void pipe_write_packet(void *buff, volatile void *fifo, unsigned cnt) +{ + u32 len = 0; + u32 i32 = 0; + u32 i8 = 0; + u8 *buf8 = 0; + u32 *buf32 = 0; + + //--<1>-- adjust data + buf32 = buff; + len = cnt; + + i32 = len >> 2; + i8 = len & 0x03; + + //--<2>-- deal with 4byte part + while (i32--) { + USBC_Writel(*buf32++, fifo); + } + + //--<3>-- deal with no 4byte part + buf8 = (u8 *)buf32; + while (i8--) { + USBC_Writeb(*buf8++, fifo); + } +} + +static void pipe_read_packet(void *buff, volatile void *fifo, unsigned cnt) +{ + u32 len = 0; + u32 i32 = 0; + u32 i8 = 0; + u8 *buf8 = 0; + u32 *buf32 = 0; + + //--<1>-- adjust data + buf32 = buff; + len = cnt; + + i32 = len >> 2; + i8 = len & 0x03; + + //--<2>-- deal with 4byte part + while (i32--) { + *buf32++ = USBC_Readl(fifo); + } + + //--<3>-- deal with no 4byte part + buf8 = (u8 *)buf32; + while (i8--) { + *buf8++ = USBC_Readb(fifo); + } +} + +static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigned len, unsigned dir) +{ + static const struct { + void (*tu_fifo_get_info)(tu_fifo_t *f, tu_fifo_buffer_info_t *info); + void (*tu_fifo_advance)(tu_fifo_t *f, uint16_t n); + void (*pipe_read_write)(void *buf, volatile void *fifo, unsigned len); + } ops[] = { + /* OUT */ {tu_fifo_get_write_info,tu_fifo_advance_write_pointer,pipe_read_packet}, + /* IN */ {tu_fifo_get_read_info, tu_fifo_advance_read_pointer, pipe_write_packet}, + }; + tu_fifo_buffer_info_t info; + ops[dir].tu_fifo_get_info(f, &info); + unsigned total_len = len; + len = TU_MIN(total_len, info.len_lin); + ops[dir].pipe_read_write(info.ptr_lin, fifo, len); + unsigned rem = total_len - len; + if (rem) { + len = TU_MIN(rem, info.len_wrap); + ops[dir].pipe_read_write(info.ptr_wrap, fifo, len); + rem -= len; + } + ops[dir].tu_fifo_advance(f, total_len - rem); +} + +/*------------------------------------------------------------------ + * TRANSFER FUNCTION DECLARATION + *------------------------------------------------------------------*/ + +static void process_setup_packet(uint8_t rhport) +{ + uint32_t *p = (void*)&_dcd.setup_packet; + p[0] = USBC_Readl(USBC_REG_EPFIFO0(USBC0_BASE)); + p[1] = USBC_Readl(USBC_REG_EPFIFO0(USBC0_BASE)); + + _dcd.pipe0.buf = NULL; + _dcd.pipe0.length = 0; + _dcd.pipe0.remaining = 0; + dcd_event_setup_received(rhport, (const uint8_t*)(uintptr_t)&_dcd.setup_packet, true); + + const unsigned len = _dcd.setup_packet.wLength; + _dcd.remaining_ctrl = len; + const unsigned dir_in = tu_edpt_dir(_dcd.setup_packet.bmRequestType); + /* Clear RX FIFO and reverse the transaction direction */ + if (len && dir_in) __USBC_Dev_ep0_ReadDataHalf(); +} + +static bool handle_xfer_in(uint_fast8_t ep_addr) +{ + unsigned epnum_minus1 = tu_edpt_number(ep_addr) - 1; + pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; + const unsigned rem = pipe->remaining; + + if (!rem) { + pipe->buf = NULL; + return true; + } + + const unsigned mps = USBC_Readw(USBC_REG_TXMAXP(USBC0_BASE)); + const unsigned len = TU_MIN(mps, rem); + uint8_t *buf = pipe->buf; + // TU_LOG1(" %p mps %d len %d rem %d\n", buf, mps, len, rem); + if (len) { + volatile void* addr = (volatile void*)(USBC_REG_EPFIFO1(USBC0_BASE) + (epnum_minus1 << 2)); + if (_dcd.pipe_buf_is_fifo[TUSB_DIR_IN] & TU_BIT(epnum_minus1)) { + pipe_read_write_packet_ff((tu_fifo_t *)buf, addr, len, TUSB_DIR_IN); + } else { + pipe_write_packet(buf, addr, len); + pipe->buf = buf + len; + } + pipe->remaining = rem - len; + } + __USBC_Dev_Tx_WriteDataComplete(); + // TU_LOG1(" TXCSRL%d = %x %d\n", epnum_minus1 + 1, regs->TXCSRL, rem - len); + return false; +} + +static bool handle_xfer_out(uint_fast8_t ep_addr) +{ + unsigned epnum_minus1 = tu_edpt_number(ep_addr) - 1; + pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; + // TU_LOG1(" RXCSRL%d = %x\n", epnum_minus1 + 1, regs->RXCSRL); + + TU_ASSERT(__USBC_Dev_Rx_IsReadDataReady()); + + const unsigned mps = USBC_Readw(USBC_REG_RXMAXP(USBC0_BASE)); + const unsigned rem = pipe->remaining; + const unsigned vld = USBC_Readw(USBC_REG_RXCOUNT(USBC0_BASE)); + const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); + uint8_t *buf = pipe->buf; + if (len) { + volatile void* addr = (volatile void*)(USBC_REG_EPFIFO1(USBC0_BASE) + (epnum_minus1 << 2)); + if (_dcd.pipe_buf_is_fifo[TUSB_DIR_OUT] & TU_BIT(epnum_minus1)) { + pipe_read_write_packet_ff((tu_fifo_t *)buf, addr, len, TUSB_DIR_OUT); + } else { + pipe_read_packet(buf, addr, len); + pipe->buf = buf + len; + } + pipe->remaining = rem - len; + __USBC_Dev_ep0_ReadDataComplete(); + } + if ((len < mps) || (rem == len)) { + pipe->buf = NULL; + return NULL != buf; + } + return false; +} + +static bool edpt_n_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) +{ + (void)rhport; + + unsigned epnum_minus1 = tu_edpt_number(ep_addr) - 1; + unsigned dir_in = tu_edpt_dir(ep_addr); + + pipe_state_t *pipe = &_dcd.pipe[dir_in][epnum_minus1]; + pipe->buf = buffer; + pipe->length = total_bytes; + pipe->remaining = total_bytes; + + USBC_SelectActiveEp(tu_edpt_number(ep_addr)); + + if (dir_in) { + handle_xfer_in(ep_addr); + } else { + if (__USBC_Dev_Rx_IsReadDataReady()) + __USBC_Dev_Rx_ReadDataComplete(); + } + return true; +} + +static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) +{ + (void)rhport; + TU_ASSERT(total_bytes <= 64); /* Current implementation supports for only up to 64 bytes. */ + + const unsigned req = _dcd.setup_packet.bmRequestType; + TU_ASSERT(req != REQUEST_TYPE_INVALID || total_bytes == 0); + + USBC_SelectActiveEp(0); + + if (req == REQUEST_TYPE_INVALID || _dcd.status_out) { + /* STATUS OUT stage. + * MUSB controller automatically handles STATUS OUT packets without + * software helps. We do not have to do anything. And STATUS stage + * may have already finished and received the next setup packet + * without calling this function, so we have no choice but to + * invoke the callback function of status packet here. */ + // TU_LOG1(" STATUS OUT CSRL0 = %x\n", CSRL0); + _dcd.status_out = 0; + if (req == REQUEST_TYPE_INVALID) { + dcd_event_xfer_complete(rhport, ep_addr, total_bytes, XFER_RESULT_SUCCESS, false); + } else { + /* The next setup packet has already been received, it aborts + * invoking callback function to avoid confusing TUSB stack. */ + TU_LOG1("Drop CONTROL_STAGE_ACK\n"); + } + return true; + } + const unsigned dir_in = tu_edpt_dir(ep_addr); + if (tu_edpt_dir(req) == dir_in) { /* DATA stage */ + TU_ASSERT(total_bytes <= _dcd.remaining_ctrl); + const unsigned rem = _dcd.remaining_ctrl; + const unsigned len = TU_MIN(TU_MIN(rem, 64), total_bytes); + if (dir_in) { + pipe_write_packet(buffer, (volatile void*) USBC_REG_EPFIFO0(USBC0_BASE), len); + + _dcd.pipe0.buf = buffer + len; + _dcd.pipe0.length = len; + _dcd.pipe0.remaining = 0; + + _dcd.remaining_ctrl = rem - len; + if ((len < 64) || (rem == len)) { + _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; /* Change to STATUS/SETUP stage */ + _dcd.status_out = 1; + /* Flush TX FIFO and reverse the transaction direction. */ + __USBC_Dev_ep0_WriteDataComplete(); + } else { + __USBC_Dev_ep0_WriteDataHalf(); + } + // TU_LOG1(" IN CSRL0 = %x\n", CSRL0); + } else { + // TU_LOG1(" OUT CSRL0 = %x\n", CSRL0); + _dcd.pipe0.buf = buffer; + _dcd.pipe0.length = len; + _dcd.pipe0.remaining = len; + __USBC_Dev_ep0_ReadDataHalf(); + } + } else if (dir_in) { + // TU_LOG1(" STATUS IN CSRL0 = %x\n", CSRL0); + _dcd.pipe0.buf = NULL; + _dcd.pipe0.length = 0; + _dcd.pipe0.remaining = 0; + /* Clear RX FIFO and reverse the transaction direction */ + __USBC_Dev_ep0_ReadDataComplete(); + } + return true; +} + +static void process_ep0(uint8_t rhport) +{ + USBC_SelectActiveEp(0); + uint_fast8_t csrl = USBC_Readw(USBC_REG_CSR0(USBC0_BASE)); + + // TU_LOG1(" EP0 CSRL0 = %x\n", csrl); + + if (csrl & USB_CSRL0_STALLED) { + /* Returned STALL packet to HOST. */ + __USBC_Dev_ep0_ClearStall(); + return; + } + + unsigned req = _dcd.setup_packet.bmRequestType; + if (csrl & USB_CSRL0_SETEND) { + // TU_LOG1(" ABORT by the next packets\n"); + USBC_Dev_Ctrl_ClearSetupEnd(); + if (req != REQUEST_TYPE_INVALID && _dcd.pipe0.buf) { + /* DATA stage was aborted by receiving STATUS or SETUP packet. */ + _dcd.pipe0.buf = NULL; + _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; + dcd_event_xfer_complete(rhport, + req & TUSB_DIR_IN_MASK, + _dcd.pipe0.length - _dcd.pipe0.remaining, + XFER_RESULT_SUCCESS, true); + } + req = REQUEST_TYPE_INVALID; + if (!(csrl & USB_CSRL0_RXRDY)) return; /* Received SETUP packet */ + } + + if (csrl & USB_CSRL0_RXRDY) { + /* Received SETUP or DATA OUT packet */ + if (req == REQUEST_TYPE_INVALID) { + /* SETUP */ + TU_ASSERT(sizeof(tusb_control_request_t) == USBC_Readw(USBC_REG_COUNT0(USBC0_BASE)),); + process_setup_packet(rhport); + return; + } + if (_dcd.pipe0.buf) { + /* DATA OUT */ + const unsigned vld = USBC_Readw(USBC_REG_COUNT0(USBC0_BASE)); + const unsigned rem = _dcd.pipe0.remaining; + const unsigned len = TU_MIN(TU_MIN(rem, 64), vld); + pipe_read_packet(_dcd.pipe0.buf, (volatile void*)USBC_REG_EPFIFO0(USBC0_BASE), len); + + _dcd.pipe0.remaining = rem - len; + _dcd.remaining_ctrl -= len; + + _dcd.pipe0.buf = NULL; + dcd_event_xfer_complete(rhport, + tu_edpt_addr(0, TUSB_DIR_OUT), + _dcd.pipe0.length - _dcd.pipe0.remaining, + XFER_RESULT_SUCCESS, true); + } + return; + } + + /* When CSRL0 is zero, it means that completion of sending a any length packet + * or receiving a zero length packet. */ + if (req != REQUEST_TYPE_INVALID && !tu_edpt_dir(req)) { + /* STATUS IN */ + if (*(const uint16_t*)(uintptr_t)&_dcd.setup_packet == 0x0500) { + /* The address must be changed on completion of the control transfer. */ + USBC_Dev_SetAddress((uint8_t)_dcd.setup_packet.wValue); + } + _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; + dcd_event_xfer_complete(rhport, + tu_edpt_addr(0, TUSB_DIR_IN), + _dcd.pipe0.length - _dcd.pipe0.remaining, + XFER_RESULT_SUCCESS, true); + return; + } + if (_dcd.pipe0.buf) { + /* DATA IN */ + _dcd.pipe0.buf = NULL; + dcd_event_xfer_complete(rhport, + tu_edpt_addr(0, TUSB_DIR_IN), + _dcd.pipe0.length - _dcd.pipe0.remaining, + XFER_RESULT_SUCCESS, true); + } +} + +static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) +{ + bool completed; + const unsigned dir_in = tu_edpt_dir(ep_addr); + const unsigned epn = tu_edpt_number(ep_addr); + + USBC_SelectActiveEp(epn); + + if (dir_in) { + // TU_LOG1(" TXCSRL%d = %x\n", epn_minus1 + 1, regs->TXCSRL); + if (__USBC_Dev_Tx_IsEpStall()) { + __USBC_Dev_Tx_ClearStall(); + return; + } + completed = handle_xfer_in(ep_addr); + } else { + // TU_LOG1(" RXCSRL%d = %x\n", epn_minus1 + 1, regs->RXCSRL); + if (__USBC_Dev_Rx_IsEpStall()) { + __USBC_Dev_Rx_ClearStall(); + return; + } + completed = handle_xfer_out(ep_addr); + } + + if (completed) { + pipe_state_t *pipe = &_dcd.pipe[dir_in][tu_edpt_number(ep_addr) - 1]; + dcd_event_xfer_complete(rhport, ep_addr, + pipe->length - pipe->remaining, + XFER_RESULT_SUCCESS, true); + } +} + +static void process_bus_reset(uint8_t rhport) +{ + /* When bmRequestType is REQUEST_TYPE_INVALID(0xFF), + * a control transfer state is SETUP or STATUS stage. */ + _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; + _dcd.status_out = 0; + /* When pipe0.buf has not NULL, DATA stage works in progress. */ + _dcd.pipe0.buf = NULL; + + USBC_Writew(1, USBC_REG_INTTxE(USBC0_BASE)); /* Enable only EP0 */ + USBC_Writew(0, USBC_REG_INTRxE(USBC0_BASE)); + + dcd_event_bus_reset(rhport, USBC_Dev_QueryTransferMode(), true); +} + +/*------------------------------------------------------------------ + * Device API + *------------------------------------------------------------------*/ + +static void usb_isr_handler() { + dcd_int_handler(0); +} + +void dcd_init(uint8_t rhport) +{ + dcd_disconnect(rhport); + USBC_HardwareReset(); + USBC_PhyConfig(); + USBC_ConfigFIFO_Base(); + USBC_EnableDpDmPullUp(); + USBC_ForceIdToHigh(); // Force device mode + USBC_ForceVbusValidToHigh(); + USBC_SelectBus(USBC_IO_TYPE_PIO, 0, 0); + + #if TUD_OPT_HIGH_SPEED + USBC_REG_set_bit_b(USBC_BP_POWER_D_HIGH_SPEED_EN, USBC_REG_PCTL(USBC0_BASE)); + #else + USBC_REG_clear_bit_b(USBC_BP_POWER_D_HIGH_SPEED_EN, USBC_REG_PCTL(USBC0_BASE)); + #endif + + USBC_Writeb((1 << USBC_BP_INTUSBE_EN_SUSPEND) + | (1 << USBC_BP_INTUSBE_EN_RESUME) + | (1 << USBC_BP_INTUSBE_EN_RESET) + | (1 << USBC_BP_INTUSBE_EN_SOF) + | (1 << USBC_BP_INTUSBE_EN_DISCONNECT) + , USBC_REG_INTUSBE(USBC0_BASE)); + f1c100s_intc_clear_pend(F1C100S_IRQ_USBOTG); + f1c100s_intc_set_isr(F1C100S_IRQ_USBOTG, usb_isr_handler); + + dcd_connect(rhport); +} + +// Connect by enabling internal pull-up resistor on D+/D- +void dcd_connect(uint8_t rhport) +{ + (void)rhport; + USBC_REG_set_bit_b(USBC_BP_POWER_D_SOFT_CONNECT, USBC_REG_PCTL(USBC0_BASE)); +} + +// Disconnect by disabling internal pull-up resistor on D+/D- +void dcd_disconnect(uint8_t rhport) +{ + (void)rhport; + USBC_REG_clear_bit_b(USBC_BP_POWER_D_SOFT_CONNECT, USBC_REG_PCTL(USBC0_BASE)); +} + +void dcd_int_enable(uint8_t rhport) +{ + (void)rhport; + f1c100s_intc_enable_irq(F1C100S_IRQ_USBOTG); +} + +static void musb_int_mask() +{ + f1c100s_intc_mask_irq(F1C100S_IRQ_USBOTG); +} + +void dcd_int_disable(uint8_t rhport) +{ + (void)rhport; + f1c100s_intc_disable_irq(F1C100S_IRQ_USBOTG); +} + +static void musb_int_unmask() +{ + f1c100s_intc_unmask_irq(F1C100S_IRQ_USBOTG); +} + +// Receive Set Address request, mcu port must also include status IN response +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + (void)rhport; + (void)dev_addr; + _dcd.pipe0.buf = NULL; + _dcd.pipe0.length = 0; + _dcd.pipe0.remaining = 0; + /* Clear RX FIFO to return ACK. */ + USBC_SelectActiveEp(0); + __USBC_Dev_ep0_ReadDataComplete(); +} + +// Wake up host +void dcd_remote_wakeup(uint8_t rhport) +{ + (void)rhport; + USBC_REG_set_bit_b(USBC_BP_POWER_D_RESUME, USBC_REG_PCTL(USBC0_BASE)); + osal_task_delay(10); + USBC_REG_clear_bit_b(USBC_BP_POWER_D_RESUME, USBC_REG_PCTL(USBC0_BASE)); +} + +//--------------------------------------------------------------------+ +// Endpoint API +//--------------------------------------------------------------------+ + +// Configure endpoint's registers according to descriptor +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) +{ + (void) rhport; + + uint16_t reg_val; + + const unsigned ep_addr = ep_desc->bEndpointAddress; + const unsigned epn = tu_edpt_number(ep_addr); + const unsigned dir_in = tu_edpt_dir(ep_addr); + const unsigned xfer = ep_desc->bmAttributes.xfer; + const unsigned mps = tu_edpt_packet_size(ep_desc); + + TU_ASSERT(epn < DCD_ATTR_ENDPOINT_MAX); + + pipe_state_t *pipe = &_dcd.pipe[dir_in][epn - 1]; + pipe->buf = NULL; + pipe->length = 0; + pipe->remaining = 0; + + musb_int_mask(); + + // volatile hw_endpoint_t *regs = edpt_regs(epn - 1); + USBC_SelectActiveEp(epn); + if (dir_in) { + USBC_Writew(mps, USBC_REG_TXMAXP(USBC0_BASE)); + + reg_val = (1 << USBC_BP_TXCSR_D_MODE) + | (1 << USBC_BP_TXCSR_D_FLUSH_FIFO) + | (1 << USBC_BP_TXCSR_D_CLEAR_DATA_TOGGLE); + if (xfer == TUSB_XFER_ISOCHRONOUS) + reg_val |= (1 << USBC_BP_TXCSR_D_ISO); + USBC_Writew(reg_val, USBC_REG_TXCSR(USBC0_BASE)); + + USBC_INT_EnableTxEp(epn); + } else { + USBC_Writew(mps, USBC_REG_RXMAXP(USBC0_BASE)); + + reg_val = (1 << USBC_BP_RXCSR_D_FLUSH_FIFO) + | (1 << USBC_BP_RXCSR_D_CLEAR_DATA_TOGGLE); + if (xfer == TUSB_XFER_ISOCHRONOUS) + reg_val |= (1 << USBC_BP_RXCSR_D_ISO); + USBC_Writew(reg_val, USBC_REG_RXCSR(USBC0_BASE)); + + USBC_INT_EnableRxEp(epn); + } + + /* Setup FIFO */ + int size_in_log2_minus3 = 28 - TU_MIN(28, __clz((uint32_t)mps)); + if ((8u << size_in_log2_minus3) < mps) ++size_in_log2_minus3; + unsigned addr = find_free_memory(size_in_log2_minus3); + TU_ASSERT(addr); + + if (dir_in) { + USBC_Writew(addr, USBC_REG_TXFIFOAD(USBC0_BASE)); + USBC_Writeb(size_in_log2_minus3, USBC_REG_TXFIFOSZ(USBC0_BASE)); + } else { + USBC_Writew(addr, USBC_REG_RXFIFOAD(USBC0_BASE)); + USBC_Writeb(size_in_log2_minus3, USBC_REG_RXFIFOSZ(USBC0_BASE)); + } + + musb_int_unmask(); + + return true; +} + +void dcd_edpt_close_all(uint8_t rhport) +{ + (void) rhport; + musb_int_mask(); + USBC_Writew(1, USBC_REG_INTTxE(USBC0_BASE)); /* Enable only EP0 */ + USBC_Writew(0, USBC_REG_INTRxE(USBC0_BASE)); + for (unsigned i = 1; i < DCD_ATTR_ENDPOINT_MAX; ++i) { + USBC_SelectActiveEp(i); + USBC_Writew(0, USBC_REG_TXMAXP(USBC0_BASE)); + USBC_Writew((1 << USBC_BP_TXCSR_D_MODE) | (1 << USBC_BP_TXCSR_D_CLEAR_DATA_TOGGLE) | (1 << USBC_BP_TXCSR_D_FLUSH_FIFO), + USBC_REG_TXCSR(USBC0_BASE)); + + USBC_Writew(0, USBC_REG_RXMAXP(USBC0_BASE)); + USBC_Writew((1 << USBC_BP_RXCSR_D_CLEAR_DATA_TOGGLE) | (1 << USBC_BP_RXCSR_D_FLUSH_FIFO), + USBC_REG_RXCSR(USBC0_BASE)); + + USBC_Writew(0, USBC_REG_TXFIFOAD(USBC0_BASE)); + USBC_Writeb(0, USBC_REG_TXFIFOSZ(USBC0_BASE)); + USBC_Writew(0, USBC_REG_RXFIFOAD(USBC0_BASE)); + USBC_Writeb(0, USBC_REG_RXFIFOSZ(USBC0_BASE)); + } + musb_int_unmask(); +} + +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) +{ + (void)rhport; + unsigned const epn = tu_edpt_number(ep_addr); + unsigned const dir_in = tu_edpt_dir(ep_addr); + + musb_int_mask(); + USBC_SelectActiveEp(epn); + if (dir_in) { + USBC_INT_DisableTxEp(epn); + USBC_Writew(0, USBC_REG_TXMAXP(USBC0_BASE)); + USBC_Writew((1 << USBC_BP_TXCSR_D_MODE) | (1 << USBC_BP_TXCSR_D_CLEAR_DATA_TOGGLE) | (1 << USBC_BP_TXCSR_D_FLUSH_FIFO), + USBC_REG_TXCSR(USBC0_BASE)); + + USBC_Writew(0, USBC_REG_TXFIFOAD(USBC0_BASE)); + USBC_Writeb(0, USBC_REG_TXFIFOSZ(USBC0_BASE)); + } else { + USBC_INT_DisableRxEp(epn); + USBC_Writew(0, USBC_REG_RXMAXP(USBC0_BASE)); + USBC_Writew((1 << USBC_BP_RXCSR_D_CLEAR_DATA_TOGGLE) | (1 << USBC_BP_RXCSR_D_FLUSH_FIFO), + USBC_REG_RXCSR(USBC0_BASE)); + + USBC_Writew(0, USBC_REG_RXFIFOAD(USBC0_BASE)); + USBC_Writeb(0, USBC_REG_RXFIFOSZ(USBC0_BASE)); + } + musb_int_unmask(); +} + +// 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) +{ + (void)rhport; + bool ret; + // TU_LOG1("X %x %d\n", ep_addr, total_bytes); + unsigned const epnum = tu_edpt_number(ep_addr); + musb_int_mask(); + + if (epnum) { + _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] &= ~TU_BIT(epnum - 1); + ret = edpt_n_xfer(rhport, ep_addr, buffer, total_bytes); + } else { + ret = edpt0_xfer(rhport, ep_addr, buffer, total_bytes); + } + musb_int_unmask(); + return ret; +} + +// Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack - optional, however, must be listed in usbd.c +bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) +{ + (void)rhport; + bool ret; + // TU_LOG1("X %x %d\n", ep_addr, total_bytes); + unsigned const epnum = tu_edpt_number(ep_addr); + TU_ASSERT(epnum); + + musb_int_mask(); + _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] |= TU_BIT(epnum - 1); + ret = edpt_n_xfer(rhport, ep_addr, (uint8_t*)ff, total_bytes); + musb_int_unmask(); + + return ret; +} + +// Stall endpoint +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void)rhport; + unsigned const epn = tu_edpt_number(ep_addr); + musb_int_mask(); + USBC_SelectActiveEp(epn); + if (0 == epn) { + if (!ep_addr) { /* Ignore EP80 */ + _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; + _dcd.pipe0.buf = NULL; + __USBC_Dev_ep0_SendStall(); + } + } else { + if (tu_edpt_dir(ep_addr)) { /* IN */ + __USBC_Dev_Tx_SendStall(); + } else { /* OUT */ + TU_ASSERT(!__USBC_Dev_Rx_IsReadDataReady(),); + __USBC_Dev_Rx_SendStall(); + } + } + musb_int_unmask(); +} + +// clear stall, data toggle is also reset to DATA0 +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void)rhport; + unsigned const epn = tu_edpt_number(ep_addr); + musb_int_mask(); + USBC_SelectActiveEp(epn); + if (0 != epn) { + if (tu_edpt_dir(ep_addr)) { /* IN */ + __USBC_Dev_Tx_ClearStall(); + } else { /* OUT */ + __USBC_Dev_Rx_ClearStall(); + } + } + musb_int_unmask(); +} + + +void dcd_int_handler(uint8_t rhport) +{ + uint8_t is; + uint16_t txis, rxis; + + is = USBC_Readb(USBC_REG_INTUSB(USBC0_BASE)); /* read interrupt status */ + txis = USBC_Readw(USBC_REG_INTTx(USBC0_BASE)); /* read interrupt status */ + rxis = USBC_Readw(USBC_REG_INTRx(USBC0_BASE)); /* read interrupt status */ + + is &= USBC_Readb(USBC_REG_INTUSBE(USBC0_BASE)); /* ignore disabled interrupts */ + USBC_Writeb(is, USBC_REG_INTUSB(USBC0_BASE)); /* sunxi musb requires a write to interrupt register to clear */ + if (is & USBC_INTUSB_DISCONNECT) { + dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); + } + if (is & USBC_INTUSB_SOF) { + dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); + } + if (is & USBC_INTUSB_RESET) { + /* ep0 FADDR must be 0 when (re)entering peripheral mode */ + USBC_SelectActiveEp(0); + USBC_Dev_SetAddress(0); + process_bus_reset(rhport); + } + if (is & USBC_INTUSB_RESUME) { + dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); + } + if (is & USBC_INTUSB_SUSPEND) { + dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); + } + + txis &= USBC_Readw(USBC_REG_INTTxE(USBC0_BASE)); + USBC_Writew(txis, USBC_REG_INTTx(USBC0_BASE)); + if (txis & USBC_INTTx_FLAG_EP0) { + process_ep0(rhport); + txis &= ~TU_BIT(0); + } + while (txis) { + unsigned const num = __builtin_ctz(txis); + process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_IN)); + txis &= ~TU_BIT(num); + } + + rxis &= USBC_Readw(USBC_REG_INTRxE(USBC0_BASE)); + USBC_Writew(rxis, USBC_REG_INTRx(USBC0_BASE)); + while (rxis) { + unsigned const num = __builtin_ctz(rxis); + process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_OUT)); + rxis &= ~TU_BIT(num); + } +} + diff --git a/src/portable/sunxi/musb_def.h b/src/portable/sunxi/musb_def.h new file mode 100644 index 000000000..f55ddab3b --- /dev/null +++ b/src/portable/sunxi/musb_def.h @@ -0,0 +1,615 @@ +#ifndef _TUSB_MUSB_DEF +#define _TUSB_MUSB_DEF + + +#define USBC_Readb(reg) (*(volatile unsigned char *)(reg)) +#define USBC_Readw(reg) (*(volatile unsigned short *)(reg)) +#define USBC_Readl(reg) (*(volatile unsigned long *)(reg)) + +#define USBC_Writeb(value, reg) (*(volatile unsigned char *)(reg) = (value)) +#define USBC_Writew(value, reg) (*(volatile unsigned short *)(reg) = (value)) +#define USBC_Writel(value, reg) (*(volatile unsigned long *)(reg) = (value)) + + +#define USBC_SetBit_Mask_b(reg,mask) do { \ + unsigned char _r = USBC_Readb(reg); \ + _r |= (unsigned char)(mask); \ + USBC_Writeb(_r,reg); \ + }while(0) +#define USBC_SetBit_Mask_w(reg,mask) do { \ + unsigned short _r = USBC_Readw(reg); \ + _r |= (unsigned short)(mask); \ + USBC_Writew(_r,reg); \ + }while(0) +#define USBC_SetBit_Mask_l(reg,mask) do { \ + unsigned int _r = USBC_Readl(reg); \ + _r |= (unsigned int)(mask); \ + USBC_Writel(_r,reg); \ + }while(0) + + +#define USBC_ClrBit_Mask_b(reg,mask) do { \ + unsigned char _r = USBC_Readb(reg); \ + _r &= (~(unsigned char)(mask)); \ + USBC_Writeb(_r,reg); \ + }while(0); +#define USBC_ClrBit_Mask_w(reg,mask) do { \ + unsigned short _r = USBC_Readw(reg); \ + _r &= (~(unsigned short)(mask)); \ + USBC_Writew(_r,reg); \ + }while(0) +#define USBC_ClrBit_Mask_l(reg,mask) do { \ + unsigned int _r = USBC_Readl(reg); \ + _r &= (~(unsigned int)(mask)); \ + USBC_Writel(_r,reg); \ + }while(0) +#define USBC_REG_test_bit_b(bp, reg) (USBC_Readb(reg) & (1 << (bp))) +#define USBC_REG_test_bit_w(bp, reg) (USBC_Readw(reg) & (1 << (bp))) +#define USBC_REG_test_bit_l(bp, reg) (USBC_Readl(reg) & (1 << (bp))) + +#define USBC_REG_set_bit_b(bp, reg) (USBC_Writeb((USBC_Readb(reg) | (1 << (bp))) , (reg))) +#define USBC_REG_set_bit_w(bp, reg) (USBC_Writew((USBC_Readw(reg) | (1 << (bp))) , (reg))) +#define USBC_REG_set_bit_l(bp, reg) (USBC_Writel((USBC_Readl(reg) | (1 << (bp))) , (reg))) + +#define USBC_REG_clear_bit_b(bp, reg) (USBC_Writeb((USBC_Readb(reg) & (~ (1 << (bp)))) , (reg))) +#define USBC_REG_clear_bit_w(bp, reg) (USBC_Writew((USBC_Readw(reg) & (~ (1 << (bp)))) , (reg))) +#define USBC_REG_clear_bit_l(bp, reg) (USBC_Writel((USBC_Readl(reg) & (~ (1 << (bp)))) , (reg))) + +#define SW_UDC_EPNUMS 3 + +#define SUNXI_SRAMC_BASE 0x01c00000 +//--------------------------------------------------------------- +// reg base +//--------------------------------------------------------------- +#define USBC0_BASE 0x01c13000 +#define USBC1_BASE 0x01c14000 +#define USBC2_BASE 0x01c1E000 + +//Some reg whithin musb +#define USBPHY_CLK_REG 0x01c200CC +#define USBPHY_CLK_RST_BIT 0 +#define USBPHY_CLK_GAT_BIT 1 + +#define BUS_CLK_RST_REG 0x01c202c0 //Bus Clock Reset Register Bit24 : USB CLK RST +#define BUS_RST_USB_BIT 24 + +#define BUS_CLK_GATE0_REG 0x01c20060 //Bus Clock Gating Register Bit24 : USB CLK GATE 0: Mask 1 : Pass +#define BUS_CLK_USB_BIT 24 + +//#define USB_INTR + +#define NDMA_CFG_REG +//----------------------------------------------------------------------- +// musb reg offset +//----------------------------------------------------------------------- + +#define USBC_REG_o_FADDR 0x0098 +#define USBC_REG_o_PCTL 0x0040 +#define USBC_REG_o_INTTx 0x0044 +#define USBC_REG_o_INTRx 0x0046 +#define USBC_REG_o_INTTxE 0x0048 +#define USBC_REG_o_INTRxE 0x004A +#define USBC_REG_o_INTUSB 0x004C +#define USBC_REG_o_INTUSBE 0x0050 +#define USBC_REG_o_FRNUM 0x0054 +#define USBC_REG_o_EPIND 0x0042 +#define USBC_REG_o_TMCTL 0x007C + +#define USBC_REG_o_TXMAXP 0x0080 +#define USBC_REG_o_CSR0 0x0082 +#define USBC_REG_o_TXCSR 0x0082 +#define USBC_REG_o_RXMAXP 0x0084 +#define USBC_REG_o_RXCSR 0x0086 +#define USBC_REG_o_COUNT0 0x0088 +#define USBC_REG_o_RXCOUNT 0x0088 +#define USBC_REG_o_EP0TYPE 0x008C +#define USBC_REG_o_TXTYPE 0x008C +#define USBC_REG_o_NAKLIMIT0 0x008D +#define USBC_REG_o_TXINTERVAL 0x008D +#define USBC_REG_o_RXTYPE 0x008E +#define USBC_REG_o_RXINTERVAL 0x008F + +//#define USBC_REG_o_CONFIGDATA 0x001F // + +#define USBC_REG_o_EPFIFO0 0x0000 +#define USBC_REG_o_EPFIFO1 0x0004 +#define USBC_REG_o_EPFIFO2 0x0008 +#define USBC_REG_o_EPFIFO3 0x000C +#define USBC_REG_o_EPFIFO4 0x0010 +#define USBC_REG_o_EPFIFO5 0x0014 +#define USBC_REG_o_EPFIFOx(n) (0x0000 + (n<<2)) + +#define USBC_REG_o_DEVCTL 0x0041 + +#define USBC_REG_o_TXFIFOSZ 0x0090 +#define USBC_REG_o_RXFIFOSZ 0x0094 +#define USBC_REG_o_TXFIFOAD 0x0092 +#define USBC_REG_o_RXFIFOAD 0x0096 + +#define USBC_REG_o_VEND0 0x0043 +#define USBC_REG_o_VEND1 0x007D +#define USBC_REG_o_VEND3 0x007E + +//#define USBC_REG_o_PHYCTL 0x006C +#define USBC_REG_o_EPINFO 0x0078 +#define USBC_REG_o_RAMINFO 0x0079 +#define USBC_REG_o_LINKINFO 0x007A +#define USBC_REG_o_VPLEN 0x007B +#define USBC_REG_o_HSEOF 0x007C +#define USBC_REG_o_FSEOF 0x007D +#define USBC_REG_o_LSEOF 0x007E + +//new +#define USBC_REG_o_FADDR0 0x0098 +#define USBC_REG_o_HADDR0 0x009A +#define USBC_REG_o_HPORT0 0x009B +#define USBC_REG_o_TXFADDRx 0x0098 +#define USBC_REG_o_TXHADDRx 0x009A +#define USBC_REG_o_TXHPORTx 0x009B +#define USBC_REG_o_RXFADDRx 0x009C +#define USBC_REG_o_RXHADDRx 0x009E +#define USBC_REG_o_RXHPORTx 0x009F + + +#define USBC_REG_o_RPCOUNT 0x008A + +//new +#define USBC_REG_o_ISCR 0x0400 +#define USBC_REG_o_PHYCTL 0x0404 +#define USBC_REG_o_PHYBIST 0x0408 +#define USBC_REG_o_PHYTUNE 0x040c + +#define USBC_REG_o_CSR 0x0410 + +#define USBC_REG_o_PMU_IRQ 0x0800 + +//----------------------------------------------------------------------- +// registers +//----------------------------------------------------------------------- + +#define USBC_REG_FADDR(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_FADDR ) +#define USBC_REG_PCTL(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_PCTL ) +#define USBC_REG_INTTx(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_INTTx ) +#define USBC_REG_INTRx(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_INTRx ) +#define USBC_REG_INTTxE(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_INTTxE ) +#define USBC_REG_INTRxE(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_INTRxE ) +#define USBC_REG_INTUSB(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_INTUSB ) +#define USBC_REG_INTUSBE(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_INTUSBE ) +#define USBC_REG_FRNUM(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_FRNUM ) +#define USBC_REG_EPIND(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_EPIND ) +#define USBC_REG_TMCTL(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_TMCTL ) +#define USBC_REG_TXMAXP(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_TXMAXP ) + +#define USBC_REG_CSR0(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_CSR0 ) +#define USBC_REG_TXCSR(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_TXCSR ) + +#define USBC_REG_RXMAXP(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_RXMAXP ) +#define USBC_REG_RXCSR(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_RXCSR ) + +#define USBC_REG_COUNT0(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_COUNT0 ) +#define USBC_REG_RXCOUNT(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_RXCOUNT ) + +#define USBC_REG_EP0TYPE(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_EP0TYPE ) +#define USBC_REG_TXTYPE(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_TXTYPE ) + +#define USBC_REG_NAKLIMIT0(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_NAKLIMIT0 ) +#define USBC_REG_TXINTERVAL(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_TXINTERVAL ) + +#define USBC_REG_RXTYPE(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_RXTYPE ) +#define USBC_REG_RXINTERVAL(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_RXINTERVAL ) +//#define USBC_REG_CONFIGDATA(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_CONFIGDATA ) +#define USBC_REG_EPFIFO0(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_EPFIFO0 ) +#define USBC_REG_EPFIFO1(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_EPFIFO1 ) +#define USBC_REG_EPFIFO2(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_EPFIFO2 ) +#define USBC_REG_EPFIFO3(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_EPFIFO3 ) +#define USBC_REG_EPFIFO4(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_EPFIFO4 ) +#define USBC_REG_EPFIFO5(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_EPFIFO5 ) +#define USBC_REG_EPFIFOx(usbc_base_addr, n) ((usbc_base_addr) + USBC_REG_o_EPFIFOx(n) ) +#define USBC_REG_DEVCTL(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_DEVCTL ) +#define USBC_REG_TXFIFOSZ(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_TXFIFOSZ ) +#define USBC_REG_RXFIFOSZ(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_RXFIFOSZ ) +#define USBC_REG_TXFIFOAD(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_TXFIFOAD ) +#define USBC_REG_RXFIFOAD(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_RXFIFOAD ) +#define USBC_REG_VEND0(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_VEND0 ) +#define USBC_REG_VEND1(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_VEND1 ) +#define USBC_REG_EPINFO(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_EPINFO ) +#define USBC_REG_RAMINFO(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_RAMINFO ) +#define USBC_REG_LINKINFO(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_LINKINFO ) +#define USBC_REG_VPLEN(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_VPLEN ) +#define USBC_REG_HSEOF(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_HSEOF ) +#define USBC_REG_FSEOF(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_FSEOF ) +#define USBC_REG_LSEOF(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_LSEOF ) + +#define USBC_REG_FADDR0(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_FADDR0 ) +#define USBC_REG_HADDR0(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_HADDR0 ) +#define USBC_REG_HPORT0(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_HPORT0 ) + +#define USBC_REG_TXFADDRx(usbc_base_addr, n) ((usbc_base_addr) + USBC_REG_o_TXFADDRx ) +#define USBC_REG_TXHADDRx(usbc_base_addr, n) ((usbc_base_addr) + USBC_REG_o_TXHADDRx ) +#define USBC_REG_TXHPORTx(usbc_base_addr, n) ((usbc_base_addr) + USBC_REG_o_TXHPORTx ) +#define USBC_REG_RXFADDRx(usbc_base_addr, n) ((usbc_base_addr) + USBC_REG_o_RXFADDRx ) +#define USBC_REG_RXHADDRx(usbc_base_addr, n) ((usbc_base_addr) + USBC_REG_o_RXHADDRx ) +#define USBC_REG_RXHPORTx(usbc_base_addr, n) ((usbc_base_addr) + USBC_REG_o_RXHPORTx ) + +#define USBC_REG_RPCOUNTx(usbc_base_addr, n) ((usbc_base_addr) + USBC_REG_o_RPCOUNT ) + +#define USBC_REG_ISCR(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_ISCR ) +#define USBC_REG_PHYCTL(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_PHYCTL ) +#define USBC_REG_PHYBIST(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_PHYBIST ) +#define USBC_REG_PHYTUNE(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_PHYTUNE ) +#define USBC_REG_PMU_IRQ(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_PMU_IRQ ) +#define USBC_REG_CSR(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_CSR) +//----------------------------------------------------------------------- +// bit position +//----------------------------------------------------------------------- + +/* USB Power Control for Host only */ +#define USBC_BP_POWER_H_HIGH_SPEED_EN 5 +#define USBC_BP_POWER_H_HIGH_SPEED_FLAG 4 +#define USBC_BP_POWER_H_RESET 3 +#define USBC_BP_POWER_H_RESUME 2 +#define USBC_BP_POWER_H_SUSPEND 1 +#define USBC_BP_POWER_H_SUEPEND_EN 0 + +/* USB Power Control for device only */ +#define USBC_BP_POWER_D_ISO_UPDATE_EN 7 +#define USBC_BP_POWER_D_SOFT_CONNECT 6 +#define USBC_BP_POWER_D_HIGH_SPEED_EN 5 +#define USBC_BP_POWER_D_HIGH_SPEED_FLAG 4 +#define USBC_BP_POWER_D_RESET_FLAG 3 +#define USBC_BP_POWER_D_RESUME 2 +#define USBC_BP_POWER_D_SUSPEND 1 +#define USBC_BP_POWER_D_ENABLE_SUSPENDM 0 + +/* interrupt flags for ep0 and the Tx ep1~4 */ +#define USBC_BP_INTTx_FLAG_EP5 5 +#define USBC_BP_INTTx_FLAG_EP4 4 +#define USBC_BP_INTTx_FLAG_EP3 3 +#define USBC_BP_INTTx_FLAG_EP2 2 +#define USBC_BP_INTTx_FLAG_EP1 1 +#define USBC_BP_INTTx_FLAG_EP0 0 + +/* interrupt flags for Rx ep1~4 */ +#define USBC_BP_INTRx_FLAG_EP5 5 +#define USBC_BP_INTRx_FLAG_EP4 4 +#define USBC_BP_INTRx_FLAG_EP3 3 +#define USBC_BP_INTRx_FLAG_EP2 2 +#define USBC_BP_INTRx_FLAG_EP1 1 + +/* interrupt enable for Tx ep0~4 */ +#define USBC_BP_INTTxE_EN_EP5 5 +#define USBC_BP_INTTxE_EN_EP4 4 +#define USBC_BP_INTTxE_EN_EP3 3 +#define USBC_BP_INTTxE_EN_EP2 2 +#define USBC_BP_INTTxE_EN_EP1 1 +#define USBC_BP_INTTxE_EN_EP0 0 + +/* interrupt enable for Rx ep1~4 */ +#define USBC_BP_INTRxE_EN_EP5 5 +#define USBC_BP_INTRxE_EN_EP4 4 +#define USBC_BP_INTRxE_EN_EP3 3 +#define USBC_BP_INTRxE_EN_EP2 2 +#define USBC_BP_INTRxE_EN_EP1 1 + +/* USB interrupt */ +#define USBC_BP_INTUSB_VBUS_ERROR 7 +#define USBC_BP_INTUSB_SESSION_REQ 6 +#define USBC_BP_INTUSB_DISCONNECT 5 +#define USBC_BP_INTUSB_CONNECT 4 +#define USBC_BP_INTUSB_SOF 3 +#define USBC_BP_INTUSB_RESET 2 +#define USBC_BP_INTUSB_RESUME 1 +#define USBC_BP_INTUSB_SUSPEND 0 + +/* USB interrupt enable */ +#define USBC_BP_INTUSBE_EN_VBUS_ERROR 7 +#define USBC_BP_INTUSBE_EN_SESSION_REQ 6 +#define USBC_BP_INTUSBE_EN_DISCONNECT 5 +#define USBC_BP_INTUSBE_EN_CONNECT 4 +#define USBC_BP_INTUSBE_EN_SOF 3 +#define USBC_BP_INTUSBE_EN_RESET 2 +#define USBC_BP_INTUSBE_EN_RESUME 1 +#define USBC_BP_INTUSBE_EN_SUSPEND 0 + +/* Test Mode Control */ +#define USBC_BP_TMCTL_FORCE_HOST 7 +#define USBC_BP_TMCTL_FIFO_ACCESS 6 +#define USBC_BP_TMCTL_FORCE_FS 5 +#define USBC_BP_TMCTL_FORCE_HS 4 +#define USBC_BP_TMCTL_TEST_PACKET 3 +#define USBC_BP_TMCTL_TEST_K 2 +#define USBC_BP_TMCTL_TEST_J 1 +#define USBC_BP_TMCTL_TEST_SE0_NAK 0 + +/* Tx Max packet */ +#define USBC_BP_TXMAXP_PACKET_COUNT 11 +#define USBC_BP_TXMAXP_MAXIMUM_PAYLOAD 0 + +/* Control and Status Register for ep0 for Host only */ +#define USBC_BP_CSR0_H_DisPing 11 +#define USBC_BP_CSR0_H_FlushFIFO 8 +#define USBC_BP_CSR0_H_NAK_Timeout 7 +#define USBC_BP_CSR0_H_StatusPkt 6 +#define USBC_BP_CSR0_H_ReqPkt 5 +#define USBC_BP_CSR0_H_Error 4 +#define USBC_BP_CSR0_H_SetupPkt 3 +#define USBC_BP_CSR0_H_RxStall 2 +#define USBC_BP_CSR0_H_TxPkRdy 1 +#define USBC_BP_CSR0_H_RxPkRdy 0 + +/* Control and Status Register for ep0 for device only */ +#define USBC_BP_CSR0_D_FLUSH_FIFO 8 +#define USBC_BP_CSR0_D_SERVICED_SETUP_END 7 +#define USBC_BP_CSR0_D_SERVICED_RX_PKT_READY 6 +#define USBC_BP_CSR0_D_SEND_STALL 5 +#define USBC_BP_CSR0_D_SETUP_END 4 +#define USBC_BP_CSR0_D_DATA_END 3 +#define USBC_BP_CSR0_D_SENT_STALL 2 +#define USBC_BP_CSR0_D_TX_PKT_READY 1 +#define USBC_BP_CSR0_D_RX_PKT_READY 0 + +/* Tx ep Control and Status Register for Host only */ +#define USBC_BP_TXCSR_H_AUTOSET 15 +#define USBC_BP_TXCSR_H_RESERVED 14 +#define USBC_BP_TXCSR_H_MODE 13 +#define USBC_BP_TXCSR_H_DMA_REQ_EN 12 +#define USBC_BP_TXCSR_H_FORCE_DATA_TOGGLE 11 +#define USBC_BP_TXCSR_H_DMA_REQ_MODE 10 +#define USBC_BP_TXCSR_H_NAK_TIMEOUT 7 +#define USBC_BP_TXCSR_H_CLEAR_DATA_TOGGLE 6 +#define USBC_BP_TXCSR_H_TX_STALL 5 +#define USBC_BP_TXCSR_H_FLUSH_FIFO 3 +#define USBC_BP_TXCSR_H_ERROR 2 +#define USBC_BP_TXCSR_H_FIFO_NOT_EMPTY 1 +#define USBC_BP_TXCSR_H_TX_READY 0 + +/* Tx ep Control and Status Register for Device only */ +#define USBC_BP_TXCSR_D_AUTOSET 15 +#define USBC_BP_TXCSR_D_ISO 14 +#define USBC_BP_TXCSR_D_MODE 13 +#define USBC_BP_TXCSR_D_DMA_REQ_EN 12 +#define USBC_BP_TXCSR_D_FORCE_DATA_TOGGLE 11 +#define USBC_BP_TXCSR_D_DMA_REQ_MODE 10 +#define USBC_BP_TXCSR_D_INCOMPLETE 7 +#define USBC_BP_TXCSR_D_CLEAR_DATA_TOGGLE 6 +#define USBC_BP_TXCSR_D_SENT_STALL 5 +#define USBC_BP_TXCSR_D_SEND_STALL 4 +#define USBC_BP_TXCSR_D_FLUSH_FIFO 3 +#define USBC_BP_TXCSR_D_UNDER_RUN 2 +#define USBC_BP_TXCSR_D_FIFO_NOT_EMPTY 1 +#define USBC_BP_TXCSR_D_TX_READY 0 + +/* Rx Max Packet */ +#define USBC_BP_RXMAXP_PACKET_COUNT 11 +#define USBC_BP_RXMAXP_MAXIMUM_PAYLOAD 0 + +/* Rx ep Control and Status Register for Host only */ +#define USBC_BP_RXCSR_H_AUTO_CLEAR 15 +#define USBC_BP_RXCSR_H_AUTO_REQ 14 +#define USBC_BP_RXCSR_H_DMA_REQ_EN 13 +#define USBC_BP_RXCSR_H_PID_ERROR 12 +#define USBC_BP_RXCSR_H_DMA_REQ_MODE 11 + +#define USBC_BP_RXCSR_H_INCOMPLETE 8 +#define USBC_BP_RXCSR_H_CLEAR_DATA_TOGGLE 7 +#define USBC_BP_RXCSR_H_RX_STALL 6 +#define USBC_BP_RXCSR_H_REQ_PACKET 5 +#define USBC_BP_RXCSR_H_FLUSH_FIFO 4 +#define USBC_BP_RXCSR_H_NAK_TIMEOUT 3 +#define USBC_BP_RXCSR_H_ERROR 2 +#define USBC_BP_RXCSR_H_FIFO_FULL 1 +#define USBC_BP_RXCSR_H_RX_PKT_READY 0 + +/* Rx ep Control and Status Register for Device only */ +#define USBC_BP_RXCSR_D_AUTO_CLEAR 15 +#define USBC_BP_RXCSR_D_ISO 14 +#define USBC_BP_RXCSR_D_DMA_REQ_EN 13 +#define USBC_BP_RXCSR_D_DISABLE_NYET 12 +#define USBC_BP_RXCSR_D_DMA_REQ_MODE 11 + +#define USBC_BP_RXCSR_D_INCOMPLETE 8 +#define USBC_BP_RXCSR_D_CLEAR_DATA_TOGGLE 7 +#define USBC_BP_RXCSR_D_SENT_STALL 6 +#define USBC_BP_RXCSR_D_SEND_STALL 5 +#define USBC_BP_RXCSR_D_FLUSH_FIFO 4 +#define USBC_BP_RXCSR_D_DATA_ERROR 3 +#define USBC_BP_RXCSR_D_OVERRUN 2 +#define USBC_BP_RXCSR_D_FIFO_FULL 1 +#define USBC_BP_RXCSR_D_RX_PKT_READY 0 + +/* Tx Type Register for host only */ +#define USBC_BP_TXTYPE_SPEED 6 //new +#define USBC_BP_TXTYPE_PROROCOL 4 +#define USBC_BP_TXTYPE_TARGET_EP_NUM 0 + +/* Rx Type Register for host only */ +#define USBC_BP_RXTYPE_SPEED 6 //new +#define USBC_BP_RXTYPE_PROROCOL 4 +#define USBC_BP_RXTYPE_TARGET_EP_NUM 0 + +/* Core Configueation */ +#define USBC_BP_CONFIGDATA_MPRXE 7 +#define USBC_BP_CONFIGDATA_MPTXE 6 +#define USBC_BP_CONFIGDATA_BIGENDIAN 5 +#define USBC_BP_CONFIGDATA_HBRXE 4 +#define USBC_BP_CONFIGDATA_HBTXE 3 +#define USBC_BP_CONFIGDATA_DYNFIFO_SIZING 2 +#define USBC_BP_CONFIGDATA_SOFTCONE 1 +#define USBC_BP_CONFIGDATA_UTMI_DATAWIDTH 0 + +/* OTG Device Control */ +#define USBC_BP_DEVCTL_B_DEVICE 7 +#define USBC_BP_DEVCTL_FS_DEV 6 +#define USBC_BP_DEVCTL_LS_DEV 5 + +#define USBC_BP_DEVCTL_VBUS 3 +#define USBC_BP_DEVCTL_HOST_MODE 2 +#define USBC_BP_DEVCTL_HOST_REQ 1 +#define USBC_BP_DEVCTL_SESSION 0 + +/* Tx EP FIFO size control */ +#define USBC_BP_TXFIFOSZ_DPB 4 +#define USBC_BP_TXFIFOSZ_SZ 0 + +/* Rx EP FIFO size control */ +#define USBC_BP_RXFIFOSZ_DPB 4 +#define USBC_BP_RXFIFOSZ_SZ 0 + +/* vendor0 */ +#define USBC_BP_VEND0_DRQ_SEL 1 +#define USBC_BP_VEND0_BUS_SEL 0 + +/* hub address */ +#define USBC_BP_HADDR_MULTI_TT 7 + +/* Interface Status and Control */ +#define USBC_BP_ISCR_VBUS_VALID_FROM_DATA 30 +#define USBC_BP_ISCR_VBUS_VALID_FROM_VBUS 29 +#define USBC_BP_ISCR_EXT_ID_STATUS 28 +#define USBC_BP_ISCR_EXT_DM_STATUS 27 +#define USBC_BP_ISCR_EXT_DP_STATUS 26 +#define USBC_BP_ISCR_MERGED_VBUS_STATUS 25 +#define USBC_BP_ISCR_MERGED_ID_STATUS 24 + +#define USBC_BP_ISCR_ID_PULLUP_EN 17 +#define USBC_BP_ISCR_DPDM_PULLUP_EN 16 +#define USBC_BP_ISCR_FORCE_ID 14 +#define USBC_BP_ISCR_FORCE_VBUS_VALID 12 +#define USBC_BP_ISCR_VBUS_VALID_SRC 10 + +#define USBC_BP_ISCR_HOSC_EN 7 +#define USBC_BP_ISCR_VBUS_CHANGE_DETECT 6 +#define USBC_BP_ISCR_ID_CHANGE_DETECT 5 +#define USBC_BP_ISCR_DPDM_CHANGE_DETECT 4 +#define USBC_BP_ISCR_IRQ_ENABLE 3 +#define USBC_BP_ISCR_VBUS_CHANGE_DETECT_EN 2 +#define USBC_BP_ISCR_ID_CHANGE_DETECT_EN 1 +#define USBC_BP_ISCR_DPDM_CHANGE_DETECT_EN 0 + + +#define SUNXI_EHCI_AHB_ICHR8_EN (1 << 10) +#define SUNXI_EHCI_AHB_INCR4_BURST_EN (1 << 9) +#define SUNXI_EHCI_AHB_INCRX_ALIGN_EN (1 << 8) +#define SUNXI_EHCI_ULPI_BYPASS_EN (1 << 0) +//----------------------------------------------------------------------- +// �Զ��� +//----------------------------------------------------------------------- + +/* usb��Դ���� */ +#define USBC_MAX_CTL_NUM 1 +#define USBC_MAX_EP_NUM 3 //ep0~2, ep�ĸ��� +#define USBC_MAX_FIFO_SIZE (2 * 1024) + +/* usb OTG mode */ +#define USBC_OTG_HOST 0 +#define USBC_OTG_DEVICE 1 + +/* usb device type */ +#define USBC_DEVICE_HSDEV 0 +#define USBC_DEVICE_FSDEV 1 +#define USBC_DEVICE_LSDEV 2 + +/* usb transfer type */ +#define USBC_TS_TYPE_IDLE 0 +#define USBC_TS_TYPE_CTRL 1 +#define USBC_TS_TYPE_ISO 2 +#define USBC_TS_TYPE_INT 3 +#define USBC_TS_TYPE_BULK 4 + +/* usb transfer mode */ +#define USBC_TS_MODE_UNKOWN 0 +#define USBC_TS_MODE_LS 1 +#define USBC_TS_MODE_FS 2 +#define USBC_TS_MODE_HS 3 + +/* usb Vbus status */ +#define USBC_VBUS_STATUS_BELOW_SESSIONEND 0 +#define USBC_VBUS_STATUS_ABOVE_SESSIONEND_BELOW_AVALID 1 +#define USBC_VBUS_STATUS_ABOVE_AVALID_BELOW_VBUSVALID 2 +#define USBC_VBUS_STATUS_ABOVE_VBUSVALID 3 + +/* usb io type */ +#define USBC_IO_TYPE_PIO 0 +#define USBC_IO_TYPE_DMA 1 + +/* usb ep type */ +#define USBC_EP_TYPE_IDLE 0 +#define USBC_EP_TYPE_EP0 1 +#define USBC_EP_TYPE_TX 2 +#define USBC_EP_TYPE_RX 3 + +/* usb id type */ +#define USBC_ID_TYPE_DISABLE 0 +#define USBC_ID_TYPE_HOST 1 +#define USBC_ID_TYPE_DEVICE 2 + +/* usb vbus valid type */ +#define USBC_VBUS_TYPE_DISABLE 0 +#define USBC_VBUS_TYPE_LOW 1 +#define USBC_VBUS_TYPE_HIGH 2 + +/* usb a valid source */ +#define USBC_A_VALID_SOURCE_UTMI_AVALID 0 +#define USBC_A_VALID_SOURCE_UTMI_VBUS 1 + +/* usb device switch */ +#define USBC_DEVICE_SWITCH_OFF 0 +#define USBC_DEVICE_SWITCH_ON 1 + +/* usb fifo config mode */ +#define USBC_FIFO_MODE_4K 0 +#define USBC_FIFO_MODE_8K 1 + +/* + ************************************************** + * usb interrupt mask + * + ************************************************** + */ + +/* interrupt flags for ep0 and the Tx ep1~4 */ +#define USBC_INTTx_FLAG_EP5 (1 << USBC_BP_INTTx_FLAG_EP5) +#define USBC_INTTx_FLAG_EP4 (1 << USBC_BP_INTTx_FLAG_EP4) +#define USBC_INTTx_FLAG_EP3 (1 << USBC_BP_INTTx_FLAG_EP3) +#define USBC_INTTx_FLAG_EP2 (1 << USBC_BP_INTTx_FLAG_EP2) +#define USBC_INTTx_FLAG_EP1 (1 << USBC_BP_INTTx_FLAG_EP1) +#define USBC_INTTx_FLAG_EP0 (1 << USBC_BP_INTTx_FLAG_EP0) + +/* interrupt flags for Rx ep1~4 */ +#define USBC_INTRx_FLAG_EP5 (1 << USBC_BP_INTRx_FLAG_EP5) +#define USBC_INTRx_FLAG_EP4 (1 << USBC_BP_INTRx_FLAG_EP4) +#define USBC_INTRx_FLAG_EP3 (1 << USBC_BP_INTRx_FLAG_EP3) +#define USBC_INTRx_FLAG_EP2 (1 << USBC_BP_INTRx_FLAG_EP2) +#define USBC_INTRx_FLAG_EP1 (1 << USBC_BP_INTRx_FLAG_EP1) + +/* USB interrupt */ +#define USBC_INTUSB_VBUS_ERROR (1 << USBC_BP_INTUSB_VBUS_ERROR) +#define USBC_INTUSB_SESSION_REQ (1 << USBC_BP_INTUSB_SESSION_REQ) +#define USBC_INTUSB_DISCONNECT (1 << USBC_BP_INTUSB_DISCONNECT) +#define USBC_INTUSB_CONNECT (1 << USBC_BP_INTUSB_CONNECT) +#define USBC_INTUSB_SOF (1 << USBC_BP_INTUSB_SOF) +#define USBC_INTUSB_RESET (1 << USBC_BP_INTUSB_RESET) +#define USBC_INTUSB_RESUME (1 << USBC_BP_INTUSB_RESUME) +#define USBC_INTUSB_SUSPEND (1 << USBC_BP_INTUSB_SUSPEND) + +#define USB_CSRL0_NAKTO 0x00000080 // NAK Timeout +#define USB_CSRL0_SETENDC 0x00000080 // Setup End Clear +#define USB_CSRL0_STATUS 0x00000040 // STATUS Packet +#define USB_CSRL0_RXRDYC 0x00000040 // RXRDY Clear +#define USB_CSRL0_REQPKT 0x00000020 // Request Packet +#define USB_CSRL0_STALL 0x00000020 // Send Stall +#define USB_CSRL0_SETEND 0x00000010 // Setup End +#define USB_CSRL0_ERROR 0x00000010 // Error +#define USB_CSRL0_DATAEND 0x00000008 // Data End +#define USB_CSRL0_SETUP 0x00000008 // Setup Packet +#define USB_CSRL0_STALLED 0x00000004 // Endpoint Stalled +#define USB_CSRL0_TXRDY 0x00000002 // Transmit Packet Ready +#define USB_CSRL0_RXRDY 0x00000001 // Receive Packet Ready + +#define USB_RXFIFOSZ_DPB 0x00000010 // Double Packet Buffer Support +#define USB_RXFIFOSZ_SIZE_M 0x0000000F // Max Packet Size + +#define USB_TXFIFOSZ_DPB 0x00000010 // Double Packet Buffer Support +#define USB_TXFIFOSZ_SIZE_M 0x0000000F // Max Packet Size + +#endif diff --git a/src/tusb_option.h b/src/tusb_option.h index dcf1c4614..dbdc83c6b 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -136,6 +136,9 @@ // Infineon #define OPT_MCU_XMC4000 1800 ///< Infineon XMC4000 +// Allwinner +#define OPT_MCU_F1C100S 1900 ///< Allwinner F1C100s family + // Helper to check if configured MCU is one of listed // Apply _TU_CHECK_MCU with || as separator to list of input #define _TU_CHECK_MCU(_m) (CFG_TUSB_MCU == _m) From c9d9bfab924244da285895d1d594900e8de303fe Mon Sep 17 00:00:00 2001 From: Sebastien COUDREAU Date: Wed, 1 Dec 2021 17:10:31 +0100 Subject: [PATCH 032/504] Remove unused-parameter errors when LOGGER=SWO --- hw/bsp/board.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/bsp/board.c b/hw/bsp/board.c index 6a26f55b7..98addca99 100644 --- a/hw/bsp/board.c +++ b/hw/bsp/board.c @@ -126,6 +126,8 @@ TU_ATTR_USED int sys_write (int fhdl, const void *buf, size_t count) TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count) { (void) fhdl; + (void) buf; + (void) count; return 0; } From 61a9e125db82ed73b56e7111c3b63c85edbf8d0b Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 1 Dec 2021 23:19:17 +0700 Subject: [PATCH 033/504] more ci abstract --- hw/bsp/imxrt/family.mk | 4 +- src/portable/chipidea/ci_hs/ci_hs_imxrt.h | 61 ++++++++++++++ src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h | 57 +++++++++++++ src/portable/chipidea/ci_hs/ci_hs_type.h | 80 ++++++++++-------- src/portable/chipidea/ci_hs/dcd_ci_hs.c | 86 ++++++-------------- 5 files changed, 189 insertions(+), 99 deletions(-) create mode 100644 src/portable/chipidea/ci_hs/ci_hs_imxrt.h create mode 100644 src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h diff --git a/hw/bsp/imxrt/family.mk b/hw/bsp/imxrt/family.mk index a919d3698..d086d503f 100644 --- a/hw/bsp/imxrt/family.mk +++ b/hw/bsp/imxrt/family.mk @@ -28,7 +28,9 @@ LDFLAGS += \ -Wl,--defsym,__stack_size__=0x800 \ SRC_C += \ - src/portable/nxp/transdimension/dcd_transdimension.c \ + src/portable/chipidea/ci_hs/dcd_ci_hs.c \ + src/portable/chipidea/ci_hs/hcd_ci_hs.c \ + src/portable/ehci/ehci.c \ $(MCU_DIR)/system_$(MCU_VARIANT).c \ $(MCU_DIR)/xip/fsl_flexspi_nor_boot.c \ $(MCU_DIR)/project_template/clock_config.c \ diff --git a/src/portable/chipidea/ci_hs/ci_hs_imxrt.h b/src/portable/chipidea/ci_hs/ci_hs_imxrt.h new file mode 100644 index 000000000..3c92dccb6 --- /dev/null +++ b/src/portable/chipidea/ci_hs/ci_hs_imxrt.h @@ -0,0 +1,61 @@ +/* + * 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. + */ + +#ifndef _CI_HS_IMXRT_H_ +#define _CI_HS_IMXRT_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "fsl_device_registers.h" + +static const dcd_controller_t _dcd_controller[] = +{ + // RT1010 and RT1020 only has 1 USB controller + #if FSL_FEATURE_SOC_USBHS_COUNT == 1 + { .regs = (ci_hs_regs_t*) USB_BASE , .irqnum = USB_OTG1_IRQn, .ep_count = 8 } + #else + { .regs = (ci_hs_regs_t*) USB1_BASE, .irqnum = USB_OTG1_IRQn, .ep_count = 8 }, + { .regs = (ci_hs_regs_t*) USB2_BASE, .irqnum = USB_OTG2_IRQn, .ep_count = 8 } + #endif +}; + +void dcd_int_enable(uint8_t rhport) +{ + NVIC_EnableIRQ(_dcd_controller[rhport].irqnum); +} + +void dcd_int_disable(uint8_t rhport) +{ + NVIC_DisableIRQ(_dcd_controller[rhport].irqnum); +} + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h b/src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h new file mode 100644 index 000000000..c4f94820d --- /dev/null +++ b/src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h @@ -0,0 +1,57 @@ +/* + * 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. + */ + +#ifndef _CI_HS_LPC18_43_H_ +#define _CI_HS_LPC18_43_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// LPCOpen for 18xx & 43xx +#include "chip.h" + +static const dcd_controller_t _dcd_controller[] = +{ + { .regs = (ci_hs_regs_t*) LPC_USB0_BASE, .irqnum = USB0_IRQn, .ep_count = 6 }, + { .regs = (ci_hs_regs_t*) LPC_USB1_BASE, .irqnum = USB1_IRQn, .ep_count = 4 } +}; + +void dcd_int_enable(uint8_t rhport) +{ + NVIC_EnableIRQ(_dcd_controller[rhport].irqnum); +} + +void dcd_int_disable(uint8_t rhport) +{ + NVIC_DisableIRQ(_dcd_controller[rhport].irqnum); +} + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/src/portable/chipidea/ci_hs/ci_hs_type.h b/src/portable/chipidea/ci_hs/ci_hs_type.h index 402c26334..772a7e413 100644 --- a/src/portable/chipidea/ci_hs/ci_hs_type.h +++ b/src/portable/chipidea/ci_hs/ci_hs_type.h @@ -85,49 +85,57 @@ enum { typedef struct { //------------- ID + HW Parameter Registers-------------// - __I uint32_t TU_RESERVED[64]; ///< For iMX RT10xx, but not used by LPC18XX/LPC43XX + volatile uint32_t TU_RESERVED[64]; ///< For iMX RT10xx, but not used by LPC18XX/LPC43XX //------------- Capability Registers-------------// - __I uint8_t CAPLENGTH; ///< Capability Registers Length - __I uint8_t TU_RESERVED[1]; - __I uint16_t HCIVERSION; ///< Host Controller Interface Version + volatile uint8_t CAPLENGTH; ///< Capability Registers Length + volatile uint8_t TU_RESERVED[1]; + volatile uint16_t HCIVERSION; ///< Host Controller Interface Version - __I uint32_t HCSPARAMS; ///< Host Controller Structural Parameters - __I uint32_t HCCPARAMS; ///< Host Controller Capability Parameters - __I uint32_t TU_RESERVED[5]; + volatile uint32_t HCSPARAMS; ///< Host Controller Structural Parameters + volatile uint32_t HCCPARAMS; ///< Host Controller Capability Parameters + volatile uint32_t TU_RESERVED[5]; - __I uint16_t DCIVERSION; ///< Device Controller Interface Version - __I uint8_t TU_RESERVED[2]; + volatile uint16_t DCIVERSION; ///< Device Controller Interface Version + volatile uint8_t TU_RESERVED[2]; - __I uint32_t DCCPARAMS; ///< Device Controller Capability Parameters - __I uint32_t TU_RESERVED[6]; + volatile uint32_t DCCPARAMS; ///< Device Controller Capability Parameters + volatile uint32_t TU_RESERVED[6]; //------------- Operational Registers -------------// - __IO uint32_t USBCMD; ///< USB Command Register - __IO uint32_t USBSTS; ///< USB Status Register - __IO uint32_t USBINTR; ///< Interrupt Enable Register - __IO uint32_t FRINDEX; ///< USB Frame Index - __I uint32_t TU_RESERVED; - __IO uint32_t DEVICEADDR; ///< Device Address - __IO uint32_t ENDPTLISTADDR; ///< Endpoint List Address - __I uint32_t TU_RESERVED; - __IO uint32_t BURSTSIZE; ///< Programmable Burst Size - __IO uint32_t TXFILLTUNING; ///< TX FIFO Fill Tuning - uint32_t TU_RESERVED[4]; - __IO uint32_t ENDPTNAK; ///< Endpoint NAK - __IO uint32_t ENDPTNAKEN; ///< Endpoint NAK Enable - __I uint32_t TU_RESERVED; - __IO uint32_t PORTSC1; ///< Port Status & Control - __I uint32_t TU_RESERVED[7]; - __IO uint32_t OTGSC; ///< On-The-Go Status & control - __IO uint32_t USBMODE; ///< USB Device Mode - __IO uint32_t ENDPTSETUPSTAT; ///< Endpoint Setup Status - __IO uint32_t ENDPTPRIME; ///< Endpoint Prime - __IO uint32_t ENDPTFLUSH; ///< Endpoint Flush - __I uint32_t ENDPTSTAT; ///< Endpoint Status - __IO uint32_t ENDPTCOMPLETE; ///< Endpoint Complete - __IO uint32_t ENDPTCTRL[8]; ///< Endpoint Control 0 - 7 -} dcd_registers_t, hcd_registers_t; + volatile uint32_t USBCMD; ///< USB Command Register + volatile uint32_t USBSTS; ///< USB Status Register + volatile uint32_t USBINTR; ///< Interrupt Enable Register + volatile uint32_t FRINDEX; ///< USB Frame Index + volatile uint32_t TU_RESERVED; + volatile uint32_t DEVICEADDR; ///< Device Address + volatile uint32_t ENDPTLISTADDR; ///< Endpoint List Address + volatile uint32_t TU_RESERVED; + volatile uint32_t BURSTSIZE; ///< Programmable Burst Size + volatile uint32_t TXFILLTUNING; ///< TX FIFO Fill Tuning + uint32_t TU_RESERVED[4]; + volatile uint32_t ENDPTNAK; ///< Endpoint NAK + volatile uint32_t ENDPTNAKEN; ///< Endpoint NAK Enable + volatile uint32_t TU_RESERVED; + volatile uint32_t PORTSC1; ///< Port Status & Control + volatile uint32_t TU_RESERVED[7]; + volatile uint32_t OTGSC; ///< On-The-Go Status & control + volatile uint32_t USBMODE; ///< USB Device Mode + volatile uint32_t ENDPTSETUPSTAT; ///< Endpoint Setup Status + volatile uint32_t ENDPTPRIME; ///< Endpoint Prime + volatile uint32_t ENDPTFLUSH; ///< Endpoint Flush + volatile uint32_t ENDPTSTAT; ///< Endpoint Status + volatile uint32_t ENDPTCOMPLETE; ///< Endpoint Complete + volatile uint32_t ENDPTCTRL[8]; ///< Endpoint Control 0 - 7 +} ci_hs_regs_t, hcd_registers_t; + + +typedef struct +{ + ci_hs_regs_t* regs; + const uint32_t irqnum; + const uint8_t ep_count; // Max bi-directional Endpoints +}dcd_controller_t; #ifdef __cplusplus } diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c index e531cd842..1824aea86 100644 --- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c @@ -25,25 +25,24 @@ */ #include "tusb_option.h" +#include "device/dcd_attr.h" -#if TUSB_OPT_DEVICE_ENABLED && \ - (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX) +#if TUSB_OPT_DEVICE_ENABLED && defined(DCD_ATTR_CONTROLLER_CHIPIDEA_HS) //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ -#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX - #include "fsl_device_registers.h" - #define INCLUDE_FSL_DEVICE_REGISTERS -#else - // LPCOpen for 18xx & 43xx - #include "chip.h" -#endif - -#include "common/tusb_common.h" #include "device/dcd.h" #include "ci_hs_type.h" +#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX + #include "ci_hs_imxrt.h" +#elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX) + #include "ci_hs_lpc18_43.h" +#else + #error "Unsupported MCUs" +#endif + #if defined(__CORTEX_M) && __CORTEX_M == 7 && __DCACHE_PRESENT == 1 #define CleanInvalidateDCache_by_Addr SCB_CleanInvalidateDCache_by_Addr #else @@ -144,33 +143,6 @@ TU_VERIFY_STATIC( sizeof(dcd_qhd_t) == 64, "size is not correct"); // Variables //--------------------------------------------------------------------+ -typedef struct -{ - dcd_registers_t* regs; // registers - const IRQn_Type irqnum; // IRQ number - const uint8_t ep_count; // Max bi-directional Endpoints -}dcd_controller_t; - -#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX - static const dcd_controller_t _dcd_controller[] = - { - // RT1010 and RT1020 only has 1 USB controller - #if FSL_FEATURE_SOC_USBHS_COUNT == 1 - { .regs = (dcd_registers_t*) USB_BASE , .irqnum = USB_OTG1_IRQn, .ep_count = 8 } - #else - { .regs = (dcd_registers_t*) USB1_BASE, .irqnum = USB_OTG1_IRQn, .ep_count = 8 }, - { .regs = (dcd_registers_t*) USB2_BASE, .irqnum = USB_OTG2_IRQn, .ep_count = 8 } - #endif - }; - -#else - static const dcd_controller_t _dcd_controller[] = - { - { .regs = (dcd_registers_t*) LPC_USB0_BASE, .irqnum = USB0_IRQn, .ep_count = 6 }, - { .regs = (dcd_registers_t*) LPC_USB1_BASE, .irqnum = USB1_IRQn, .ep_count = 4 } - }; -#endif - #define QTD_NEXT_INVALID 0x01 typedef struct { @@ -191,7 +163,7 @@ static dcd_data_t _dcd_data; /// follows LPC43xx User Manual 23.10.3 static void bus_reset(uint8_t rhport) { - dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + ci_hs_regs_t* dcd_reg = _dcd_controller[rhport].regs; // The reset value for all endpoint types is the control endpoint. If one endpoint // direction is enabled and the paired endpoint of opposite direction is disabled, then the @@ -231,7 +203,7 @@ void dcd_init(uint8_t rhport) { tu_memclr(&_dcd_data, sizeof(dcd_data_t)); - dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + ci_hs_regs_t* dcd_reg = _dcd_controller[rhport].regs; // Reset controller dcd_reg->USBCMD |= USBCMD_RESET; @@ -255,40 +227,30 @@ void dcd_init(uint8_t rhport) dcd_reg->USBCMD |= USBCMD_RUN_STOP; // Connect } -void dcd_int_enable(uint8_t rhport) -{ - NVIC_EnableIRQ(_dcd_controller[rhport].irqnum); -} - -void dcd_int_disable(uint8_t rhport) -{ - NVIC_DisableIRQ(_dcd_controller[rhport].irqnum); -} - void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { // Response with status first before changing device address dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); - dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + ci_hs_regs_t* dcd_reg = _dcd_controller[rhport].regs; dcd_reg->DEVICEADDR = (dev_addr << 25) | TU_BIT(24); } void dcd_remote_wakeup(uint8_t rhport) { - dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + ci_hs_regs_t* dcd_reg = _dcd_controller[rhport].regs; dcd_reg->PORTSC1 |= PORTSC1_FORCE_PORT_RESUME; } void dcd_connect(uint8_t rhport) { - dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + ci_hs_regs_t* dcd_reg = _dcd_controller[rhport].regs; dcd_reg->USBCMD |= USBCMD_RUN_STOP; } void dcd_disconnect(uint8_t rhport) { - dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + ci_hs_regs_t* dcd_reg = _dcd_controller[rhport].regs; dcd_reg->USBCMD &= ~USBCMD_RUN_STOP; } @@ -334,7 +296,7 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); - dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + ci_hs_regs_t* dcd_reg = _dcd_controller[rhport].regs; dcd_reg->ENDPTCTRL[epnum] |= ENDPTCTRL_STALL << (dir ? 16 : 0); // flush to abort any primed buffer @@ -347,7 +309,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) uint8_t const dir = tu_edpt_dir(ep_addr); // data toggle also need to be reset - dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + ci_hs_regs_t* dcd_reg = _dcd_controller[rhport].regs; dcd_reg->ENDPTCTRL[epnum] |= ENDPTCTRL_TOGGLE_RESET << ( dir ? 16 : 0 ); dcd_reg->ENDPTCTRL[epnum] &= ~(ENDPTCTRL_STALL << ( dir ? 16 : 0)); } @@ -376,7 +338,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) CleanInvalidateDCache_by_Addr((uint32_t*) &_dcd_data, sizeof(dcd_data_t)); // Enable EP Control - dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + ci_hs_regs_t* dcd_reg = _dcd_controller[rhport].regs; uint32_t const epctrl = (p_endpoint_desc->bmAttributes.xfer << ENDPTCTRL_TYPE_POS) | ENDPTCTRL_ENABLE | ENDPTCTRL_TOGGLE_RESET; @@ -393,7 +355,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) void dcd_edpt_close_all (uint8_t rhport) { - dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + ci_hs_regs_t* dcd_reg = _dcd_controller[rhport].regs; // Disable all non-control endpoints for( uint8_t epnum=1; epnum < _dcd_controller[rhport].ep_count; epnum++) @@ -411,7 +373,7 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); - dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + ci_hs_regs_t* dcd_reg = _dcd_controller[rhport].regs; _dcd_data.qhd[epnum][dir].qtd_overlay.halted = 1; @@ -426,7 +388,7 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) static void qhd_start_xfer(uint8_t rhport, uint8_t epnum, uint8_t dir) { - dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + ci_hs_regs_t* dcd_reg = _dcd_controller[rhport].regs; dcd_qhd_t* p_qhd = &_dcd_data.qhd[epnum][dir]; dcd_qtd_t* p_qtd = &_dcd_data.qtd[epnum][dir]; @@ -542,7 +504,7 @@ static void process_edpt_complete_isr(uint8_t rhport, uint8_t epnum, uint8_t dir if ( result != XFER_RESULT_SUCCESS ) { - dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + ci_hs_regs_t* dcd_reg = _dcd_controller[rhport].regs; // flush to abort error buffer dcd_reg->ENDPTFLUSH = TU_BIT(epnum + (dir ? 16 : 0)); } @@ -566,7 +528,7 @@ static void process_edpt_complete_isr(uint8_t rhport, uint8_t epnum, uint8_t dir void dcd_int_handler(uint8_t rhport) { - dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + ci_hs_regs_t* dcd_reg = _dcd_controller[rhport].regs; uint32_t const int_enable = dcd_reg->USBINTR; uint32_t const int_status = dcd_reg->USBSTS & int_enable; From 83dc3e25f002a49f05919c3d8ebac37756641786 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 1 Dec 2021 23:30:09 +0700 Subject: [PATCH 034/504] more work to abstract chipidea driver --- hw/bsp/ea4357/board.mk | 4 ++- hw/bsp/ngx4330/board.mk | 4 ++- src/portable/chipidea/ci_hs/ci_hs_imxrt.h | 12 +++---- src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h | 10 +++--- src/portable/chipidea/ci_hs/ci_hs_type.h | 8 ++--- src/portable/chipidea/ci_hs/dcd_ci_hs.c | 37 +++++++++++--------- 6 files changed, 41 insertions(+), 34 deletions(-) diff --git a/hw/bsp/ea4357/board.mk b/hw/bsp/ea4357/board.mk index 4390d1eda..6f243c6a2 100644 --- a/hw/bsp/ea4357/board.mk +++ b/hw/bsp/ea4357/board.mk @@ -21,7 +21,9 @@ MCU_DIR = hw/mcu/nxp/lpcopen/lpc43xx/lpc_chip_43xx LD_FILE = hw/bsp/$(BOARD)/lpc4357.ld SRC_C += \ - src/portable/nxp/transdimension/dcd_transdimension.c \ + src/portable/chipidea/ci_hs/dcd_ci_hs.c \ + src/portable/chipidea/ci_hs/hcd_ci_hs.c \ + src/portable/ehci/ehci.c \ $(MCU_DIR)/../gcc/cr_startup_lpc43xx.c \ $(MCU_DIR)/src/chip_18xx_43xx.c \ $(MCU_DIR)/src/clock_18xx_43xx.c \ diff --git a/hw/bsp/ngx4330/board.mk b/hw/bsp/ngx4330/board.mk index 3b193c0a5..3e901567c 100644 --- a/hw/bsp/ngx4330/board.mk +++ b/hw/bsp/ngx4330/board.mk @@ -21,7 +21,9 @@ MCU_DIR = hw/mcu/nxp/lpcopen/lpc43xx/lpc_chip_43xx LD_FILE = hw/bsp/$(BOARD)/ngx4330.ld SRC_C += \ - src/portable/nxp/transdimension/dcd_transdimension.c \ + src/portable/chipidea/ci_hs/dcd_ci_hs.c \ + src/portable/chipidea/ci_hs/hcd_ci_hs.c \ + src/portable/ehci/ehci.c \ $(MCU_DIR)/../gcc/cr_startup_lpc43xx.c \ $(MCU_DIR)/src/chip_18xx_43xx.c \ $(MCU_DIR)/src/clock_18xx_43xx.c \ diff --git a/src/portable/chipidea/ci_hs/ci_hs_imxrt.h b/src/portable/chipidea/ci_hs/ci_hs_imxrt.h index 3c92dccb6..52671509b 100644 --- a/src/portable/chipidea/ci_hs/ci_hs_imxrt.h +++ b/src/portable/chipidea/ci_hs/ci_hs_imxrt.h @@ -33,25 +33,25 @@ #include "fsl_device_registers.h" -static const dcd_controller_t _dcd_controller[] = +static const ci_hs_controller_t _ci_controller[] = { // RT1010 and RT1020 only has 1 USB controller #if FSL_FEATURE_SOC_USBHS_COUNT == 1 - { .regs = (ci_hs_regs_t*) USB_BASE , .irqnum = USB_OTG1_IRQn, .ep_count = 8 } + { .reg_base = USB_BASE , .irqnum = USB_OTG1_IRQn, .ep_count = 8 } #else - { .regs = (ci_hs_regs_t*) USB1_BASE, .irqnum = USB_OTG1_IRQn, .ep_count = 8 }, - { .regs = (ci_hs_regs_t*) USB2_BASE, .irqnum = USB_OTG2_IRQn, .ep_count = 8 } + { .reg_base = USB1_BASE, .irqnum = USB_OTG1_IRQn, .ep_count = 8 }, + { .reg_base = USB2_BASE, .irqnum = USB_OTG2_IRQn, .ep_count = 8 } #endif }; void dcd_int_enable(uint8_t rhport) { - NVIC_EnableIRQ(_dcd_controller[rhport].irqnum); + NVIC_EnableIRQ(_ci_controller[rhport].irqnum); } void dcd_int_disable(uint8_t rhport) { - NVIC_DisableIRQ(_dcd_controller[rhport].irqnum); + NVIC_DisableIRQ(_ci_controller[rhport].irqnum); } #ifdef __cplusplus 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 c4f94820d..1d6accded 100644 --- a/src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h +++ b/src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h @@ -34,20 +34,20 @@ // LPCOpen for 18xx & 43xx #include "chip.h" -static const dcd_controller_t _dcd_controller[] = +static const ci_hs_controller_t _ci_controller[] = { - { .regs = (ci_hs_regs_t*) LPC_USB0_BASE, .irqnum = USB0_IRQn, .ep_count = 6 }, - { .regs = (ci_hs_regs_t*) LPC_USB1_BASE, .irqnum = USB1_IRQn, .ep_count = 4 } + { .reg_base = LPC_USB0_BASE, .irqnum = USB0_IRQn, .ep_count = 6 }, + { .reg_base = LPC_USB1_BASE, .irqnum = USB1_IRQn, .ep_count = 4 } }; void dcd_int_enable(uint8_t rhport) { - NVIC_EnableIRQ(_dcd_controller[rhport].irqnum); + NVIC_EnableIRQ(_ci_controller[rhport].irqnum); } void dcd_int_disable(uint8_t rhport) { - NVIC_DisableIRQ(_dcd_controller[rhport].irqnum); + NVIC_DisableIRQ(_ci_controller[rhport].irqnum); } #ifdef __cplusplus diff --git a/src/portable/chipidea/ci_hs/ci_hs_type.h b/src/portable/chipidea/ci_hs/ci_hs_type.h index 772a7e413..810ec15ce 100644 --- a/src/portable/chipidea/ci_hs/ci_hs_type.h +++ b/src/portable/chipidea/ci_hs/ci_hs_type.h @@ -132,10 +132,10 @@ typedef struct typedef struct { - ci_hs_regs_t* regs; - const uint32_t irqnum; - const uint8_t ep_count; // Max bi-directional Endpoints -}dcd_controller_t; + uint32_t reg_base; + uint32_t irqnum; + uint8_t ep_count; // Max bi-directional Endpoints +}ci_hs_controller_t; #ifdef __cplusplus } diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c index 1824aea86..6f28862b7 100644 --- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c @@ -43,6 +43,9 @@ #error "Unsupported MCUs" #endif + +#define CI_HS_REG(_port) ((ci_hs_regs_t*) _ci_controller[_port].reg_base) + #if defined(__CORTEX_M) && __CORTEX_M == 7 && __DCACHE_PRESENT == 1 #define CleanInvalidateDCache_by_Addr SCB_CleanInvalidateDCache_by_Addr #else @@ -163,14 +166,14 @@ static dcd_data_t _dcd_data; /// follows LPC43xx User Manual 23.10.3 static void bus_reset(uint8_t rhport) { - ci_hs_regs_t* dcd_reg = _dcd_controller[rhport].regs; + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); // The reset value for all endpoint types is the control endpoint. If one endpoint // direction is enabled and the paired endpoint of opposite direction is disabled, then the // endpoint type of the unused direction must be changed from the control type to any other // type (e.g. bulk). Leaving an un-configured endpoint control will cause undefined behavior // for the data PID tracking on the active endpoint. - for( uint8_t i=1; i < _dcd_controller[rhport].ep_count; i++) + for( uint8_t i=1; i < _ci_controller[rhport].ep_count; i++) { dcd_reg->ENDPTCTRL[i] = (TUSB_XFER_BULK << ENDPTCTRL_TYPE_POS) | (TUSB_XFER_BULK << (16+ENDPTCTRL_TYPE_POS)); } @@ -203,7 +206,7 @@ void dcd_init(uint8_t rhport) { tu_memclr(&_dcd_data, sizeof(dcd_data_t)); - ci_hs_regs_t* dcd_reg = _dcd_controller[rhport].regs; + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); // Reset controller dcd_reg->USBCMD |= USBCMD_RESET; @@ -232,25 +235,25 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) // Response with status first before changing device address dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); - ci_hs_regs_t* dcd_reg = _dcd_controller[rhport].regs; + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); dcd_reg->DEVICEADDR = (dev_addr << 25) | TU_BIT(24); } void dcd_remote_wakeup(uint8_t rhport) { - ci_hs_regs_t* dcd_reg = _dcd_controller[rhport].regs; + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); dcd_reg->PORTSC1 |= PORTSC1_FORCE_PORT_RESUME; } void dcd_connect(uint8_t rhport) { - ci_hs_regs_t* dcd_reg = _dcd_controller[rhport].regs; + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); dcd_reg->USBCMD |= USBCMD_RUN_STOP; } void dcd_disconnect(uint8_t rhport) { - ci_hs_regs_t* dcd_reg = _dcd_controller[rhport].regs; + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); dcd_reg->USBCMD &= ~USBCMD_RUN_STOP; } @@ -296,7 +299,7 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); - ci_hs_regs_t* dcd_reg = _dcd_controller[rhport].regs; + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); dcd_reg->ENDPTCTRL[epnum] |= ENDPTCTRL_STALL << (dir ? 16 : 0); // flush to abort any primed buffer @@ -309,7 +312,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) uint8_t const dir = tu_edpt_dir(ep_addr); // data toggle also need to be reset - ci_hs_regs_t* dcd_reg = _dcd_controller[rhport].regs; + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); dcd_reg->ENDPTCTRL[epnum] |= ENDPTCTRL_TOGGLE_RESET << ( dir ? 16 : 0 ); dcd_reg->ENDPTCTRL[epnum] &= ~(ENDPTCTRL_STALL << ( dir ? 16 : 0)); } @@ -320,7 +323,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); // Must not exceed max endpoint number - TU_ASSERT( epnum < _dcd_controller[rhport].ep_count ); + TU_ASSERT( epnum < _ci_controller[rhport].ep_count ); //------------- Prepare Queue Head -------------// dcd_qhd_t * p_qhd = &_dcd_data.qhd[epnum][dir]; @@ -338,7 +341,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) CleanInvalidateDCache_by_Addr((uint32_t*) &_dcd_data, sizeof(dcd_data_t)); // Enable EP Control - ci_hs_regs_t* dcd_reg = _dcd_controller[rhport].regs; + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); uint32_t const epctrl = (p_endpoint_desc->bmAttributes.xfer << ENDPTCTRL_TYPE_POS) | ENDPTCTRL_ENABLE | ENDPTCTRL_TOGGLE_RESET; @@ -355,10 +358,10 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) void dcd_edpt_close_all (uint8_t rhport) { - ci_hs_regs_t* dcd_reg = _dcd_controller[rhport].regs; + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); // Disable all non-control endpoints - for( uint8_t epnum=1; epnum < _dcd_controller[rhport].ep_count; epnum++) + for( uint8_t epnum=1; epnum < _ci_controller[rhport].ep_count; epnum++) { _dcd_data.qhd[epnum][TUSB_DIR_OUT].qtd_overlay.halted = 1; _dcd_data.qhd[epnum][TUSB_DIR_IN ].qtd_overlay.halted = 1; @@ -373,7 +376,7 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); - ci_hs_regs_t* dcd_reg = _dcd_controller[rhport].regs; + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); _dcd_data.qhd[epnum][dir].qtd_overlay.halted = 1; @@ -388,7 +391,7 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) static void qhd_start_xfer(uint8_t rhport, uint8_t epnum, uint8_t dir) { - ci_hs_regs_t* dcd_reg = _dcd_controller[rhport].regs; + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); dcd_qhd_t* p_qhd = &_dcd_data.qhd[epnum][dir]; dcd_qtd_t* p_qtd = &_dcd_data.qtd[epnum][dir]; @@ -504,7 +507,7 @@ static void process_edpt_complete_isr(uint8_t rhport, uint8_t epnum, uint8_t dir if ( result != XFER_RESULT_SUCCESS ) { - ci_hs_regs_t* dcd_reg = _dcd_controller[rhport].regs; + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); // flush to abort error buffer dcd_reg->ENDPTFLUSH = TU_BIT(epnum + (dir ? 16 : 0)); } @@ -528,7 +531,7 @@ static void process_edpt_complete_isr(uint8_t rhport, uint8_t epnum, uint8_t dir void dcd_int_handler(uint8_t rhport) { - ci_hs_regs_t* dcd_reg = _dcd_controller[rhport].regs; + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); uint32_t const int_enable = dcd_reg->USBINTR; uint32_t const int_status = dcd_reg->USBSTS & int_enable; From 207c60d055dd810525db11666b029f322cbaf9e8 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 2 Dec 2021 00:03:44 +0700 Subject: [PATCH 035/504] more chipidea --- src/portable/chipidea/ci_hs/ci_hs_imxrt.h | 19 ++------ src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h | 20 ++------ src/portable/chipidea/ci_hs/ci_hs_type.h | 2 +- src/portable/chipidea/ci_hs/dcd_ci_hs.c | 16 +++++-- src/portable/chipidea/ci_hs/hcd_ci_hs.c | 50 +++++--------------- 5 files changed, 35 insertions(+), 72 deletions(-) diff --git a/src/portable/chipidea/ci_hs/ci_hs_imxrt.h b/src/portable/chipidea/ci_hs/ci_hs_imxrt.h index 52671509b..78ca5a5a2 100644 --- a/src/portable/chipidea/ci_hs/ci_hs_imxrt.h +++ b/src/portable/chipidea/ci_hs/ci_hs_imxrt.h @@ -27,10 +27,6 @@ #ifndef _CI_HS_IMXRT_H_ #define _CI_HS_IMXRT_H_ -#ifdef __cplusplus - extern "C" { -#endif - #include "fsl_device_registers.h" static const ci_hs_controller_t _ci_controller[] = @@ -44,18 +40,11 @@ static const ci_hs_controller_t _ci_controller[] = #endif }; -void dcd_int_enable(uint8_t rhport) -{ - NVIC_EnableIRQ(_ci_controller[rhport].irqnum); -} +#define CI_DCD_INT_ENABLE(_p) NVIC_EnableIRQ (_ci_controller[_p].irqnum) +#define CI_DCD_INT_DISABLE(_p) NVIC_DisableIRQ(_ci_controller[_p].irqnum) -void dcd_int_disable(uint8_t rhport) -{ - NVIC_DisableIRQ(_ci_controller[rhport].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) -#ifdef __cplusplus - } -#endif #endif 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 1d6accded..8c2e7dfa6 100644 --- a/src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h +++ b/src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h @@ -27,10 +27,6 @@ #ifndef _CI_HS_LPC18_43_H_ #define _CI_HS_LPC18_43_H_ -#ifdef __cplusplus - extern "C" { -#endif - // LPCOpen for 18xx & 43xx #include "chip.h" @@ -40,18 +36,10 @@ static const ci_hs_controller_t _ci_controller[] = { .reg_base = LPC_USB1_BASE, .irqnum = USB1_IRQn, .ep_count = 4 } }; -void dcd_int_enable(uint8_t rhport) -{ - NVIC_EnableIRQ(_ci_controller[rhport].irqnum); -} +#define CI_DCD_INT_ENABLE(_p) NVIC_EnableIRQ (_ci_controller[_p].irqnum) +#define CI_DCD_INT_DISABLE(_p) NVIC_DisableIRQ(_ci_controller[_p].irqnum) -void dcd_int_disable(uint8_t rhport) -{ - NVIC_DisableIRQ(_ci_controller[rhport].irqnum); -} - -#ifdef __cplusplus - } -#endif +#define CI_HCD_INT_ENABLE(_p) NVIC_EnableIRQ (_ci_controller[_p].irqnum) +#define CI_HCD_INT_DISABLE(_p) NVIC_DisableIRQ(_ci_controller[_p].irqnum) #endif diff --git a/src/portable/chipidea/ci_hs/ci_hs_type.h b/src/portable/chipidea/ci_hs/ci_hs_type.h index 810ec15ce..728a86b86 100644 --- a/src/portable/chipidea/ci_hs/ci_hs_type.h +++ b/src/portable/chipidea/ci_hs/ci_hs_type.h @@ -127,7 +127,7 @@ typedef struct volatile uint32_t ENDPTSTAT; ///< Endpoint Status volatile uint32_t ENDPTCOMPLETE; ///< Endpoint Complete volatile uint32_t ENDPTCTRL[8]; ///< Endpoint Control 0 - 7 -} ci_hs_regs_t, hcd_registers_t; +} ci_hs_regs_t; typedef struct diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c index 6f28862b7..c943396fc 100644 --- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c @@ -43,6 +43,9 @@ #error "Unsupported MCUs" #endif +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ #define CI_HS_REG(_port) ((ci_hs_regs_t*) _ci_controller[_port].reg_base) @@ -52,9 +55,6 @@ #define CleanInvalidateDCache_by_Addr(_addr, _dsize) #endif -//--------------------------------------------------------------------+ -// MACRO CONSTANT TYPEDEF -//--------------------------------------------------------------------+ // ENDPTCTRL enum { @@ -230,6 +230,16 @@ void dcd_init(uint8_t rhport) dcd_reg->USBCMD |= USBCMD_RUN_STOP; // Connect } +void dcd_int_enable(uint8_t rhport) +{ + CI_DCD_INT_ENABLE(rhport); +} + +void dcd_int_disable(uint8_t rhport) +{ + CI_DCD_INT_DISABLE(rhport); +} + void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { // Response with status first before changing device address diff --git a/src/portable/chipidea/ci_hs/hcd_ci_hs.c b/src/portable/chipidea/ci_hs/hcd_ci_hs.c index a62ebf2a3..3d028bf32 100644 --- a/src/portable/chipidea/ci_hs/hcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/hcd_ci_hs.c @@ -34,47 +34,23 @@ //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ -#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX - #include "fsl_device_registers.h" -#else - // LPCOpen for 18xx & 43xx - #include "chip.h" -#endif - #include "common/tusb_common.h" -#include "ci_hs_type.h" #include "portable/ehci/ehci_api.h" +#include "ci_hs_type.h" + +#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX + #include "ci_hs_imxrt.h" +#elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX) + #include "ci_hs_lpc18_43.h" +#else + #error "Unsupported MCUs" +#endif //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -// TODO can be merged with dcd_controller_t -typedef struct -{ - uint32_t regs_base; // registers base - const IRQn_Type irqnum; // IRQ number -}hcd_controller_t; - -#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX - static const hcd_controller_t _hcd_controller[] = - { - // RT1010 and RT1020 only has 1 USB controller - #if FSL_FEATURE_SOC_USBHS_COUNT == 1 - { .regs_base = USB_BASE , .irqnum = USB_OTG1_IRQn } - #else - { .regs_base = USB1_BASE, .irqnum = USB_OTG1_IRQn }, - { .regs_base = USB2_BASE, .irqnum = USB_OTG2_IRQn } - #endif - }; - -#else - static const hcd_controller_t _hcd_controller[] = - { - { .regs_base = LPC_USB0_BASE, .irqnum = USB0_IRQn }, - { .regs_base = LPC_USB1_BASE, .irqnum = USB1_IRQn } - }; -#endif +#define CI_HS_REG(_port) ((ci_hs_regs_t*) _ci_controller[_port].reg_base) //--------------------------------------------------------------------+ // Controller API @@ -82,7 +58,7 @@ typedef struct bool hcd_init(uint8_t rhport) { - hcd_registers_t* hcd_reg = (hcd_registers_t*) _hcd_controller[rhport].regs_base; + ci_hs_regs_t* hcd_reg = CI_HS_REG(rhport); // Reset controller hcd_reg->USBCMD |= USBCMD_RESET; @@ -106,12 +82,12 @@ bool hcd_init(uint8_t rhport) void hcd_int_enable(uint8_t rhport) { - NVIC_EnableIRQ(_hcd_controller[rhport].irqnum); + CI_HCD_INT_ENABLE(rhport); } void hcd_int_disable(uint8_t rhport) { - NVIC_DisableIRQ(_hcd_controller[rhport].irqnum); + CI_HCD_INT_DISABLE(rhport); } #endif From eae4132fbb216329e9a0d8b624baf1c5aad56359 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 2 Dec 2021 11:31:27 +0700 Subject: [PATCH 036/504] update supported doc --- docs/reference/supported.rst | 212 +++++++++++++++++------------------ 1 file changed, 101 insertions(+), 111 deletions(-) diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index dfaffe6e3..83cf874da 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -2,124 +2,114 @@ Supported Devices ***************** - Supported MCUs ============== -+--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| Manufacturer | Family | Device | Host | Highspeed | Driver | Note | -+==============+=======================+======================+======================+======================+=================+==============+ -| Broadcom | BCM2711, BCM2837 | |:heavy_check_mark:| | | |:heavy_check_mark:| | dwc2 | | -+--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| Dialog | DA1469x | |:heavy_check_mark:| | |:x:| | |:x:| | da146xx | | -+--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| Espressif | ESP32 S2, S3 | |:heavy_check_mark:| | | |:x:| | dwc2 or esp32sx | | -+--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| GigaDevice | GD32VF103 | |:heavy_check_mark:| | | |:x:| | dwc2 | | -+--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| Infineon | XMC4500 | |:heavy_check_mark:| | | |:x:| | dwc2 | | -+--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| MicroChip | SAM D11, D21 | |:heavy_check_mark:| | | |:x:| | samd | | -| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | SAM D51, E5x | |:heavy_check_mark:| | | |:x:| | samd | | -| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | SAM G55 | |:heavy_check_mark:| | | |:x:| | samg | | -| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | SAM L21, L22 | |:heavy_check_mark:| | | |:x:| | samd | | -| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | SAM E70,S70,V70,V71 | |:heavy_check_mark:| | | |:heavy_check_mark:| | samx7x | | -+--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| NordicSemi | nRF52833, nRF52840 | |:heavy_check_mark:| | |:x:| | |:x:| | nrf5x | | -| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | nRF5340 | |:heavy_check_mark:| | |:x:| | |:x:| | nrf5x | | -+--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| Nuvoton | NUC120 | |:heavy_check_mark:| | |:x:| | |:x:| | | | -| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | NUC121/NUC125 | |:heavy_check_mark:| | |:x:| | |:x:| | | | -| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | NUC126 | |:heavy_check_mark:| | |:x:| | |:x:| | | | -| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | NUC505 | |:heavy_check_mark:| | | |:heavy_check_mark:| | | | -+--------------+---------+-------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| NXP | iMXRT | RT1011 | |:heavy_check_mark:| | |:heavy_check_mark:| | |:heavy_check_mark:| | | | -| | +-------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | | RT1015 | |:heavy_check_mark:| | |:heavy_check_mark:| | |:heavy_check_mark:| | | | -| | +-------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | | RT1021 | |:heavy_check_mark:| | |:heavy_check_mark:| | |:heavy_check_mark:| | | | -| | +-------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | | RT1052 | |:heavy_check_mark:| | |:heavy_check_mark:| | |:heavy_check_mark:| | | | -| | +-------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | | RT1062 | |:heavy_check_mark:| | |:heavy_check_mark:| | |:heavy_check_mark:| | | | -| | +-------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | | RT1064 | |:heavy_check_mark:| | |:heavy_check_mark:| | |:heavy_check_mark:| | | | -| +---------+-------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | Kinetis | KL25 | |:heavy_check_mark:| | | |:x:| | | | -| | +-------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | | K32L2 | |:heavy_check_mark:| | | |:x:| | | | -| +---------+-------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | LPC | 11u, 13, 15 | |:heavy_check_mark:| | |:x:| | |:x:| | lpc_ip3511 | | -| | +-------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | | 17, 40 | |:heavy_check_mark:| | |:construction:| | |:x:| | lpc17_40 | | -| | +-------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | | 18, 43 | |:heavy_check_mark:| | |:heavy_check_mark:| | |:x:| | | | -| | +-------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | | 51u | |:heavy_check_mark:| | |:x:| | |:x:| | lpc_ip3511 | | -| | +-------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | | 54 | |:heavy_check_mark:| | | |:heavy_check_mark:| | lpc_ip3511 | | -| | +-------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | | 55 | |:heavy_check_mark:| | | |:heavy_check_mark:| | lpc_ip3511 | | -+--------------+---------+-------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| Raspberry Pi | RP2040 | |:heavy_check_mark:| | |:heavy_check_mark:| | |:x:| | rp2040 | | -+--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| Renesas | RX 63N, 65N, 72N | |:heavy_check_mark:| | |:x:| | |:x:| | usba | | -+--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| Silabs | EFM32GG12 | |:heavy_check_mark:| | | |:x:| | dwc2 | | -+--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| Sony | CXD56 | |:heavy_check_mark:| | |:x:| | |:heavy_check_mark:| | cxd56 | | -+--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| ST STM32 | F0 | |:heavy_check_mark:| | |:x:| | |:x:| | stm32_fsdev | | -| +----+------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | F1 | 102, 103 | |:heavy_check_mark:| | |:x:| | |:x:| | stm32_fsdev | | -| | +------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | | 105, 107 | |:heavy_check_mark:| | | |:x:| | dwc2 | | -| +----+------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | F2 | |:heavy_check_mark:| | | |:heavy_check_mark:| | dwc2 | | -| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | F3 | |:heavy_check_mark:| | |:x:| | |:x:| | stm32_fsdev | | -| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | F4 | |:heavy_check_mark:| | | |:heavy_check_mark:| | dwc2 | | -| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | F7 | |:heavy_check_mark:| | | |:heavy_check_mark:| | dwc2 | | -| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | H7 | |:heavy_check_mark:| | | |:heavy_check_mark:| | dwc2 | | -| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | L0, L1 | |:heavy_check_mark:| | |:x:| | |:x:| | stm32_fsdev | | -| +----+------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | L4 | 4x2, 4x3 | |:heavy_check_mark:| | |:x:| | |:x:| | stm32_fsdev | | -| | +------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | | 4x5, 4x6 | |:heavy_check_mark:| | | | dwc2 | | -| +----+------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | L4+ | |:heavy_check_mark:| | | | dwc2 | | -| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | U5 | |:construction:| | | | dwc2 | | -+--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| TI | MSP430 | |:heavy_check_mark:| | |:x:| | |:x:| | msp430x5xx | | -| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | MSP432E4 | |:heavy_check_mark:| | | |:x:| | musb | | -| +-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| | TM4C123 | |:heavy_check_mark:| | | |:x:| | musb | | -+--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ -| ValentyUSB | eptri | |:heavy_check_mark:| | |:x:| | |:x:| | eptri | | -+--------------+-----------------------+----------------------+----------------------+----------------------+-----------------+--------------+ ++--------------+-----------------------+--------+------+-----------+-------------------+--------------+ +| Manufacturer | Family | Device | Host | Highspeed | Driver | Note | ++==============+=======================+========+======+===========+===================+==============+ +| Broadcom | BCM2711, BCM2837 | ✔ | | ✔ | dwc2 | | ++--------------+-----------------------+--------+------+-----------+-------------------+--------------+ +| Dialog | DA1469x | ✔ | ✖ | ✖ | da146xx | | ++--------------+-----------------------+--------+------+-----------+-------------------+--------------+ +| Espressif | ESP32 S2, S3 | ✔ | | ✖ | dwc2 or esp32sx | | ++--------------+-----------------------+--------+------+-----------+-------------------+--------------+ +| GigaDevice | GD32VF103 | ✔ | | ✖ | dwc2 | | ++--------------+-----------------------+--------+------+-----------+-------------------+--------------+ +| Infineon | XMC4500 | ✔ | | ✖ | dwc2 | | ++--------------+-----------------------+--------+------+-----------+-------------------+--------------+ +| MicroChip | SAM D11, D21 | ✔ | | ✖ | samd | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ +| | SAM D51, E5x | ✔ | | ✖ | samd | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ +| | SAM G55 | ✔ | | ✖ | samg | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ +| | SAM L21, L22 | ✔ | | ✖ | samd | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ +| | SAM E70,S70,V70,V71 | ✔ | | ✔ | samx7x | | ++--------------+-----------------------+--------+------+-----------+-------------------+--------------+ +| NordicSemi | nRF52833, nRF52840 | ✔ | ✖ | ✖ | nrf5x | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ +| | nRF5340 | ✔ | ✖ | ✖ | nrf5x | | ++--------------+-----------------------+--------+------+-----------+-------------------+--------------+ +| Nuvoton | NUC120 | ✔ | ✖ | ✖ | | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ +| | NUC121/NUC125 | ✔ | ✖ | ✖ | | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ +| | NUC126 | ✔ | ✖ | ✖ | | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ +| | NUC505 | ✔ | | ✔ | | | ++--------------+-----------------------+--------+------+-----------+-------------------+--------------+ +| NXP | iMXRT | RT10xx | ✔ | ✔ | ✔ | ci_hs | | +| +---------+-------------+--------+------+-----------+-------------------+--------------+ +| | Kinetis | KL25 | ✔ | | ✖ | | | +| | +-------------+--------+------+-----------+-------------------+--------------+ +| | | K32L2 | ✔ | | ✖ | | | +| +---------+-------------+--------+------+-----------+-------------------+--------------+ +| | LPC | 11u, 13, 15 | ✔ | ✖ | ✖ | lpc_ip3511 | | +| | +-------------+--------+------+-----------+-------------------+--------------+ +| | | 17, 40 | ✔ | ⚠ | ✖ | lpc17_40 | | +| | +-------------+--------+------+-----------+-------------------+--------------+ +| | | 18, 43 | ✔ | ✔ | ✔ | ci_hs | | +| | +-------------+--------+------+-----------+-------------------+--------------+ +| | | 51u | ✔ | ✖ | ✖ | lpc_ip3511 | | +| | +-------------+--------+------+-----------+-------------------+--------------+ +| | | 54 | ✔ | | ✔ | lpc_ip3511 | | +| | +-------------+--------+------+-----------+-------------------+--------------+ +| | | 55 | ✔ | | ✔ | lpc_ip3511 | | ++--------------+---------+-------------+--------+------+-----------+-------------------+--------------+ +| Raspberry Pi | RP2040 | ✔ | ✔ | ✖ | rp2040 | | ++--------------+-----------------------+--------+------+-----------+-------------------+--------------+ +| Renesas | RX 63N, 65N, 72N | ✔ | ✖ | ✖ | usba | | ++--------------+-----------------------+--------+------+-----------+-------------------+--------------+ +| Silabs | EFM32GG12 | ✔ | | ✖ | dwc2 | | ++--------------+-----------------------+--------+------+-----------+-------------------+--------------+ +| Sony | CXD56 | ✔ | ✖ | ✔ | cxd56 | | ++--------------+-----------------------+--------+------+-----------+-------------------+--------------+ +| ST STM32 | F0 | ✔ | ✖ | ✖ | stm32_fsdev | | +| +----+------------------+--------+------+-----------+-------------------+--------------+ +| | F1 | 102, 103 | ✔ | ✖ | ✖ | stm32_fsdev | | +| | +------------------+--------+------+-----------+-------------------+--------------+ +| | | 105, 107 | ✔ | | ✖ | dwc2 | | +| +----+------------------+--------+------+-----------+-------------------+--------------+ +| | F2 | ✔ | | ✔ | dwc2 | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ +| | F3 | ✔ | ✖ | ✖ | stm32_fsdev | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ +| | F4 | ✔ | | ✔ | dwc2 | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ +| | F7 | ✔ | | ✔ | dwc2 | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ +| | H7 | ✔ | | ✔ | dwc2 | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ +| | L0, L1 | ✔ | ✖ | ✖ | stm32_fsdev | | +| +----+------------------+--------+------+-----------+-------------------+--------------+ +| | L4 | 4x2, 4x3 | ✔ | ✖ | ✖ | stm32_fsdev | | +| | +------------------+--------+------+-----------+-------------------+--------------+ +| | | 4x5, 4x6 | ✔ | | | dwc2 | | +| +----+------------------+--------+------+-----------+-------------------+--------------+ +| | L4+ | ✔ | | | dwc2 | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ +| | U5 | ⚠ | | | dwc2 | | ++--------------+-----------------------+--------+------+-----------+-------------------+--------------+ +| TI | MSP430 | ✔ | ✖ | ✖ | msp430x5xx | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ +| | MSP432E4 | ✔ | | ✖ | musb | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ +| | TM4C123 | ✔ | | ✖ | musb | | ++--------------+-----------------------+--------+------+-----------+-------------------+--------------+ +| ValentyUSB | eptri | ✔ | ✖ | ✖ | eptri | | ++--------------+-----------------------+--------+------+-----------+-------------------+--------------+ + Table Legend ------------ -==================== =================== -|:heavy_check_mark:| Supported -|:construction:| WIP/partial support -|:x:| Not supported -==================== =================== += =================== +✔ Supported +⚠ WIP/partial support +✖ Not supported += =================== Supported Boards ================ From 369f11fe5c21ca19538e9165100115d34fdc72f4 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 2 Dec 2021 11:50:28 +0700 Subject: [PATCH 037/504] fix ci --- examples/host/hid_controller/Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/host/hid_controller/Makefile b/examples/host/hid_controller/Makefile index 2595ec4a7..a4eaf0816 100644 --- a/examples/host/hid_controller/Makefile +++ b/examples/host/hid_controller/Makefile @@ -23,9 +23,7 @@ SRC_C += \ src/host/hub.c \ src/host/usbh.c \ src/host/usbh_control.c \ - src/portable/ehci/ehci.c \ src/portable/ohci/ohci.c \ - src/portable/nxp/transdimension/hcd_transdimension.c \ src/portable/nxp/lpc17_40/hcd_lpc17_40.c include ../../rules.mk From 1d1e75236c4bed4346e6ed840869de2c3acf7220 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 2 Dec 2021 12:02:25 +0700 Subject: [PATCH 038/504] temporarily skip s3 build on ci --- .github/workflows/build_esp.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_esp.yml b/.github/workflows/build_esp.yml index 15071b178..57dbf33e3 100644 --- a/.github/workflows/build_esp.yml +++ b/.github/workflows/build_esp.yml @@ -18,7 +18,8 @@ jobs: # ESP32-S2 - 'espressif_saola_1' # ESP32-S3 - - 'espressif_addax_1' + #- 'espressif_addax_1' + # S3 compile error with "dangerous relocation: call8: call target out of range: memcpy" steps: - name: Setup Python From 94c35de0d2632574b8833a3310082a7e25aa6dd2 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 2 Dec 2021 13:19:27 +0700 Subject: [PATCH 039/504] minor doc update --- docs/reference/supported.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index 83cf874da..e3cb8c679 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -39,7 +39,7 @@ Supported MCUs | | NUC126 | ✔ | ✖ | ✖ | | | | +-----------------------+--------+------+-----------+-------------------+--------------+ | | NUC505 | ✔ | | ✔ | | | -+--------------+-----------------------+--------+------+-----------+-------------------+--------------+ ++--------------+---------+-------------+--------+------+-----------+-------------------+--------------+ | NXP | iMXRT | RT10xx | ✔ | ✔ | ✔ | ci_hs | | | +---------+-------------+--------+------+-----------+-------------------+--------------+ | | Kinetis | KL25 | ✔ | | ✖ | | | From c52c9cda913a828da4d6b2da4df8a0ef1751c425 Mon Sep 17 00:00:00 2001 From: Rafael Silva Date: Thu, 2 Dec 2021 10:22:24 +0000 Subject: [PATCH 040/504] after commit: eae4132 this dependency is no longer required Signed-off-by: Rafael Silva --- docs/conf.py | 1 - docs/requirements.txt | 1 - 2 files changed, 2 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index c7a17478f..878b29645 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -21,7 +21,6 @@ extensions = [ 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx_autodoc_typehints', - 'sphinxemoji.sphinxemoji', ] templates_path = ['_templates'] diff --git a/docs/requirements.txt b/docs/requirements.txt index e415ae03e..8ae9ae73b 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,3 @@ sphinx~=3.0 furo>=2020.12.30.b24 -sphinxemoji>=0.1.8 sphinx-autodoc-typehints>=1.10 From 81285273a6b5cacace52e74890ff9863a6a92d1a Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Sat, 4 Dec 2021 01:18:42 +0900 Subject: [PATCH 041/504] Fix memory overrun at pipe_read_packet() --- src/portable/mentor/musb/hcd_musb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/portable/mentor/musb/hcd_musb.c b/src/portable/mentor/musb/hcd_musb.c index dc614d074..acccb7674 100644 --- a/src/portable/mentor/musb/hcd_musb.c +++ b/src/portable/mentor/musb/hcd_musb.c @@ -269,12 +269,12 @@ static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len) len -= 4; } if (len >= 2) { - *(uint32_t *)addr = reg->u16; + *(uint16_t *)addr = reg->u16; addr += 2; len -= 2; } if (len) { - *(uint32_t *)addr = reg->u8; + *(uint8_t *)addr = reg->u8; } } From 7137a0a92f5623e06d7457aba0eaa65f077010a2 Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Sat, 4 Dec 2021 01:25:34 +0900 Subject: [PATCH 042/504] Fix buffer overrun at pipe_read_packet() --- src/portable/mentor/musb/dcd_musb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 4b4c2f9b2..512beff97 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -250,12 +250,12 @@ static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len) len -= 4; } if (len >= 2) { - *(uint32_t *)addr = reg->u16; + *(uint16_t *)addr = reg->u16; addr += 2; len -= 2; } if (len) { - *(uint32_t *)addr = reg->u8; + *(uint8_t *)addr = reg->u8; } } From dff54d854ddae3ff5c8dc81bac77fd8b50564598 Mon Sep 17 00:00:00 2001 From: Yunhao Tian Date: Sat, 4 Dec 2021 17:18:39 +0800 Subject: [PATCH 043/504] Modify sunxi_musb code --- src/portable/sunxi/dcd_sunxi_musb.c | 40 +++++++++++++++++++---------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/portable/sunxi/dcd_sunxi_musb.c b/src/portable/sunxi/dcd_sunxi_musb.c index bb39d3890..b13842de1 100644 --- a/src/portable/sunxi/dcd_sunxi_musb.c +++ b/src/portable/sunxi/dcd_sunxi_musb.c @@ -1,8 +1,7 @@ #include -#include +#include "tusb_option.h" +#include "osal/osal.h" #include - -#include #include #include "musb_def.h" @@ -10,9 +9,7 @@ typedef uint32_t u32; typedef uint16_t u16; typedef uint8_t u8; -#if !TU_CHECK_MCU(OPT_MCU_F1C100S) - #error "Only f1c100s is supported" -#endif +#if TUSB_OPT_DEVICE_ENABLED && CFG_TUSB_MCU == OPT_MCU_F1C100S #define REQUEST_TYPE_INVALID (0xFFu) @@ -69,12 +66,22 @@ static void usb_phy_write(int addr, int data, int len) } } +static void delay_ms(uint32_t ms) +{ +#if CFG_TUSB_OS == OPT_OS_NONE + int cnt = ms * 1000 * 1000 / 2; + while (cnt--) asm("nop"); +#else + osal_task_delay(ms); +#endif +} + static void USBC_HardwareReset(void) { // Reset phy and controller USBC_REG_set_bit_l(USBPHY_CLK_RST_BIT, USBPHY_CLK_REG); USBC_REG_set_bit_l(BUS_RST_USB_BIT, BUS_CLK_RST_REG); - osal_task_delay(2); + delay_ms(2); USBC_REG_set_bit_l(USBPHY_CLK_GAT_BIT, USBPHY_CLK_REG); USBC_REG_set_bit_l(USBPHY_CLK_RST_BIT, USBPHY_CLK_REG); @@ -83,7 +90,7 @@ static void USBC_HardwareReset(void) USBC_REG_set_bit_l(BUS_RST_USB_BIT, BUS_CLK_RST_REG); } -static void USBC_PhyConfig() +static void USBC_PhyConfig(void) { /* Regulation 45 ohms */ usb_phy_write(0x0c, 0x01, 1); @@ -97,7 +104,7 @@ static void USBC_PhyConfig() return; } -static void USBC_ConfigFIFO_Base() +static void USBC_ConfigFIFO_Base(void) { u32 reg_value; @@ -507,7 +514,7 @@ static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigne static void process_setup_packet(uint8_t rhport) { - uint32_t *p = (void*)&_dcd.setup_packet; + uint32_t *p = (uint32_t*)&_dcd.setup_packet; p[0] = USBC_Readl(USBC_REG_EPFIFO0(USBC0_BASE)); p[1] = USBC_Readl(USBC_REG_EPFIFO0(USBC0_BASE)); @@ -808,7 +815,7 @@ static void process_bus_reset(uint8_t rhport) * Device API *------------------------------------------------------------------*/ -static void usb_isr_handler() { +static void usb_isr_handler(void) { dcd_int_handler(0); } @@ -861,7 +868,7 @@ void dcd_int_enable(uint8_t rhport) f1c100s_intc_enable_irq(F1C100S_IRQ_USBOTG); } -static void musb_int_mask() +static void musb_int_mask(void) { f1c100s_intc_mask_irq(F1C100S_IRQ_USBOTG); } @@ -872,7 +879,7 @@ void dcd_int_disable(uint8_t rhport) f1c100s_intc_disable_irq(F1C100S_IRQ_USBOTG); } -static void musb_int_unmask() +static void musb_int_unmask(void) { f1c100s_intc_unmask_irq(F1C100S_IRQ_USBOTG); } @@ -895,7 +902,7 @@ void dcd_remote_wakeup(uint8_t rhport) { (void)rhport; USBC_REG_set_bit_b(USBC_BP_POWER_D_RESUME, USBC_REG_PCTL(USBC0_BASE)); - osal_task_delay(10); + delay_ms(10); USBC_REG_clear_bit_b(USBC_BP_POWER_D_RESUME, USBC_REG_PCTL(USBC0_BASE)); } @@ -903,6 +910,10 @@ void dcd_remote_wakeup(uint8_t rhport) // Endpoint API //--------------------------------------------------------------------+ +#ifndef __ARMCC_VERSION +#define __clz __builtin_clz +#endif + // Configure endpoint's registers according to descriptor bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) { @@ -1150,3 +1161,4 @@ void dcd_int_handler(uint8_t rhport) } } +#endif From 68ca62dfd7e7fe757ba436fee7721520119da92b Mon Sep 17 00:00:00 2001 From: Yunhao Tian Date: Sat, 4 Dec 2021 18:02:07 +0800 Subject: [PATCH 044/504] Add BSP support for F1C100s --- examples/rules.mk | 5 + hw/bsp/f1c100s/README.md | 17 + hw/bsp/f1c100s/board.h | 1 + hw/bsp/f1c100s/board.mk | 45 + hw/bsp/f1c100s/f1c100s.c | 130 +++ hw/mcu/allwinner/f1c100s/f1c100s.ld | 137 +++ hw/mcu/allwinner/f1c100s/include/arm32.h | 150 ++++ .../allwinner/f1c100s/include/f1c100s-gpio.h | 66 ++ .../allwinner/f1c100s/include/f1c100s-irq.h | 104 +++ .../allwinner/f1c100s/include/f1c100s-reset.h | 39 + .../allwinner/f1c100s/include/f1c100s-util.h | 139 +++ .../f1c100s/include/f1c100s/reg-ccu.h | 55 ++ .../f1c100s/include/f1c100s/reg-dram.h | 39 + hw/mcu/allwinner/f1c100s/include/io.h | 57 ++ hw/mcu/allwinner/f1c100s/include/irqflags.h | 104 +++ hw/mcu/allwinner/f1c100s/include/malloc.h | 35 + hw/mcu/allwinner/f1c100s/include/printf.h | 99 +++ hw/mcu/allwinner/f1c100s/include/sizes.h | 42 + hw/mcu/allwinner/f1c100s/include/types.h | 55 ++ hw/mcu/allwinner/f1c100s/lib/malloc.c | 834 ++++++++++++++++++ hw/mcu/allwinner/f1c100s/lib/memcpy.S | 404 +++++++++ hw/mcu/allwinner/f1c100s/lib/memset.S | 79 ++ hw/mcu/allwinner/f1c100s/lib/printf.c | 757 ++++++++++++++++ hw/mcu/allwinner/f1c100s/machine/exception.c | 76 ++ .../allwinner/f1c100s/machine/f1c100s-intc.c | 173 ++++ hw/mcu/allwinner/f1c100s/machine/start.S | 313 +++++++ hw/mcu/allwinner/f1c100s/machine/sys-clock.c | 124 +++ .../allwinner/f1c100s/machine/sys-copyself.c | 111 +++ hw/mcu/allwinner/f1c100s/machine/sys-dram.c | 506 +++++++++++ hw/mcu/allwinner/f1c100s/machine/sys-mmu.c | 57 ++ .../allwinner/f1c100s/machine/sys-spi-flash.c | 204 +++++ hw/mcu/allwinner/f1c100s/machine/sys-uart.c | 83 ++ src/portable/sunxi/dcd_sunxi_musb.c | 5 +- 33 files changed, 5043 insertions(+), 2 deletions(-) create mode 100644 hw/bsp/f1c100s/README.md create mode 100644 hw/bsp/f1c100s/board.h create mode 100644 hw/bsp/f1c100s/board.mk create mode 100644 hw/bsp/f1c100s/f1c100s.c create mode 100644 hw/mcu/allwinner/f1c100s/f1c100s.ld create mode 100644 hw/mcu/allwinner/f1c100s/include/arm32.h create mode 100644 hw/mcu/allwinner/f1c100s/include/f1c100s-gpio.h create mode 100644 hw/mcu/allwinner/f1c100s/include/f1c100s-irq.h create mode 100644 hw/mcu/allwinner/f1c100s/include/f1c100s-reset.h create mode 100644 hw/mcu/allwinner/f1c100s/include/f1c100s-util.h create mode 100644 hw/mcu/allwinner/f1c100s/include/f1c100s/reg-ccu.h create mode 100644 hw/mcu/allwinner/f1c100s/include/f1c100s/reg-dram.h create mode 100644 hw/mcu/allwinner/f1c100s/include/io.h create mode 100644 hw/mcu/allwinner/f1c100s/include/irqflags.h create mode 100644 hw/mcu/allwinner/f1c100s/include/malloc.h create mode 100644 hw/mcu/allwinner/f1c100s/include/printf.h create mode 100644 hw/mcu/allwinner/f1c100s/include/sizes.h create mode 100644 hw/mcu/allwinner/f1c100s/include/types.h create mode 100644 hw/mcu/allwinner/f1c100s/lib/malloc.c create mode 100644 hw/mcu/allwinner/f1c100s/lib/memcpy.S create mode 100644 hw/mcu/allwinner/f1c100s/lib/memset.S create mode 100644 hw/mcu/allwinner/f1c100s/lib/printf.c create mode 100644 hw/mcu/allwinner/f1c100s/machine/exception.c create mode 100644 hw/mcu/allwinner/f1c100s/machine/f1c100s-intc.c create mode 100644 hw/mcu/allwinner/f1c100s/machine/start.S create mode 100644 hw/mcu/allwinner/f1c100s/machine/sys-clock.c create mode 100644 hw/mcu/allwinner/f1c100s/machine/sys-copyself.c create mode 100644 hw/mcu/allwinner/f1c100s/machine/sys-dram.c create mode 100644 hw/mcu/allwinner/f1c100s/machine/sys-mmu.c create mode 100644 hw/mcu/allwinner/f1c100s/machine/sys-spi-flash.c create mode 100644 hw/mcu/allwinner/f1c100s/machine/sys-uart.c diff --git a/examples/rules.mk b/examples/rules.mk index 4cc35cb22..6314380ec 100644 --- a/examples/rules.mk +++ b/examples/rules.mk @@ -182,6 +182,11 @@ flash-jlink: $(BUILD)/$(PROJECT).hex flash-stlink: $(BUILD)/$(PROJECT).elf STM32_Programmer_CLI --connect port=swd --write $< --go +flash-xfel: $(BUILD)/$(PROJECT).bin + xfel ddr + xfel write 0x80000000 $< + xfel exec 0x80000000 + # Flash using pyocd PYOCD_OPTION ?= flash-pyocd: $(BUILD)/$(PROJECT).hex diff --git a/hw/bsp/f1c100s/README.md b/hw/bsp/f1c100s/README.md new file mode 100644 index 000000000..a4865b925 --- /dev/null +++ b/hw/bsp/f1c100s/README.md @@ -0,0 +1,17 @@ +# BSP support for F1Cx00s boards + +This folder contains necessary file and scripts to run TinyUSB examples on F1Cx00s boards. + +Currently tested on: + +* Lichee Pi Nano (F1C100s) + +## make flash +`make flash` will use [xfel](https://github.com/xboot/xfel) to write the code to onchip DDR memory and execute it. It will not write the program to SPI Flash. + +To enter FEL mode, you have to press BOOT button, then press RESET once, and release BOOT button. You will find VID/PID=1f3a:efe8 on your PC. + +## TODO +* Test on Tiny200 v2 (F1C200s) +* Make it able to load .bin directly to SPI Flash and boot +* Add F1C100s to `#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX` high speed MCU check in examples (maybe we should extract the logic?) \ No newline at end of file diff --git a/hw/bsp/f1c100s/board.h b/hw/bsp/f1c100s/board.h new file mode 100644 index 000000000..238ac796d --- /dev/null +++ b/hw/bsp/f1c100s/board.h @@ -0,0 +1 @@ +// Nothing valuable here \ No newline at end of file diff --git a/hw/bsp/f1c100s/board.mk b/hw/bsp/f1c100s/board.mk new file mode 100644 index 000000000..993aa0d24 --- /dev/null +++ b/hw/bsp/f1c100s/board.mk @@ -0,0 +1,45 @@ +DEFINES += -D__ARM32_ARCH__=5 -D__ARM926EJS__ + +CFLAGS += \ + -ffreestanding \ + -std=gnu99 \ + -march=armv5te \ + -mtune=arm926ej-s \ + -mfloat-abi=soft \ + -marm \ + -mno-thumb-interwork \ + -Wno-unused-parameter \ + -Wno-float-equal \ + -DCFG_TUSB_MCU=OPT_MCU_F1C100S \ + -Wno-error=cast-align \ + -Wno-error=address-of-packed-member \ + $(DEFINES) + +LD_FILE = hw/mcu/allwinner/f1c100s/f1c100s.ld +LDFLAGS += -nostdlib -lgcc +MCU_DIR = hw/mcu/allwinner/f1c100s + +SRC_C += \ + src/portable/sunxi/dcd_sunxi_musb.c \ + $(MCU_DIR)/machine/sys-uart.c \ + $(MCU_DIR)/machine/exception.c \ + $(MCU_DIR)/machine/sys-clock.c \ + $(MCU_DIR)/machine/sys-copyself.c \ + $(MCU_DIR)/machine/sys-dram.c \ + $(MCU_DIR)/machine/sys-mmu.c \ + $(MCU_DIR)/machine/sys-spi-flash.c \ + $(MCU_DIR)/machine/f1c100s-intc.c \ + $(MCU_DIR)/lib/malloc.c \ + $(MCU_DIR)/lib/printf.c + +SRC_S += \ + $(MCU_DIR)/machine/start.S \ + $(MCU_DIR)/lib/memcpy.S \ + $(MCU_DIR)/lib/memset.S + +INC += \ + $(TOP)/$(MCU_DIR)/include \ + $(TOP)/$(BOARD_PATH) + +# flash target using on-board stlink +flash: flash-xfel diff --git a/hw/bsp/f1c100s/f1c100s.c b/hw/bsp/f1c100s/f1c100s.c new file mode 100644 index 000000000..6cf18597c --- /dev/null +++ b/hw/bsp/f1c100s/f1c100s.c @@ -0,0 +1,130 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include "bsp/board.h" +#include "board.h" + +extern void sys_uart_putc(char c); + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +static void timer_init(void); + +void board_init(void) +{ + arch_local_irq_disable(); + do_init_mem_pool(); + f1c100s_intc_init(); + timer_init(); + printf("Timer INIT done\n"); + arch_local_irq_enable(); +} + +// No LED, no button, sorry +void board_led_write(bool state) +{ + +} + +uint32_t board_button_read(void) +{ + return 0; +} + +int board_uart_read(uint8_t* buf, int len) +{ + return 0; +} + +int board_uart_write(void const * buf, int len) +{ + int txsize = len; + while (txsize--) { + sys_uart_putc(*(uint8_t const*)buf); + buf++; + } + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; + +uint32_t board_millis(void) +{ + return system_ticks; +} + +static void timer_handler(void) +{ + volatile uint32_t *temp_addr = (uint32_t *)(0x01C20C00 + 0x04); + + /* clear timer */ + *temp_addr |= 0x01; + + system_ticks++; +} + +static void timer_init(void) { + uint32_t temp; + volatile uint32_t *temp_addr; + + /* reload value */ + temp = 12000000 / 1000; + temp_addr = (uint32_t *)(0x01C20C00 + 0x14); + *temp_addr = temp; + + /* continuous | /2 | 24Mhz | reload*/ + temp = (0x00 << 7) | (0x01 << 4) | (0x01 << 2) | (0x00 << 1); + temp_addr = (uint32_t *)(0x01C20C00 + 0x10); + *temp_addr &= 0xffffff00; + *temp_addr |= temp; + + /* open timer irq */ + temp = 0x01 << 0; + temp_addr = (uint32_t *)(0x01C20C00); + *temp_addr |= temp; + + /* set init value */ + temp_addr = (uint32_t *)(0x01C20C00 + 0x18); + *temp_addr = 0; + + /* begin run timer */ + temp = 0x01 << 0; + temp_addr = (uint32_t *)(0x01C20C00 + 0x10); + *temp_addr |= temp; + + f1c100s_intc_set_isr(F1C100S_IRQ_TIMER0, timer_handler); + f1c100s_intc_enable_irq(F1C100S_IRQ_TIMER0); +} +#else +static void timer_init(void) { } +#endif diff --git a/hw/mcu/allwinner/f1c100s/f1c100s.ld b/hw/mcu/allwinner/f1c100s/f1c100s.ld new file mode 100644 index 000000000..a261618e5 --- /dev/null +++ b/hw/mcu/allwinner/f1c100s/f1c100s.ld @@ -0,0 +1,137 @@ +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) + +STACK_UND_SIZE = 0x10000; +STACK_ABT_SIZE = 0x10000; +STACK_IRQ_SIZE = 0x10000; +STACK_FIQ_SIZE = 0x10000; +STACK_SRV_SIZE = 0x40000; + +MEMORY +{ + ram : org = 0x80000000, len = 8M + heap : org = 0x81000000, len = 16M +} + +SECTIONS +{ + .bootloader : + { + PROVIDE(__bootloader_start = .); + PROVIDE(__image_start = .); + PROVIDE(__text_start = .); + */machine/start.o (.text) + */lib/memcpy.o (.text) + */lib/memset.o (.text) + */machine/sys-uart.o (.text) + */machine/sys-clock.o (.text) + */machine/sys-dram.o (.text) + */machine/sys-mmu.o (.text) + */machine/sys-spi-flash.o (.text) + */machine/sys-copyself.o (.text) + PROVIDE(__bootloader_end = .); + } > ram + + __bootloader_size = SIZEOF(.bootloader); + + .text : + { + */main.o (.text) + *(.text*) + *(.glue*) + *(.note.gnu.build-id) + PROVIDE(__text_end = .); + } > ram + + .rodata ALIGN(8) : + { + PROVIDE(__rodata_start = .); + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) + PROVIDE(__rodata_end = .); + } > ram + + .data_shadow ALIGN(8) : + { + PROVIDE(__data_shadow_start = .); + PROVIDE(__data_shadow_end = (. + SIZEOF(.data))); + PROVIDE(__image_end = __data_shadow_end); + } > ram + + .data : AT(ADDR(.data_shadow)) + { + PROVIDE(__data_start = .); + *(.data*) + . = ALIGN(8); + PROVIDE(__data_end = .); + } > ram + + .ARM.exidx ALIGN(8) : + { + PROVIDE (__exidx_start = .); + *(.ARM.exidx*) + PROVIDE (__exidx_end = .); + } > ram + + .ARM.extab ALIGN(8) : + { + PROVIDE (__extab_start = .); + *(.ARM.extab*) + PROVIDE (__extab_end = .); + } > ram + + .bss ALIGN(8) (NOLOAD) : + { + PROVIDE(__bss_start = .); + *(.bss*) + *(.sbss*) + *(COMMON) + . = ALIGN(8); + PROVIDE(__bss_end = .); + } > ram + + .stack ALIGN(8) (NOLOAD) : + { + PROVIDE(__stack_start = .); + PROVIDE(__stack_und_start = .); + . += STACK_UND_SIZE; + PROVIDE(__stack_und_end = .); + . = ALIGN(8); + PROVIDE(__stack_abt_start = .); + . += STACK_ABT_SIZE; + PROVIDE(__stack_abt_end = .); + . = ALIGN(8); + PROVIDE(__stack_irq_start = .); + . += STACK_IRQ_SIZE; + PROVIDE(__stack_irq_end = .); + . = ALIGN(8); + PROVIDE(__stack_fiq_start = .); + . += STACK_FIQ_SIZE; + PROVIDE(__stack_fiq_end = .); + . = ALIGN(8); + PROVIDE(__stack_srv_start = .); + . += STACK_SRV_SIZE; + PROVIDE(__stack_srv_end = .); + . = ALIGN(8); + PROVIDE(__stack_end = .); + } > ram + + .heap ALIGN(8) (NOLOAD) : + { + PROVIDE(__heap_start = ORIGIN(heap)); + PROVIDE(__heap_end = ORIGIN(heap) + LENGTH(heap)); + } > heap + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/hw/mcu/allwinner/f1c100s/include/arm32.h b/hw/mcu/allwinner/f1c100s/include/arm32.h new file mode 100644 index 000000000..a3a254551 --- /dev/null +++ b/hw/mcu/allwinner/f1c100s/include/arm32.h @@ -0,0 +1,150 @@ +#ifndef __ARM32_H__ +#define __ARM32_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +struct arm_regs_t { + uint32_t r[13]; + uint32_t sp; + uint32_t lr; + uint32_t pc; + uint32_t cpsr; +}; + +static inline uint32_t arm32_read_p15_c1(void) +{ + uint32_t value; + + __asm__ __volatile__( + "mrc p15, 0, %0, c1, c0, 0" + : "=r" (value) + : + : "memory"); + + return value; +} + +static inline void arm32_write_p15_c1(uint32_t value) +{ + __asm__ __volatile__( + "mcr p15, 0, %0, c1, c0, 0" + : + : "r" (value) + : "memory"); + arm32_read_p15_c1(); +} + +static inline void arm32_interrupt_enable(void) +{ + uint32_t tmp; + + __asm__ __volatile__( + "mrs %0, cpsr\n" + "bic %0, %0, #(1<<7)\n" + "msr cpsr_cxsf, %0" + : "=r" (tmp) + : + : "memory"); +} + +static inline void arm32_interrupt_disable(void) +{ + uint32_t tmp; + + __asm__ __volatile__( + "mrs %0, cpsr\n" + "orr %0, %0, #(1<<7)\n" + "msr cpsr_cxsf, %0" + : "=r" (tmp) + : + : "memory"); +} + +static inline void arm32_mmu_enable(void) +{ + uint32_t value = arm32_read_p15_c1(); + arm32_write_p15_c1(value | (1 << 0)); +} + +static inline void arm32_mmu_disable(void) +{ + uint32_t value = arm32_read_p15_c1(); + arm32_write_p15_c1(value & ~(1 << 0)); +} + +static inline void arm32_dcache_enable(void) +{ + uint32_t value = arm32_read_p15_c1(); + arm32_write_p15_c1(value | (1 << 2)); +} + +static inline void arm32_dcache_disable(void) +{ + uint32_t value = arm32_read_p15_c1(); + arm32_write_p15_c1(value & ~(1 << 2)); +} + +static inline void arm32_icache_enable(void) +{ + uint32_t value = arm32_read_p15_c1(); + arm32_write_p15_c1(value | (1 << 12)); +} + +static inline void arm32_icache_disable(void) +{ + uint32_t value = arm32_read_p15_c1(); + arm32_write_p15_c1(value & ~(1 << 12)); +} + +static inline uint32_t arm32_smp_processor_id(void) +{ + uint32_t tmp; + + __asm__ __volatile__( + "mrc p15,0,%0,c0,c0,5\n" + "and %0,%0,#0x3\n" + : "=r" (tmp) + : + : "memory"); + return tmp; +} + +static inline void arm32_ttb_set(uint32_t base) +{ + __asm__ __volatile__( + "mcr p15, 0, %0, c2, c0, 0" + : + : "r" (base) + : "memory"); +} + +static inline void arm32_domain_set(uint32_t domain) +{ + __asm__ __volatile__( + "mcr p15, 0, %0, c3, c0, 0" + : + : "r" (domain) + : "memory"); +} + +static inline void arm32_tlb_invalidate(void) +{ + __asm__ __volatile__( + "mov r0, #0\n" + "mcr p15, 0, r0, c7, c10, 4\n" + "mcr p15, 0, r0, c8, c6, 0\n" + "mcr p15, 0, r0, c8, c5, 0\n" + : + : + : "r0"); +} + +#ifdef __cplusplus +} +#endif + +#endif /* __ARM32_H__ */ diff --git a/hw/mcu/allwinner/f1c100s/include/f1c100s-gpio.h b/hw/mcu/allwinner/f1c100s/include/f1c100s-gpio.h new file mode 100644 index 000000000..3dbe8bf13 --- /dev/null +++ b/hw/mcu/allwinner/f1c100s/include/f1c100s-gpio.h @@ -0,0 +1,66 @@ +#ifndef __F1C100S_GPIO_H__ +#define __F1C100S_GPIO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define F1C100S_GPIOA0 (0) +#define F1C100S_GPIOA1 (1) +#define F1C100S_GPIOA2 (2) +#define F1C100S_GPIOA3 (3) + +#define F1C100S_GPIOC0 (64) +#define F1C100S_GPIOC1 (65) +#define F1C100S_GPIOC2 (66) +#define F1C100S_GPIOC3 (67) + +#define F1C100S_GPIOD0 (96) +#define F1C100S_GPIOD1 (97) +#define F1C100S_GPIOD2 (98) +#define F1C100S_GPIOD3 (99) +#define F1C100S_GPIOD4 (100) +#define F1C100S_GPIOD5 (101) +#define F1C100S_GPIOD6 (102) +#define F1C100S_GPIOD7 (103) +#define F1C100S_GPIOD8 (104) +#define F1C100S_GPIOD9 (105) +#define F1C100S_GPIOD10 (106) +#define F1C100S_GPIOD11 (107) +#define F1C100S_GPIOD12 (108) +#define F1C100S_GPIOD13 (109) +#define F1C100S_GPIOD14 (110) +#define F1C100S_GPIOD15 (111) +#define F1C100S_GPIOD16 (112) +#define F1C100S_GPIOD17 (113) +#define F1C100S_GPIOD18 (114) +#define F1C100S_GPIOD19 (115) +#define F1C100S_GPIOD20 (116) +#define F1C100S_GPIOD21 (117) + +#define F1C100S_GPIOE0 (128) +#define F1C100S_GPIOE1 (129) +#define F1C100S_GPIOE2 (130) +#define F1C100S_GPIOE3 (131) +#define F1C100S_GPIOE4 (132) +#define F1C100S_GPIOE5 (133) +#define F1C100S_GPIOE6 (134) +#define F1C100S_GPIOE7 (135) +#define F1C100S_GPIOE8 (136) +#define F1C100S_GPIOE9 (137) +#define F1C100S_GPIOE10 (138) +#define F1C100S_GPIOE11 (139) +#define F1C100S_GPIOE12 (140) + +#define F1C100S_GPIOF0 (160) +#define F1C100S_GPIOF1 (161) +#define F1C100S_GPIOF2 (162) +#define F1C100S_GPIOF3 (163) +#define F1C100S_GPIOF4 (164) +#define F1C100S_GPIOF5 (165) + +#ifdef __cplusplus +} +#endif + +#endif /* __F1C100S_GPIO_H__ */ diff --git a/hw/mcu/allwinner/f1c100s/include/f1c100s-irq.h b/hw/mcu/allwinner/f1c100s/include/f1c100s-irq.h new file mode 100644 index 000000000..410d1be93 --- /dev/null +++ b/hw/mcu/allwinner/f1c100s/include/f1c100s-irq.h @@ -0,0 +1,104 @@ +#ifndef __F1C100S_IRQ_H__ +#define __F1C100S_IRQ_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define F1C100S_IRQ_NMI (0) +#define F1C100S_IRQ_UART0 (1) +#define F1C100S_IRQ_UART1 (2) +#define F1C100S_IRQ_UART2 (3) +#define F1C100S_IRQ_SPDIF (5) +#define F1C100S_IRQ_CIR (6) +#define F1C100S_IRQ_I2C0 (7) +#define F1C100S_IRQ_I2C1 (8) +#define F1C100S_IRQ_I2C2 (9) +#define F1C100S_IRQ_SPI0 (10) +#define F1C100S_IRQ_SPI1 (11) +#define F1C100S_IRQ_TIMER0 (13) +#define F1C100S_IRQ_TIMER1 (14) +#define F1C100S_IRQ_TIMER2 (15) +#define F1C100S_IRQ_WDOG (16) +#define F1C100S_IRQ_RSB (17) +#define F1C100S_IRQ_DMA (18) +#define F1C100S_IRQ_TP (20) +#define F1C100S_IRQ_AUDIO (21) +#define F1C100S_IRQ_LRADC (22) +#define F1C100S_IRQ_MMC0 (23) +#define F1C100S_IRQ_MMC1 (24) +#define F1C100S_IRQ_USBOTG (26) +#define F1C100S_IRQ_TVD (27) +#define F1C100S_IRQ_TVE (28) +#define F1C100S_IRQ_LCD (29) +#define F1C100S_IRQ_DEFE (30) +#define F1C100S_IRQ_DEBE (31) +#define F1C100S_IRQ_CSI (32) +#define F1C100S_IRQ_DEITLA (33) +#define F1C100S_IRQ_VE (34) +#define F1C100S_IRQ_I2S (35) +#define F1C100S_IRQ_GPIOD (38) +#define F1C100S_IRQ_GPIOE (39) +#define F1C100S_IRQ_GPIOF (40) + +#define F1C100S_IRQ_GPIOD0 (64) +#define F1C100S_IRQ_GPIOD1 (65) +#define F1C100S_IRQ_GPIOD2 (66) +#define F1C100S_IRQ_GPIOD3 (67) +#define F1C100S_IRQ_GPIOD4 (68) +#define F1C100S_IRQ_GPIOD5 (69) +#define F1C100S_IRQ_GPIOD6 (70) +#define F1C100S_IRQ_GPIOD7 (71) +#define F1C100S_IRQ_GPIOD8 (72) +#define F1C100S_IRQ_GPIOD9 (73) +#define F1C100S_IRQ_GPIOD10 (74) +#define F1C100S_IRQ_GPIOD11 (75) +#define F1C100S_IRQ_GPIOD12 (76) +#define F1C100S_IRQ_GPIOD13 (77) +#define F1C100S_IRQ_GPIOD14 (78) +#define F1C100S_IRQ_GPIOD15 (79) +#define F1C100S_IRQ_GPIOD17 (80) +#define F1C100S_IRQ_GPIOD18 (81) +#define F1C100S_IRQ_GPIOD19 (82) +#define F1C100S_IRQ_GPIOD20 (83) +#define F1C100S_IRQ_GPIOD21 (84) + +#define F1C100S_IRQ_GPIOE0 (96) +#define F1C100S_IRQ_GPIOE1 (97) +#define F1C100S_IRQ_GPIOE2 (98) +#define F1C100S_IRQ_GPIOE3 (99) +#define F1C100S_IRQ_GPIOE4 (100) +#define F1C100S_IRQ_GPIOE5 (101) +#define F1C100S_IRQ_GPIOE6 (102) +#define F1C100S_IRQ_GPIOE7 (103) +#define F1C100S_IRQ_GPIOE8 (104) +#define F1C100S_IRQ_GPIOE9 (105) +#define F1C100S_IRQ_GPIOE10 (106) +#define F1C100S_IRQ_GPIOE11 (107) +#define F1C100S_IRQ_GPIOE12 (108) + +#define F1C100S_IRQ_GPIOF0 (128) +#define F1C100S_IRQ_GPIOF1 (129) +#define F1C100S_IRQ_GPIOF2 (130) +#define F1C100S_IRQ_GPIOF3 (131) +#define F1C100S_IRQ_GPIOF4 (132) +#define F1C100S_IRQ_GPIOF5 (133) + +typedef void (*IRQHandleTypeDef)(void); + +uint8_t f1c100s_intc_get_nirq(void); +void f1c100s_intc_dispatch(uint8_t nIRQ); +void f1c100s_intc_set_isr(uint8_t nIRQ, IRQHandleTypeDef handle); +void f1c100s_intc_enable_irq(uint8_t nIRQ); +void f1c100s_intc_disable_irq(uint8_t nIRQ); +void f1c100s_intc_unmask_irq(uint8_t nIRQ); +void f1c100s_intc_mask_irq(uint8_t nIRQ); +void f1c100s_intc_force_irq(uint8_t nIRQ); +void f1c100s_intc_clear_pend(uint8_t nIRQ); +void f1c100s_intc_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __F1C100S_IRQ_H__ */ diff --git a/hw/mcu/allwinner/f1c100s/include/f1c100s-reset.h b/hw/mcu/allwinner/f1c100s/include/f1c100s-reset.h new file mode 100644 index 000000000..e787a1ac1 --- /dev/null +++ b/hw/mcu/allwinner/f1c100s/include/f1c100s-reset.h @@ -0,0 +1,39 @@ +#ifndef __F1C100S_RESET_H__ +#define __F1C100S_RESET_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define F1C100S_RESET_DMA (6) +#define F1C100S_RESET_SD0 (8) +#define F1C100S_RESET_SD1 (9) +#define F1C100S_RESET_SDRAM (14) +#define F1C100S_RESET_SPI0 (20) +#define F1C100S_RESET_SPI1 (21) +#define F1C100S_RESET_USB_OTG (24) +#define F1C100S_RESET_VE (32) +#define F1C100S_RESET_LCD (36) +#define F1C100S_RESET_DEINTERLACE (37) +#define F1C100S_RESET_CSI (40) +#define F1C100S_RESET_TVD (41) +#define F1C100S_RESET_TVE (42) +#define F1C100S_RESET_DEBE (44) +#define F1C100S_RESET_DEFE (46) +#define F1C100S_RESET_ADDA (64) +#define F1C100S_RESET_SPDIF (65) +#define F1C100S_RESET_CIR (66) +#define F1C100S_RESET_RSB (67) +#define F1C100S_RESET_DAUDIO (76) +#define F1C100S_RESET_I2C0 (80) +#define F1C100S_RESET_I2C1 (81) +#define F1C100S_RESET_I2C2 (82) +#define F1C100S_RESET_UART0 (84) +#define F1C100S_RESET_UART1 (85) +#define F1C100S_RESET_UART2 (86) + +#ifdef __cplusplus +} +#endif + +#endif /* __F1C100S_RESET_H__ */ diff --git a/hw/mcu/allwinner/f1c100s/include/f1c100s-util.h b/hw/mcu/allwinner/f1c100s/include/f1c100s-util.h new file mode 100644 index 000000000..cb3829f82 --- /dev/null +++ b/hw/mcu/allwinner/f1c100s/include/f1c100s-util.h @@ -0,0 +1,139 @@ +// Designed by Hong Xuyao + +#ifndef __TARGET_H__ +#define __TARGET_H__ +//////////////////////////////////////////////////////////////////////////////// +#include +typedef unsigned long ubase_t; + +#define MEM_PI_SRAM __attribute__((section("SRAM"))) + +#define MEM_PI_SUMMARY __attribute__((section("SUMMARY"))) + +#define MEM_PI_NOINIT __attribute__((section("NOINIT"),zero_init)) + +#define MEM_PI_CPUONLY __attribute__((section("CPUONLY"),zero_init)) + +#define MEM_PI_HARDWARE __attribute__((section("HARDWARE"),zero_init,aligned(32))) + +#define MEM_PI_NCNB __attribute__((section("NCNB"),zero_init,aligned(32))) + +#define MEM_PI_STACK __attribute__((section("STACK"),zero_init,aligned(8))) + +#define CACHE_ALIGNED __attribute__((aligned(32))) + +#ifndef INLINE +#define INLINE __attribute__((always_inline)) +#endif + +#ifndef NOINLINE +#define NOINLINE __attribute__((noinline)) +#endif + +#ifndef NOINLINE_FUNC +#define NOINLINE_FUNC __attribute__((noinline)) +#endif + +#ifndef ALIGN +#define ALIGN(n) __attribute__((aligned(n))) +#endif + +#define CPU_SR_DECL ubase_t cpu_sr + +#ifdef __thumb__ +#define __SWITCH_TO_ARM__ +#pragma arm +#endif + +#if 0 +#define CPU_ENTER_CRITICAL() do{cpu_sr = util_enter_critical();}while(0) +#else +#define CPU_ENTER_CRITICAL() do{cpu_sr = __fast_enter_critical();}while(0) +static inline ubase_t __fast_enter_critical(void) +{ + ubase_t cpu_sr, tmp_sr; + __asm volatile { + MRS cpu_sr, CPSR + ORR tmp_sr, cpu_sr, #0xC0 + MSR CPSR_c, tmp_sr + } + return cpu_sr; +} +#endif + +#if 0 +#define CPU_EXIT_CRITICAL() do{util_exit_critical(cpu_sr);}while(0) +#else +#define CPU_EXIT_CRITICAL() do{__fast_exit_critical(cpu_sr);}while(0) +static inline void __fast_exit_critical(ubase_t cpu_sr) +{ + __asm volatile { + MSR CPSR_c, cpu_sr + } +} +#endif + +static inline unsigned CPU_CLZ16(uint16_t val) +{ + __asm volatile { + CLZ val, val + } + return (val - 16); +} + +static inline uint8_t __swap_byte(uint8_t newval, uint8_t volatile* pmem) +{ + uint8_t oldval; + __asm volatile { + SWPB oldval, newval, [pmem] + }; + return oldval; +} + +static inline uint32_t UTL_REV32(uint32_t val) +{ + uint32_t tmpval; + __asm volatile { + EOR tmpval, val, val, ROR #16 + MOV tmpval, tmpval, LSR #8 + BIC tmpval, tmpval, #0xFF00 + EOR val, tmpval, val, ROR #8 + } + return val; +} + +static inline uint16_t UTL_REV16(uint16_t val) +{ + uint32_t tmpval; + __asm volatile { + LSR tmpval, val, #8 + ORR val, tmpval, val, LSL #8 + BIC val, val, #0xFF0000 + } + return val; +} + +#ifdef __SWITCH_TO_ARM__ +#undef __SWITCH_TO_ARM__ +#pragma thumb +#endif + +#ifndef COUNTOF +#define COUNTOF(ar) (sizeof(ar)/sizeof(ar[0])) +#endif +/* +void util_halt(void); +void util_fastloop(ubase_t n); +ubase_t util_getCPSR(void); +ubase_t util_enter_critical(void); +void util_exit_critical(ubase_t sr); +void util_enable_interrupt(void); +void util_disable_interrupt(void); + +void target_wdt_setup(void); +void target_wdt_feed(void); +void target_reset(void); +*/ +//////////////////////////////////////////////////////////////////////////////// +#endif /* __TARGET_H__ */ + diff --git a/hw/mcu/allwinner/f1c100s/include/f1c100s/reg-ccu.h b/hw/mcu/allwinner/f1c100s/include/f1c100s/reg-ccu.h new file mode 100644 index 000000000..1770ad7ff --- /dev/null +++ b/hw/mcu/allwinner/f1c100s/include/f1c100s/reg-ccu.h @@ -0,0 +1,55 @@ +#ifndef __F1C100S_REG_CCU_H__ +#define __F1C100S_REG_CCU_H__ + +#define F1C100S_CCU_BASE (0x01c20000) + +#define CCU_PLL_CPU_CTRL (0x000) +#define CCU_PLL_AUDIO_CTRL (0x008) +#define CCU_PLL_VIDEO_CTRL (0x010) +#define CCU_PLL_VE_CTRL (0x018) +#define CCU_PLL_DDR_CTRL (0x020) +#define CCU_PLL_PERIPH_CTRL (0x028) +#define CCU_CPU_CFG (0x050) +#define CCU_AHB_APB_CFG (0x054) + +#define CCU_BUS_CLK_GATE0 (0x060) +#define CCU_BUS_CLK_GATE1 (0x064) +#define CCU_BUS_CLK_GATE2 (0x068) + +#define CCU_SDMMC0_CLK (0x088) +#define CCU_SDMMC1_CLK (0x08c) +#define CCU_DAUDIO_CLK (0x0b0) +#define CCU_SPDIF_CLK (0x0b4) +#define CCU_I2S_CLK (0x0b8) +#define CCU_USBPHY_CFG (0x0cc) +#define CCU_DRAM_CLK_GATE (0x100) +#define CCU_DEBE_CLK (0x104) +#define CCU_DEFE_CLK (0x10c) +#define CCU_LCD_CLK (0x118) +#define CCU_DEINTERLACE_CLK (0x11c) +#define CCU_TVE_CLK (0x120) +#define CCU_TVD_CLK (0x124) +#define CCU_CSI_CLK (0x134) +#define CCU_VE_CLK (0x13c) +#define CCU_ADDA_CLK (0x140) +#define CCU_AVS_CLK (0x144) + +#define CCU_PLL_STABLE_TIME0 (0x200) +#define CCU_PLL_STABLE_TIME1 (0x204) +#define CCU_PLL_CPU_BIAS (0x220) +#define CCU_PLL_AUDIO_BIAS (0x224) +#define CCU_PLL_VIDEO_BIAS (0x228) +#define CCU_PLL_VE_BIAS (0x22c) +#define CCU_PLL_DDR0_BIAS (0x230) +#define CCU_PLL_PERIPH_BIAS (0x234) +#define CCU_PLL_CPU_TUN (0x250) +#define CCU_PLL_DDR_TUN (0x260) +#define CCU_PLL_AUDIO_PAT (0x284) +#define CCU_PLL_VIDEO_PAT (0x288) +#define CCU_PLL_DDR0_PAT (0x290) + +#define CCU_BUS_SOFT_RST0 (0x2c0) +#define CCU_BUS_SOFT_RST1 (0x2c4) +#define CCU_BUS_SOFT_RST3 (0x2d0) + +#endif /* __F1C100S_REG_CCU_H__ */ diff --git a/hw/mcu/allwinner/f1c100s/include/f1c100s/reg-dram.h b/hw/mcu/allwinner/f1c100s/include/f1c100s/reg-dram.h new file mode 100644 index 000000000..8a0ac3e0e --- /dev/null +++ b/hw/mcu/allwinner/f1c100s/include/f1c100s/reg-dram.h @@ -0,0 +1,39 @@ +#ifndef __F1C100S_REG_DRAM_H__ +#define __F1C100S_REG_DRAM_H__ + +#define F1C100S_DRAM_BASE (0x01c01000) + +#define DRAM_SCONR (0x00) +#define DRAM_STMG0R (0x04) +#define DRAM_STMG1R (0x08) +#define DRAM_SCTLR (0x0c) +#define DRAM_SREFR (0x10) +#define DRAM_SEXTMR (0x14) +#define DRAM_DDLYR (0x24) +#define DRAM_DADRR (0x28) +#define DRAM_DVALR (0x2c) +#define DRAM_DRPTR0 (0x30) +#define DRAM_DRPTR1 (0x34) +#define DRAM_DRPTR2 (0x38) +#define DRAM_DRPTR3 (0x3c) +#define DRAM_SEFR (0x40) +#define DRAM_MAE (0x44) +#define DRAM_ASPR (0x48) +#define DRAM_SDLY0 (0x4C) +#define DRAM_SDLY1 (0x50) +#define DRAM_SDLY2 (0x54) +#define DRAM_MCR0 (0x100) +#define DRAM_MCR1 (0x104) +#define DRAM_MCR2 (0x108) +#define DRAM_MCR3 (0x10c) +#define DRAM_MCR4 (0x110) +#define DRAM_MCR5 (0x114) +#define DRAM_MCR6 (0x118) +#define DRAM_MCR7 (0x11c) +#define DRAM_MCR8 (0x120) +#define DRAM_MCR9 (0x124) +#define DRAM_MCR10 (0x128) +#define DRAM_MCR11 (0x12c) +#define DRAM_BWCR (0x140) + +#endif /* __F1C100S_REG_DRAM_H__ */ diff --git a/hw/mcu/allwinner/f1c100s/include/io.h b/hw/mcu/allwinner/f1c100s/include/io.h new file mode 100644 index 000000000..f0dad1785 --- /dev/null +++ b/hw/mcu/allwinner/f1c100s/include/io.h @@ -0,0 +1,57 @@ +#ifndef __IO_H__ +#define __IO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +static inline u8_t read8(virtual_addr_t addr) +{ + return( *((volatile u8_t *)(addr)) ); +} + +static inline u16_t read16(virtual_addr_t addr) +{ + return( *((volatile u16_t *)(addr)) ); +} + +static inline u32_t read32(virtual_addr_t addr) +{ + return( *((volatile u32_t *)(addr)) ); +} + +static inline u64_t read64(virtual_addr_t addr) +{ + return( *((volatile u64_t *)(addr)) ); +} + +static inline void write8(virtual_addr_t addr, u8_t value) +{ + *((volatile u8_t *)(addr)) = value; +} + +static inline void write16(virtual_addr_t addr, u16_t value) +{ + *((volatile u16_t *)(addr)) = value; +} + +static inline void write32(virtual_addr_t addr, u32_t value) +{ + *((volatile u32_t *)(addr)) = value; +} + +static inline void write64(virtual_addr_t addr, u64_t value) +{ + *((volatile u64_t *)(addr)) = value; +} + +virtual_addr_t phys_to_virt(physical_addr_t phys); +physical_addr_t virt_to_phys(virtual_addr_t virt); + +#ifdef __cplusplus +} +#endif + +#endif /* __IO_H__ */ diff --git a/hw/mcu/allwinner/f1c100s/include/irqflags.h b/hw/mcu/allwinner/f1c100s/include/irqflags.h new file mode 100644 index 000000000..e4ef97cd2 --- /dev/null +++ b/hw/mcu/allwinner/f1c100s/include/irqflags.h @@ -0,0 +1,104 @@ +#ifndef __ARM32_IRQFLAGS_H__ +#define __ARM32_IRQFLAGS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#if __ARM32_ARCH__ == 5 + +static inline void arch_local_irq_enable(void) +{ + irq_flags_t temp; + + __asm__ __volatile__( + "mrs %0, cpsr\n" + "bic %0, %0, #(1<<7)\n" + "msr cpsr_c, %0" + : "=r" (temp) + : + : "memory", "cc"); +} + +static inline void arch_local_irq_disable(void) +{ + irq_flags_t temp; + + __asm__ __volatile__( + "mrs %0, cpsr\n" + "orr %0, %0, #(1<<7)\n" + "msr cpsr_c, %0" + : "=r" (temp) + : + : "memory", "cc"); +} + +static inline irq_flags_t arch_local_irq_save(void) +{ + irq_flags_t flags, temp; + + __asm__ __volatile__( + "mrs %0, cpsr\n" + "orr %1, %0, #(1<<7)\n" + "msr cpsr_c, %1" + : "=r" (flags), "=r" (temp) + : + : "memory", "cc"); + + return flags; +} + +static inline void arch_local_irq_restore(irq_flags_t flags) +{ + __asm__ __volatile__( + "msr cpsr_c, %0" + : + : "r" (flags) + : "memory", "cc"); +} +#else +static inline void arch_local_irq_enable(void) +{ + __asm__ __volatile__("cpsie i" ::: "memory", "cc"); +} + +static inline void arch_local_irq_disable(void) +{ + __asm__ __volatile__("cpsid i" ::: "memory", "cc"); +} + +static inline irq_flags_t arch_local_irq_save(void) +{ + irq_flags_t flags; + + __asm__ __volatile__( + "mrs %0, cpsr\n" + "cpsid i" + : "=r" (flags) + : + : "memory", "cc"); + return flags; +} + +static inline void arch_local_irq_restore(irq_flags_t flags) +{ + __asm__ __volatile__( + "msr cpsr_c, %0" + : + : "r" (flags) + : "memory", "cc"); +} +#endif + +#define local_irq_enable() do { arch_local_irq_enable(); } while(0) +#define local_irq_disable() do { arch_local_irq_disable(); } while(0) +#define local_irq_save(flags) do { flags = arch_local_irq_save(); } while(0) +#define local_irq_restore(flags) do { arch_local_irq_restore(flags); } while(0) + +#ifdef __cplusplus +} +#endif + +#endif /* __ARM32_IRQFLAGS_H__ */ diff --git a/hw/mcu/allwinner/f1c100s/include/malloc.h b/hw/mcu/allwinner/f1c100s/include/malloc.h new file mode 100644 index 000000000..6669fe48c --- /dev/null +++ b/hw/mcu/allwinner/f1c100s/include/malloc.h @@ -0,0 +1,35 @@ +#ifndef __MALLOC_H__ +#define __MALLOC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +void * mm_create(void * mem, size_t bytes); +void mm_destroy(void * mm); +void * mm_get_pool(void * mm); +void * mm_add_pool(void * mm, void * mem, size_t bytes); +void mm_remove_pool(void * mm, void * pool); +void * mm_malloc(void * mm, size_t size); +void * mm_memalign(void * mm, size_t align, size_t size); +void * mm_realloc(void * mm, void * ptr, size_t size); +void mm_free(void * mm, void * ptr); + +void * malloc(size_t size); +void * memalign(size_t align, size_t size); +void * realloc(void * ptr, size_t size); +void * calloc(size_t nmemb, size_t size); +void free(void * ptr); + +void do_init_mem_pool(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __MALLOC_H__ */ diff --git a/hw/mcu/allwinner/f1c100s/include/printf.h b/hw/mcu/allwinner/f1c100s/include/printf.h new file mode 100644 index 000000000..632bfc20e --- /dev/null +++ b/hw/mcu/allwinner/f1c100s/include/printf.h @@ -0,0 +1,99 @@ +/////////////////////////////////////////////////////////////////////////////// +// \author (c) Marco Paland (info@paland.com) +// 2014-2018, PALANDesign Hannover, Germany +// +// \license The MIT License (MIT) +// +// 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. +// +// \brief Tiny printf, sprintf and snprintf implementation, optimized for speed on +// embedded systems with a very limited resources. +// Use this instead of bloated standard/newlib printf. +// These routines are thread safe and reentrant! +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _PRINTF_H_ +#define _PRINTF_H_ + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Output a character to a custom device like UART, used by the printf() function + * This function is declared here only. You have to write your custom implementation somewhere + * \param character Character to output + */ +void _putchar(char character); + + +/** + * Tiny printf implementation + * You have to implement _putchar if you use printf() + * \param format A string that specifies the format of the output + * \return The number of characters that are written into the array, not counting the terminating null character + */ +int printf(const char* format, ...); + + +/** + * Tiny sprintf implementation + * Due to security reasons (buffer overflow) YOU SHOULD CONSIDER USING (V)SNPRINTF INSTEAD! + * \param buffer A pointer to the buffer where to store the formatted string. MUST be big enough to store the output! + * \param format A string that specifies the format of the output + * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character + */ +int sprintf(char* buffer, const char* format, ...); + + +/** + * Tiny snprintf/vsnprintf implementation + * \param buffer A pointer to the buffer where to store the formatted string + * \param count The maximum number of characters to store in the buffer, including a terminating null character + * \param format A string that specifies the format of the output + * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character + * If the formatted string is truncated the buffer size (count) is returned + */ +int snprintf(char* buffer, size_t count, const char* format, ...); +int vsnprintf(char* buffer, size_t count, const char* format, va_list va); + + +/** + * printf with output function + * You may use this as dynamic alternative to printf() with its fixed _putchar() output + * \param out An output function which takes one character and an argument pointer + * \param arg An argument pointer for user data passed to output function + * \param format A string that specifies the format of the output + * \return The number of characters that are sent to the output function, not counting the terminating null character + */ +int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...); + + +#ifdef __cplusplus +} +#endif + + +#endif // _PRINTF_H_ diff --git a/hw/mcu/allwinner/f1c100s/include/sizes.h b/hw/mcu/allwinner/f1c100s/include/sizes.h new file mode 100644 index 000000000..3edeed503 --- /dev/null +++ b/hw/mcu/allwinner/f1c100s/include/sizes.h @@ -0,0 +1,42 @@ +#ifndef __SIZES_H__ +#define __SIZES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define SZ_16 (0x00000010) +#define SZ_256 (0x00000100) +#define SZ_512 (0x00000200) + +#define SZ_1K (0x00000400) +#define SZ_4K (0x00001000) +#define SZ_8K (0x00002000) +#define SZ_16K (0x00004000) +#define SZ_32K (0x00008000) +#define SZ_64K (0x00010000) +#define SZ_128K (0x00020000) +#define SZ_256K (0x00040000) +#define SZ_512K (0x00080000) + +#define SZ_1M (0x00100000) +#define SZ_2M (0x00200000) +#define SZ_4M (0x00400000) +#define SZ_8M (0x00800000) +#define SZ_16M (0x01000000) +#define SZ_32M (0x02000000) +#define SZ_64M (0x04000000) +#define SZ_128M (0x08000000) +#define SZ_256M (0x10000000) +#define SZ_512M (0x20000000) + +#define SZ_1G (0x40000000) +#define SZ_2G (0x80000000) + +#define ARRAY_SIZE(array) ( sizeof(array) / sizeof((array)[0]) ) + +#ifdef __cplusplus +} +#endif + +#endif /* __SIZES_H__ */ diff --git a/hw/mcu/allwinner/f1c100s/include/types.h b/hw/mcu/allwinner/f1c100s/include/types.h new file mode 100644 index 000000000..61b87b6d7 --- /dev/null +++ b/hw/mcu/allwinner/f1c100s/include/types.h @@ -0,0 +1,55 @@ +#ifndef __ARM32_TYPES_H__ +#define __ARM32_TYPES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef signed char s8_t; +typedef unsigned char u8_t; + +typedef signed short s16_t; +typedef unsigned short u16_t; + +typedef signed int s32_t; +typedef unsigned int u32_t; + +typedef signed long long s64_t; +typedef unsigned long long u64_t; + +typedef signed long long intmax_t; +typedef unsigned long long uintmax_t; + +typedef signed int ptrdiff_t; +typedef signed int intptr_t; +typedef unsigned int uintptr_t; + +typedef unsigned int size_t; +typedef signed int ssize_t; + +// typedef signed int off_t; +typedef signed long long loff_t; + +typedef signed int bool_t; + +typedef signed int register_t; +typedef unsigned int irq_flags_t; + +typedef unsigned int virtual_addr_t; +typedef unsigned int virtual_size_t; +typedef unsigned int physical_addr_t; +typedef unsigned int physical_size_t; + +typedef struct { + volatile long counter; +} atomic_t; + +typedef struct { + volatile long lock; +} spinlock_t; + +#ifdef __cplusplus +} +#endif + +#endif /* __ARM32_TYPES_H__ */ diff --git a/hw/mcu/allwinner/f1c100s/lib/malloc.c b/hw/mcu/allwinner/f1c100s/lib/malloc.c new file mode 100644 index 000000000..763746a47 --- /dev/null +++ b/hw/mcu/allwinner/f1c100s/lib/malloc.c @@ -0,0 +1,834 @@ +/* + * lib/libc/malloc/malloc.c + */ + +#include + +static void * __heap_pool = NULL; + +/* + * Some macros. + */ +#define tlsf_cast(t, exp) ((t)(exp)) +#define tlsf_min(a, b) ((a) < (b) ? (a) : (b)) +#define tlsf_max(a, b) ((a) > (b) ? (a) : (b)) + +#define tlsf_assert assert +#define tlsf_insist(x) { tlsf_assert(x); if (!(x)) { status--; } } + +#if defined(__ARM64__) || defined(__X64__) +# define TLSF_64BIT +#else +# undef TLSF_64BIT +#endif + +/* + * Public constants + */ +enum tlsf_public +{ + /* + * log2 of number of linear subdivisions of block sizes + */ + SL_INDEX_COUNT_LOG2 = 5, +}; + +/* + * Private constants + */ +enum tlsf_private +{ +#if defined(TLSF_64BIT) + /* + * All allocation sizes and addresses are aligned to 8 bytes + */ + ALIGN_SIZE_LOG2 = 3, +#else + /* + * All allocation sizes and addresses are aligned to 4 bytes + */ + ALIGN_SIZE_LOG2 = 2, +#endif + ALIGN_SIZE = (1 << ALIGN_SIZE_LOG2), + +#if defined(TLSF_64BIT) + FL_INDEX_MAX = 32, +#else + FL_INDEX_MAX = 30, +#endif + SL_INDEX_COUNT = (1 << SL_INDEX_COUNT_LOG2), + FL_INDEX_SHIFT = (SL_INDEX_COUNT_LOG2 + ALIGN_SIZE_LOG2), + FL_INDEX_COUNT = (FL_INDEX_MAX - FL_INDEX_SHIFT + 1), + + SMALL_BLOCK_SIZE = (1 << FL_INDEX_SHIFT), +}; + +/* + * Block header structure + */ +typedef struct block_header_t +{ + /* + * Points to the previous physical block + */ + struct block_header_t * prev_phys_block; + + /* + * The size of this block, excluding the block header + */ + size_t size; + + /* + * Next and previous free blocks + */ + struct block_header_t * next_free; + struct block_header_t * prev_free; +} block_header_t; + +/* + * The TLSF control structure. + */ +typedef struct control_t +{ + /* + * Empty lists point at this block to indicate they are free. + */ + block_header_t block_null; + + /* + * Bitmaps for free lists. + */ + unsigned int fl_bitmap; + unsigned int sl_bitmap[FL_INDEX_COUNT]; + + /* + * Head of free lists. + */ + block_header_t * blocks[FL_INDEX_COUNT][SL_INDEX_COUNT]; +} control_t; + +/* + * A type used for casting when doing pointer arithmetic. + */ +typedef ptrdiff_t tlsfptr_t; + +/* + * Associated constants + */ +static const size_t block_header_free_bit = 1 << 0; +static const size_t block_header_prev_free_bit = 1 << 1; +static const size_t block_header_overhead = sizeof(size_t); +static const size_t block_start_offset = offsetof(block_header_t, size) + sizeof(size_t); +static const size_t block_size_min = sizeof(block_header_t) - sizeof(block_header_t *); +static const size_t block_size_max = tlsf_cast(size_t, 1) << FL_INDEX_MAX; + +#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) && defined(__GNUC_PATCHLEVEL__) +static int tlsf_ffs(unsigned int word) +{ + return __builtin_ffs(word) - 1; +} + +static int tlsf_fls(unsigned int word) +{ + const int bit = word ? 32 - __builtin_clz(word) : 0; + return bit - 1; +} +#else +static int tlsf_fls_generic(unsigned int word) +{ + int bit = 32; + + if (!word) bit -= 1; + if (!(word & 0xffff0000)) { word <<= 16; bit -= 16; } + if (!(word & 0xff000000)) { word <<= 8; bit -= 8; } + if (!(word & 0xf0000000)) { word <<= 4; bit -= 4; } + if (!(word & 0xc0000000)) { word <<= 2; bit -= 2; } + if (!(word & 0x80000000)) { word <<= 1; bit -= 1; } + + return bit; +} + +static int tlsf_ffs(unsigned int word) +{ + return tlsf_fls_generic(word & (~word + 1)) - 1; +} + +static int tlsf_fls(unsigned int word) +{ + return tlsf_fls_generic(word) - 1; +} +#endif + +#if defined(TLSF_64BIT) +static int tlsf_fls_sizet(size_t size) +{ + int high = (int)(size >> 32); + int bits = 0; + if(high) + { + bits = 32 + tlsf_fls(high); + } + else + { + bits = tlsf_fls((int)size & 0xffffffff); + + } + return bits; +} +#else +#define tlsf_fls_sizet tlsf_fls +#endif + +static size_t block_get_size(const block_header_t * block) +{ + return block->size & ~(block_header_free_bit | block_header_prev_free_bit); +} + +static void block_set_size(block_header_t * block, size_t size) +{ + const size_t oldsize = block->size; + block->size = size | (oldsize & (block_header_free_bit | block_header_prev_free_bit)); +} + +static int block_is_last(const block_header_t * block) +{ + return (0 == block_get_size(block)); +} + +static int block_is_free(const block_header_t * block) +{ + return tlsf_cast(int, block->size & block_header_free_bit); +} + +static void block_set_free(block_header_t * block) +{ + block->size |= block_header_free_bit; +} + +static void block_set_used(block_header_t * block) +{ + block->size &= ~block_header_free_bit; +} + +static int block_is_prev_free(const block_header_t * block) +{ + return tlsf_cast(int, block->size & block_header_prev_free_bit); +} + +static void block_set_prev_free(block_header_t * block) +{ + block->size |= block_header_prev_free_bit; +} + +static void block_set_prev_used(block_header_t * block) +{ + block->size &= ~block_header_prev_free_bit; +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-align" +static block_header_t * block_from_ptr(void * ptr) +{ + return tlsf_cast(block_header_t *, tlsf_cast(unsigned char*, ptr) - block_start_offset); +} +#pragma GCC diagnostic pop + +static void * block_to_ptr(block_header_t * block) +{ + return tlsf_cast(void *, tlsf_cast(unsigned char*, block) + block_start_offset); +} + +static block_header_t * offset_to_block(void * ptr, size_t size) +{ + return tlsf_cast(block_header_t *, tlsf_cast(tlsfptr_t, ptr) + size); +} + +static block_header_t * block_prev(block_header_t * block) +{ + return block->prev_phys_block; +} + +static block_header_t * block_next(block_header_t * block) +{ + block_header_t * next = offset_to_block(block_to_ptr(block), block_get_size(block) - block_header_overhead); + tlsf_assert(!block_is_last(block)); + return next; +} + +static block_header_t * block_link_next(block_header_t * block) +{ + block_header_t * next = block_next(block); + next->prev_phys_block = block; + return next; +} + +static void block_mark_as_free(block_header_t * block) +{ + block_header_t * next = block_link_next(block); + block_set_prev_free(next); + block_set_free(block); +} + +static void block_mark_as_used(block_header_t * block) +{ + block_header_t * next = block_next(block); + block_set_prev_used(next); + block_set_used(block); +} + +static size_t align_up(size_t x, size_t align) +{ + tlsf_assert(0 == (align & (align - 1)) && "must align to a power of two"); + return (x + (align - 1)) & ~(align - 1); +} + +static size_t align_down(size_t x, size_t align) +{ + tlsf_assert(0 == (align & (align - 1)) && "must align to a power of two"); + return x - (x & (align - 1)); +} + +static void * align_ptr(const void * ptr, size_t align) +{ + const tlsfptr_t aligned = (tlsf_cast(tlsfptr_t, ptr) + (align - 1)) & ~(align - 1); + tlsf_assert(0 == (align & (align - 1)) && "must align to a power of two"); + return tlsf_cast(void*, aligned); +} + +static size_t adjust_request_size(size_t size, size_t align) +{ + size_t adjust = 0; + if (size && size < block_size_max) + { + const size_t aligned = align_up(size, align); + adjust = tlsf_max(aligned, block_size_min); + } + return adjust; +} + +static void mapping_insert(size_t size, int * fli, int * sli) +{ + int fl, sl; + if (size < SMALL_BLOCK_SIZE) + { + fl = 0; + sl = tlsf_cast(int, size) / (SMALL_BLOCK_SIZE / SL_INDEX_COUNT); + } + else + { + fl = tlsf_fls_sizet(size); + sl = tlsf_cast(int, size >> (fl - SL_INDEX_COUNT_LOG2)) ^ (1 << SL_INDEX_COUNT_LOG2); + fl -= (FL_INDEX_SHIFT - 1); + } + *fli = fl; + *sli = sl; +} + +static void mapping_search(size_t size, int * fli, int * sli) +{ + if (size >= (1 << SL_INDEX_COUNT_LOG2)) + { + const size_t round = (1 << (tlsf_fls_sizet(size) - SL_INDEX_COUNT_LOG2)) - 1; + size += round; + } + mapping_insert(size, fli, sli); +} + +static block_header_t * search_suitable_block(control_t * control, int * fli, int * sli) +{ + int fl = *fli; + int sl = *sli; + + unsigned int sl_map = control->sl_bitmap[fl] & (~0U << sl); + if (!sl_map) + { + const unsigned int fl_map = control->fl_bitmap & (~0U << (fl + 1)); + if (!fl_map) + { + return 0; + } + + fl = tlsf_ffs(fl_map); + *fli = fl; + sl_map = control->sl_bitmap[fl]; + } + tlsf_assert(sl_map && "internal error - second level bitmap is null"); + sl = tlsf_ffs(sl_map); + *sli = sl; + + return control->blocks[fl][sl]; +} + +static void remove_free_block(control_t * control, block_header_t * block, int fl, int sl) +{ + block_header_t * prev = block->prev_free; + block_header_t * next = block->next_free; + tlsf_assert(prev && "prev_free field can not be null"); + tlsf_assert(next && "next_free field can not be null"); + next->prev_free = prev; + prev->next_free = next; + + if (control->blocks[fl][sl] == block) + { + control->blocks[fl][sl] = next; + + if (next == &control->block_null) + { + control->sl_bitmap[fl] &= ~(1 << sl); + + if (!control->sl_bitmap[fl]) + { + control->fl_bitmap &= ~(1 << fl); + } + } + } +} + +static void insert_free_block(control_t * control, block_header_t * block, int fl, int sl) +{ + block_header_t * current = control->blocks[fl][sl]; + tlsf_assert(current && "free list cannot have a null entry"); + tlsf_assert(block && "cannot insert a null entry into the free list"); + block->next_free = current; + block->prev_free = &control->block_null; + current->prev_free = block; + + tlsf_assert(block_to_ptr(block) == align_ptr(block_to_ptr(block), ALIGN_SIZE) && "block not aligned properly"); + + control->blocks[fl][sl] = block; + control->fl_bitmap |= (1 << fl); + control->sl_bitmap[fl] |= (1 << sl); +} + +static void block_remove(control_t * control, block_header_t * block) +{ + int fl, sl; + mapping_insert(block_get_size(block), &fl, &sl); + remove_free_block(control, block, fl, sl); +} + +static void block_insert(control_t * control, block_header_t * block) +{ + int fl, sl; + mapping_insert(block_get_size(block), &fl, &sl); + insert_free_block(control, block, fl, sl); +} + +static int block_can_split(block_header_t * block, size_t size) +{ + return block_get_size(block) >= sizeof(block_header_t) + size; +} + +static block_header_t * block_split(block_header_t * block, size_t size) +{ + block_header_t* remaining = offset_to_block(block_to_ptr(block), size - block_header_overhead); + const size_t remain_size = block_get_size(block) - (size + block_header_overhead); + + tlsf_assert(block_to_ptr(remaining) == align_ptr(block_to_ptr(remaining), ALIGN_SIZE) && "remaining block not aligned properly"); + + tlsf_assert(block_get_size(block) == remain_size + size + block_header_overhead); + block_set_size(remaining, remain_size); + tlsf_assert(block_get_size(remaining) >= block_size_min && "block split with invalid size"); + + block_set_size(block, size); + block_mark_as_free(remaining); + + return remaining; +} + +static block_header_t * block_absorb(block_header_t * prev, block_header_t * block) +{ + tlsf_assert(!block_is_last(prev) && "previous block can't be last!"); + prev->size += block_get_size(block) + block_header_overhead; + block_link_next(prev); + return prev; +} + +static block_header_t * block_merge_prev(control_t * control, block_header_t * block) +{ + if (block_is_prev_free(block)) + { + block_header_t* prev = block_prev(block); + tlsf_assert(prev && "prev physical block can't be null"); + tlsf_assert(block_is_free(prev) && "prev block is not free though marked as such"); + block_remove(control, prev); + block = block_absorb(prev, block); + } + + return block; +} + +static block_header_t * block_merge_next(control_t * control, block_header_t * block) +{ + block_header_t* next = block_next(block); + tlsf_assert(next && "next physical block can't be null"); + + if (block_is_free(next)) + { + tlsf_assert(!block_is_last(block) && "previous block can't be last!"); + block_remove(control, next); + block = block_absorb(block, next); + } + + return block; +} + +static void block_trim_free(control_t * control, block_header_t * block, size_t size) +{ + tlsf_assert(block_is_free(block) && "block must be free"); + if (block_can_split(block, size)) + { + block_header_t* remaining_block = block_split(block, size); + block_link_next(block); + block_set_prev_free(remaining_block); + block_insert(control, remaining_block); + } +} + +static void block_trim_used(control_t * control, block_header_t * block, size_t size) +{ + tlsf_assert(!block_is_free(block) && "block must be used"); + if (block_can_split(block, size)) + { + block_header_t* remaining_block = block_split(block, size); + block_set_prev_used(remaining_block); + + remaining_block = block_merge_next(control, remaining_block); + block_insert(control, remaining_block); + } +} + +static block_header_t * block_trim_free_leading(control_t * control, block_header_t * block, size_t size) +{ + block_header_t * remaining_block = block; + if (block_can_split(block, size)) + { + remaining_block = block_split(block, size - block_header_overhead); + block_set_prev_free(remaining_block); + + block_link_next(block); + block_insert(control, block); + } + + return remaining_block; +} + +static block_header_t * block_locate_free(control_t * control, size_t size) +{ + int fl = 0, sl = 0; + block_header_t * block = 0; + + if (size) + { + mapping_search(size, &fl, &sl); + block = search_suitable_block(control, &fl, &sl); + } + + if (block) + { + tlsf_assert(block_get_size(block) >= size); + remove_free_block(control, block, fl, sl); + } + + return block; +} + +static void * block_prepare_used(control_t * control, block_header_t * block, size_t size) +{ + void* p = 0; + if (block) + { + block_trim_free(control, block, size); + block_mark_as_used(block); + p = block_to_ptr(block); + } + return p; +} + +static void control_construct(control_t * control) +{ + int i, j; + + control->block_null.next_free = &control->block_null; + control->block_null.prev_free = &control->block_null; + + control->fl_bitmap = 0; + for (i = 0; i < FL_INDEX_COUNT; ++i) + { + control->sl_bitmap[i] = 0; + for (j = 0; j < SL_INDEX_COUNT; ++j) + { + control->blocks[i][j] = &control->block_null; + } + } +} + +static inline void * tlsf_add_pool(void * tlsf, void * mem, size_t bytes) +{ + block_header_t * block; + block_header_t * next; + const size_t pool_overhead = 2 * block_header_overhead; + const size_t pool_bytes = align_down(bytes - pool_overhead, ALIGN_SIZE); + + if (((ptrdiff_t)mem % ALIGN_SIZE) != 0) + return 0; + + if (pool_bytes < block_size_min || pool_bytes > block_size_max) + return 0; + + block = offset_to_block(mem, -(tlsfptr_t)block_header_overhead); + block_set_size(block, pool_bytes); + block_set_free(block); + block_set_prev_used(block); + block_insert(tlsf_cast(control_t*, tlsf), block); + + next = block_link_next(block); + block_set_size(next, 0); + block_set_used(next); + block_set_prev_free(next); + + return mem; +} + +static inline void tlsf_remove_pool(void * tlsf, void * pool) +{ + control_t * control = tlsf_cast(control_t *, tlsf); + block_header_t * block = offset_to_block(pool, -(int)block_header_overhead); + int fl = 0, sl = 0; + + tlsf_assert(block_is_free(block) && "block should be free"); + tlsf_assert(!block_is_free(block_next(block)) && "next block should not be free"); + tlsf_assert(block_get_size(block_next(block)) == 0 && "next block size should be zero"); + + mapping_insert(block_get_size(block), &fl, &sl); + remove_free_block(control, block, fl, sl); +} + +static inline void * tlsf_create(void * mem) +{ + if (((tlsfptr_t)mem % ALIGN_SIZE) != 0) + return 0; + + control_construct(tlsf_cast(control_t *, mem)); + return tlsf_cast(void *, mem); +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Warray-bounds" +static inline void * tlsf_create_with_pool(void * mem, size_t bytes) +{ + void * tlsf = tlsf_create(mem); + tlsf_add_pool(tlsf, (char *)mem + sizeof(control_t), bytes - sizeof(control_t)); + return tlsf; +} +#pragma GCC diagnostic pop + + +static inline void tlsf_destroy(void * tlsf) +{ + (void)tlsf; +} + +static inline void * tlsf_get_pool(void * tlsf) +{ + return tlsf_cast(void *, (char *)tlsf + sizeof(control_t)); +} + +static inline void * tlsf_malloc(void * tlsf, size_t size) +{ + control_t * control = tlsf_cast(control_t *, tlsf); + const size_t adjust = adjust_request_size(size, ALIGN_SIZE); + block_header_t * block = block_locate_free(control, adjust); + return block_prepare_used(control, block, adjust); +} + +static inline void * tlsf_memalign(void * tlsf, size_t align, size_t size) +{ + control_t * control = tlsf_cast(control_t *, tlsf); + const size_t adjust = adjust_request_size(size, ALIGN_SIZE); + + const size_t gap_minimum = sizeof(block_header_t); + const size_t size_with_gap = adjust_request_size(adjust + align + gap_minimum, align); + + const size_t aligned_size = (align <= ALIGN_SIZE) ? adjust : size_with_gap; + + block_header_t* block = block_locate_free(control, aligned_size); + + tlsf_assert(sizeof(block_header_t) == block_size_min + block_header_overhead); + + if (block) + { + void * ptr = block_to_ptr(block); + void * aligned = align_ptr(ptr, align); + size_t gap = tlsf_cast(size_t, tlsf_cast(tlsfptr_t, aligned) - tlsf_cast(tlsfptr_t, ptr)); + + if (gap && gap < gap_minimum) + { + const size_t gap_remain = gap_minimum - gap; + const size_t offset = tlsf_max(gap_remain, align); + const void * next_aligned = tlsf_cast(void *, tlsf_cast(tlsfptr_t, aligned) + offset); + + aligned = align_ptr(next_aligned, align); + gap = tlsf_cast(size_t, tlsf_cast(tlsfptr_t, aligned) - tlsf_cast(tlsfptr_t, ptr)); + } + + if (gap) + { + tlsf_assert(gap >= gap_minimum && "gap size too small"); + block = block_trim_free_leading(control, block, gap); + } + } + + return block_prepare_used(control, block, adjust); +} + +static inline void tlsf_free(void * tlsf, void * ptr) +{ + if (ptr) + { + control_t * control = tlsf_cast(control_t *, tlsf); + block_header_t * block = block_from_ptr(ptr); + tlsf_assert(!block_is_free(block) && "block already marked as free"); + block_mark_as_free(block); + block = block_merge_prev(control, block); + block = block_merge_next(control, block); + block_insert(control, block); + } +} + +static inline void * tlsf_realloc(void * tlsf, void * ptr, size_t size) +{ + control_t * control = tlsf_cast(control_t *, tlsf); + void * p = 0; + + if (ptr && size == 0) + { + tlsf_free(tlsf, ptr); + } + else if (!ptr) + { + p = tlsf_malloc(tlsf, size); + } + else + { + block_header_t * block = block_from_ptr(ptr); + block_header_t * next = block_next(block); + + const size_t cursize = block_get_size(block); + const size_t combined = cursize + block_get_size(next) + block_header_overhead; + const size_t adjust = adjust_request_size(size, ALIGN_SIZE); + + tlsf_assert(!block_is_free(block) && "block already marked as free"); + + if (adjust > cursize && (!block_is_free(next) || adjust > combined)) + { + p = tlsf_malloc(tlsf, size); + if (p) + { + const size_t minsize = tlsf_min(cursize, size); + memcpy(p, ptr, minsize); + tlsf_free(tlsf, ptr); + } + } + else + { + if (adjust > cursize) + { + block_merge_next(control, block); + block_mark_as_used(block); + } + + block_trim_used(control, block, adjust); + p = ptr; + } + } + + return p; +} + +void * mm_create(void * mem, size_t bytes) +{ + return tlsf_create_with_pool(mem, bytes); +} + +void mm_destroy(void * mm) +{ + tlsf_destroy(mm); +} + +void * mm_get_pool(void * mm) +{ + return tlsf_get_pool(mm); +} + +void * mm_add_pool(void * mm, void * mem, size_t bytes) +{ + return tlsf_add_pool(mm, mem, bytes); +} + +void mm_remove_pool(void * mm, void * pool) +{ + tlsf_remove_pool(mm, pool); +} + +void * mm_malloc(void * mm, size_t size) +{ + return tlsf_malloc(mm, size); +} + +void * mm_memalign(void * mm, size_t align, size_t size) +{ + return tlsf_memalign(mm, align, size); +} + +void * mm_realloc(void * mm, void * ptr, size_t size) +{ + return tlsf_realloc(mm, ptr, size); +} + +void mm_free(void * mm, void * ptr) +{ + tlsf_free(mm, ptr); +} + +void * malloc(size_t size) +{ + return tlsf_malloc(__heap_pool, size); +} + +void * memalign(size_t align, size_t size) +{ + return tlsf_memalign(__heap_pool, align, size); +} + +void * realloc(void * ptr, size_t size) +{ + return tlsf_realloc(__heap_pool, ptr, size); +} + +void * calloc(size_t nmemb, size_t size) +{ + void * ptr; + + if((ptr = malloc(nmemb * size))) + memset(ptr, 0, nmemb * size); + + return ptr; +} + +void free(void * ptr) +{ + tlsf_free(__heap_pool, ptr); +} + +void do_init_mem_pool(void) +{ +#ifndef __SANDBOX__ + extern unsigned char __heap_start; + extern unsigned char __heap_end; + __heap_pool = tlsf_create_with_pool((void *)&__heap_start, (size_t)(&__heap_end - &__heap_start)); +#else + static char __heap_buf[SZ_16M]; + __heap_pool = tlsf_create_with_pool((void *)__heap_buf, (size_t)(sizeof(__heap_buf))); +#endif +} diff --git a/hw/mcu/allwinner/f1c100s/lib/memcpy.S b/hw/mcu/allwinner/f1c100s/lib/memcpy.S new file mode 100644 index 000000000..f7ed3130c --- /dev/null +++ b/hw/mcu/allwinner/f1c100s/lib/memcpy.S @@ -0,0 +1,404 @@ +/* + * memcpy.S + */ + .text + + .global memcpy + .type memcpy, %function + .align 4 + +memcpy: + /* determine copy direction */ + cmp r1, r0 + bcc .Lmemcpy_backwards + + moveq r0, #0 /* quick abort for len=0 */ + moveq pc, lr + + stmdb sp!, {r0, lr} /* memcpy() returns dest addr */ + subs r2, r2, #4 + blt .Lmemcpy_fl4 /* less than 4 bytes */ + ands r12, r0, #3 + bne .Lmemcpy_fdestul /* oh unaligned destination addr */ + ands r12, r1, #3 + bne .Lmemcpy_fsrcul /* oh unaligned source addr */ + +.Lmemcpy_ft8: + /* we have aligned source and destination */ + subs r2, r2, #8 + blt .Lmemcpy_fl12 /* less than 12 bytes (4 from above) */ + subs r2, r2, #0x14 + blt .Lmemcpy_fl32 /* less than 32 bytes (12 from above) */ + stmdb sp!, {r4} /* borrow r4 */ + + /* blat 32 bytes at a time */ +.Lmemcpy_floop32: + ldmia r1!, {r3, r4, r12, lr} + stmia r0!, {r3, r4, r12, lr} + ldmia r1!, {r3, r4, r12, lr} + stmia r0!, {r3, r4, r12, lr} + subs r2, r2, #0x20 + bge .Lmemcpy_floop32 + + cmn r2, #0x10 + ldmgeia r1!, {r3, r4, r12, lr} /* blat a remaining 16 bytes */ + stmgeia r0!, {r3, r4, r12, lr} + subge r2, r2, #0x10 + ldmia sp!, {r4} /* return r4 */ + +.Lmemcpy_fl32: + adds r2, r2, #0x14 + + /* blat 12 bytes at a time */ +.Lmemcpy_floop12: + ldmgeia r1!, {r3, r12, lr} + stmgeia r0!, {r3, r12, lr} + subges r2, r2, #0x0c + bge .Lmemcpy_floop12 + +.Lmemcpy_fl12: + adds r2, r2, #8 + blt .Lmemcpy_fl4 + + subs r2, r2, #4 + ldrlt r3, [r1], #4 + strlt r3, [r0], #4 + ldmgeia r1!, {r3, r12} + stmgeia r0!, {r3, r12} + subge r2, r2, #4 + +.Lmemcpy_fl4: + /* less than 4 bytes to go */ + adds r2, r2, #4 + ldmeqia sp!, {r0, pc} /* done */ + + /* copy the crud byte at a time */ + cmp r2, #2 + ldrb r3, [r1], #1 + strb r3, [r0], #1 + ldrgeb r3, [r1], #1 + strgeb r3, [r0], #1 + ldrgtb r3, [r1], #1 + strgtb r3, [r0], #1 + ldmia sp!, {r0, pc} + + /* erg - unaligned destination */ +.Lmemcpy_fdestul: + rsb r12, r12, #4 + cmp r12, #2 + + /* align destination with byte copies */ + ldrb r3, [r1], #1 + strb r3, [r0], #1 + ldrgeb r3, [r1], #1 + strgeb r3, [r0], #1 + ldrgtb r3, [r1], #1 + strgtb r3, [r0], #1 + subs r2, r2, r12 + blt .Lmemcpy_fl4 /* less the 4 bytes */ + + ands r12, r1, #3 + beq .Lmemcpy_ft8 /* we have an aligned source */ + + /* erg - unaligned source */ + /* This is where it gets nasty ... */ +.Lmemcpy_fsrcul: + bic r1, r1, #3 + ldr lr, [r1], #4 + cmp r12, #2 + bgt .Lmemcpy_fsrcul3 + beq .Lmemcpy_fsrcul2 + cmp r2, #0x0c + blt .Lmemcpy_fsrcul1loop4 + sub r2, r2, #0x0c + stmdb sp!, {r4, r5} + +.Lmemcpy_fsrcul1loop16: + mov r3, lr, lsr #8 + ldmia r1!, {r4, r5, r12, lr} + orr r3, r3, r4, lsl #24 + mov r4, r4, lsr #8 + orr r4, r4, r5, lsl #24 + mov r5, r5, lsr #8 + orr r5, r5, r12, lsl #24 + mov r12, r12, lsr #8 + orr r12, r12, lr, lsl #24 + stmia r0!, {r3-r5, r12} + subs r2, r2, #0x10 + bge .Lmemcpy_fsrcul1loop16 + ldmia sp!, {r4, r5} + adds r2, r2, #0x0c + blt .Lmemcpy_fsrcul1l4 + +.Lmemcpy_fsrcul1loop4: + mov r12, lr, lsr #8 + ldr lr, [r1], #4 + orr r12, r12, lr, lsl #24 + str r12, [r0], #4 + subs r2, r2, #4 + bge .Lmemcpy_fsrcul1loop4 + +.Lmemcpy_fsrcul1l4: + sub r1, r1, #3 + b .Lmemcpy_fl4 + +.Lmemcpy_fsrcul2: + cmp r2, #0x0c + blt .Lmemcpy_fsrcul2loop4 + sub r2, r2, #0x0c + stmdb sp!, {r4, r5} + +.Lmemcpy_fsrcul2loop16: + mov r3, lr, lsr #16 + ldmia r1!, {r4, r5, r12, lr} + orr r3, r3, r4, lsl #16 + mov r4, r4, lsr #16 + orr r4, r4, r5, lsl #16 + mov r5, r5, lsr #16 + orr r5, r5, r12, lsl #16 + mov r12, r12, lsr #16 + orr r12, r12, lr, lsl #16 + stmia r0!, {r3-r5, r12} + subs r2, r2, #0x10 + bge .Lmemcpy_fsrcul2loop16 + ldmia sp!, {r4, r5} + adds r2, r2, #0x0c + blt .Lmemcpy_fsrcul2l4 + +.Lmemcpy_fsrcul2loop4: + mov r12, lr, lsr #16 + ldr lr, [r1], #4 + orr r12, r12, lr, lsl #16 + str r12, [r0], #4 + subs r2, r2, #4 + bge .Lmemcpy_fsrcul2loop4 + +.Lmemcpy_fsrcul2l4: + sub r1, r1, #2 + b .Lmemcpy_fl4 + +.Lmemcpy_fsrcul3: + cmp r2, #0x0c + blt .Lmemcpy_fsrcul3loop4 + sub r2, r2, #0x0c + stmdb sp!, {r4, r5} + +.Lmemcpy_fsrcul3loop16: + mov r3, lr, lsr #24 + ldmia r1!, {r4, r5, r12, lr} + orr r3, r3, r4, lsl #8 + mov r4, r4, lsr #24 + orr r4, r4, r5, lsl #8 + mov r5, r5, lsr #24 + orr r5, r5, r12, lsl #8 + mov r12, r12, lsr #24 + orr r12, r12, lr, lsl #8 + stmia r0!, {r3-r5, r12} + subs r2, r2, #0x10 + bge .Lmemcpy_fsrcul3loop16 + ldmia sp!, {r4, r5} + adds r2, r2, #0x0c + blt .Lmemcpy_fsrcul3l4 + +.Lmemcpy_fsrcul3loop4: + mov r12, lr, lsr #24 + ldr lr, [r1], #4 + orr r12, r12, lr, lsl #8 + str r12, [r0], #4 + subs r2, r2, #4 + bge .Lmemcpy_fsrcul3loop4 + +.Lmemcpy_fsrcul3l4: + sub r1, r1, #1 + b .Lmemcpy_fl4 + +.Lmemcpy_backwards: + add r1, r1, r2 + add r0, r0, r2 + subs r2, r2, #4 + blt .Lmemcpy_bl4 /* less than 4 bytes */ + ands r12, r0, #3 + bne .Lmemcpy_bdestul /* oh unaligned destination addr */ + ands r12, r1, #3 + bne .Lmemcpy_bsrcul /* oh unaligned source addr */ + +.Lmemcpy_bt8: + /* we have aligned source and destination */ + subs r2, r2, #8 + blt .Lmemcpy_bl12 /* less than 12 bytes (4 from above) */ + stmdb sp!, {r4, lr} + subs r2, r2, #0x14 /* less than 32 bytes (12 from above) */ + blt .Lmemcpy_bl32 + + /* blat 32 bytes at a time */ +.Lmemcpy_bloop32: + ldmdb r1!, {r3, r4, r12, lr} + stmdb r0!, {r3, r4, r12, lr} + ldmdb r1!, {r3, r4, r12, lr} + stmdb r0!, {r3, r4, r12, lr} + subs r2, r2, #0x20 + bge .Lmemcpy_bloop32 + +.Lmemcpy_bl32: + cmn r2, #0x10 + ldmgedb r1!, {r3, r4, r12, lr} /* blat a remaining 16 bytes */ + stmgedb r0!, {r3, r4, r12, lr} + subge r2, r2, #0x10 + adds r2, r2, #0x14 + ldmgedb r1!, {r3, r12, lr} /* blat a remaining 12 bytes */ + stmgedb r0!, {r3, r12, lr} + subge r2, r2, #0x0c + ldmia sp!, {r4, lr} + +.Lmemcpy_bl12: + adds r2, r2, #8 + blt .Lmemcpy_bl4 + subs r2, r2, #4 + ldrlt r3, [r1, #-4]! + strlt r3, [r0, #-4]! + ldmgedb r1!, {r3, r12} + stmgedb r0!, {r3, r12} + subge r2, r2, #4 + +.Lmemcpy_bl4: + /* less than 4 bytes to go */ + adds r2, r2, #4 + moveq pc, lr + + /* copy the crud byte at a time */ + cmp r2, #2 + ldrb r3, [r1, #-1]! + strb r3, [r0, #-1]! + ldrgeb r3, [r1, #-1]! + strgeb r3, [r0, #-1]! + ldrgtb r3, [r1, #-1]! + strgtb r3, [r0, #-1]! + mov pc, lr + + /* erg - unaligned destination */ +.Lmemcpy_bdestul: + cmp r12, #2 + + /* align destination with byte copies */ + ldrb r3, [r1, #-1]! + strb r3, [r0, #-1]! + ldrgeb r3, [r1, #-1]! + strgeb r3, [r0, #-1]! + ldrgtb r3, [r1, #-1]! + strgtb r3, [r0, #-1]! + subs r2, r2, r12 + blt .Lmemcpy_bl4 /* less than 4 bytes to go */ + ands r12, r1, #3 + beq .Lmemcpy_bt8 /* we have an aligned source */ + + /* erg - unaligned source */ + /* This is where it gets nasty ... */ +.Lmemcpy_bsrcul: + bic r1, r1, #3 + ldr r3, [r1, #0] + cmp r12, #2 + blt .Lmemcpy_bsrcul1 + beq .Lmemcpy_bsrcul2 + cmp r2, #0x0c + blt .Lmemcpy_bsrcul3loop4 + sub r2, r2, #0x0c + stmdb sp!, {r4, r5, lr} + +.Lmemcpy_bsrcul3loop16: + mov lr, r3, lsl #8 + ldmdb r1!, {r3-r5, r12} + orr lr, lr, r12, lsr #24 + mov r12, r12, lsl #8 + orr r12, r12, r5, lsr #24 + mov r5, r5, lsl #8 + orr r5, r5, r4, lsr #24 + mov r4, r4, lsl #8 + orr r4, r4, r3, lsr #24 + stmdb r0!, {r4, r5, r12, lr} + subs r2, r2, #0x10 + bge .Lmemcpy_bsrcul3loop16 + ldmia sp!, {r4, r5, lr} + adds r2, r2, #0x0c + blt .Lmemcpy_bsrcul3l4 + +.Lmemcpy_bsrcul3loop4: + mov r12, r3, lsl #8 + ldr r3, [r1, #-4]! + orr r12, r12, r3, lsr #24 + str r12, [r0, #-4]! + subs r2, r2, #4 + bge .Lmemcpy_bsrcul3loop4 + +.Lmemcpy_bsrcul3l4: + add r1, r1, #3 + b .Lmemcpy_bl4 + +.Lmemcpy_bsrcul2: + cmp r2, #0x0c + blt .Lmemcpy_bsrcul2loop4 + sub r2, r2, #0x0c + stmdb sp!, {r4, r5, lr} + +.Lmemcpy_bsrcul2loop16: + mov lr, r3, lsl #16 + ldmdb r1!, {r3-r5, r12} + orr lr, lr, r12, lsr #16 + mov r12, r12, lsl #16 + orr r12, r12, r5, lsr #16 + mov r5, r5, lsl #16 + orr r5, r5, r4, lsr #16 + mov r4, r4, lsl #16 + orr r4, r4, r3, lsr #16 + stmdb r0!, {r4, r5, r12, lr} + subs r2, r2, #0x10 + bge .Lmemcpy_bsrcul2loop16 + ldmia sp!, {r4, r5, lr} + adds r2, r2, #0x0c + blt .Lmemcpy_bsrcul2l4 + +.Lmemcpy_bsrcul2loop4: + mov r12, r3, lsl #16 + ldr r3, [r1, #-4]! + orr r12, r12, r3, lsr #16 + str r12, [r0, #-4]! + subs r2, r2, #4 + bge .Lmemcpy_bsrcul2loop4 + +.Lmemcpy_bsrcul2l4: + add r1, r1, #2 + b .Lmemcpy_bl4 + +.Lmemcpy_bsrcul1: + cmp r2, #0x0c + blt .Lmemcpy_bsrcul1loop4 + sub r2, r2, #0x0c + stmdb sp!, {r4, r5, lr} + +.Lmemcpy_bsrcul1loop32: + mov lr, r3, lsl #24 + ldmdb r1!, {r3-r5, r12} + orr lr, lr, r12, lsr #8 + mov r12, r12, lsl #24 + orr r12, r12, r5, lsr #8 + mov r5, r5, lsl #24 + orr r5, r5, r4, lsr #8 + mov r4, r4, lsl #24 + orr r4, r4, r3, lsr #8 + stmdb r0!, {r4, r5, r12, lr} + subs r2, r2, #0x10 + bge .Lmemcpy_bsrcul1loop32 + ldmia sp!, {r4, r5, lr} + adds r2, r2, #0x0c + blt .Lmemcpy_bsrcul1l4 + +.Lmemcpy_bsrcul1loop4: + mov r12, r3, lsl #24 + ldr r3, [r1, #-4]! + orr r12, r12, r3, lsr #8 + str r12, [r0, #-4]! + subs r2, r2, #4 + bge .Lmemcpy_bsrcul1loop4 + +.Lmemcpy_bsrcul1l4: + add r1, r1, #1 + b .Lmemcpy_bl4 diff --git a/hw/mcu/allwinner/f1c100s/lib/memset.S b/hw/mcu/allwinner/f1c100s/lib/memset.S new file mode 100644 index 000000000..3eea2db1e --- /dev/null +++ b/hw/mcu/allwinner/f1c100s/lib/memset.S @@ -0,0 +1,79 @@ +/* + * memcpy.S + */ + .text + + .global memset + .type memset, %function + .align 4 + +memset: + stmfd sp!, {r0} /* remember address for return value */ + and r1, r1, #0x000000ff /* we write bytes */ + + cmp r2, #0x00000004 /* do we have less than 4 bytes */ + blt .Lmemset_lessthanfour + + /* first we will word align the address */ + ands r3, r0, #0x00000003 /* get the bottom two bits */ + beq .Lmemset_addraligned /* the address is word aligned */ + + rsb r3, r3, #0x00000004 + sub r2, r2, r3 + cmp r3, #0x00000002 + strb r1, [r0], #0x0001 /* set 1 byte */ + strgeb r1, [r0], #0x0001 /* set another byte */ + strgtb r1, [r0], #0x0001 /* and a third */ + + cmp r2, #0x00000004 + blt .Lmemset_lessthanfour + + /* now we must be word aligned */ +.Lmemset_addraligned: + orr r3, r1, r1, lsl #8 /* repeat the byte into a word */ + orr r3, r3, r3, lsl #16 + + /* we know we have at least 4 bytes ... */ + cmp r2, #0x00000020 /* if less than 32 then use words */ + blt .Lmemset_lessthan32 + + /* we have at least 32 so lets use quad words */ + stmfd sp!, {r4-r6} /* store registers */ + mov r4, r3 /* duplicate data */ + mov r5, r3 + mov r6, r3 + +.Lmemset_loop16: + stmia r0!, {r3-r6} /* store 16 bytes */ + sub r2, r2, #0x00000010 /* adjust count */ + cmp r2, #0x00000010 /* still got at least 16 bytes ? */ + bgt .Lmemset_loop16 + + ldmfd sp!, {r4-r6} /* restore registers */ + + /* do we need to set some words as well ? */ + cmp r2, #0x00000004 + blt .Lmemset_lessthanfour + + /* have either less than 16 or less than 32 depending on route taken */ +.Lmemset_lessthan32: + + /* we have at least 4 bytes so copy as words */ +.Lmemset_loop4: + str r3, [r0], #0x0004 + sub r2, r2, #0x0004 + cmp r2, #0x00000004 + bge .Lmemset_loop4 + +.Lmemset_lessthanfour: + cmp r2, #0x00000000 + ldmeqfd sp!, {r0} + moveq pc, lr /* zero length so exit */ + + cmp r2, #0x00000002 + strb r1, [r0], #0x0001 /* set 1 byte */ + strgeb r1, [r0], #0x0001 /* set another byte */ + strgtb r1, [r0], #0x0001 /* and a third */ + + ldmfd sp!, {r0} + mov pc, lr /* exit */ diff --git a/hw/mcu/allwinner/f1c100s/lib/printf.c b/hw/mcu/allwinner/f1c100s/lib/printf.c new file mode 100644 index 000000000..366bb9c0b --- /dev/null +++ b/hw/mcu/allwinner/f1c100s/lib/printf.c @@ -0,0 +1,757 @@ + +/////////////////////////////////////////////////////////////////////////////// +// \author (c) Marco Paland (info@paland.com) +// 2014-2018, PALANDesign Hannover, Germany +// +// \license The MIT License (MIT) +// +// 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. +// +// \brief Tiny printf, sprintf and (v)snprintf implementation, optimized for speed on +// embedded systems with a very limited resources. These routines are thread +// safe and reentrant! +// Use this instead of the bloated standard/newlib printf cause these use +// malloc for printf (and may not be thread safe). +// +/////////////////////////////////////////////////////////////////////////////// + +#include +#include "printf.h" + + +// ntoa conversion buffer size, this must be big enough to hold +// one converted numeric number including padded zeros (dynamically created on stack) +// 32 byte is a good default +#define PRINTF_NTOA_BUFFER_SIZE 32U + +// ftoa conversion buffer size, this must be big enough to hold +// one converted float number including padded zeros (dynamically created on stack) +// 32 byte is a good default +#define PRINTF_FTOA_BUFFER_SIZE 32U + +// define this to support floating point (%f) +#define PRINTF_SUPPORT_FLOAT + +// define this to support long long types (%llu or %p) +#define PRINTF_SUPPORT_LONG_LONG + +// define this to support the ptrdiff_t type (%t) +// ptrdiff_t is normally defined in as long or long long type +#define PRINTF_SUPPORT_PTRDIFF_T + + +/////////////////////////////////////////////////////////////////////////////// + +// internal flag definitions +#define FLAGS_ZEROPAD (1U << 0U) +#define FLAGS_LEFT (1U << 1U) +#define FLAGS_PLUS (1U << 2U) +#define FLAGS_SPACE (1U << 3U) +#define FLAGS_HASH (1U << 4U) +#define FLAGS_UPPERCASE (1U << 5U) +#define FLAGS_CHAR (1U << 6U) +#define FLAGS_SHORT (1U << 7U) +#define FLAGS_LONG (1U << 8U) +#define FLAGS_LONG_LONG (1U << 9U) +#define FLAGS_PRECISION (1U << 10U) + +typedef unsigned char bool; +#ifndef false +#define false 0 +#endif +#ifndef true +#define true (!false) +#endif +extern void sys_uart_putc(char c); +static char last_ch; +void _putchar(char character) +{ + if(character == 0x0a && last_ch != 0x0d) + { + sys_uart_putc(0x0d); + } + sys_uart_putc(character); + +} + +// output function type +typedef void (*out_fct_type)(char character, void* buffer, size_t idx, size_t maxlen); + + +// wrapper (used as buffer) for output function type +typedef struct { + void (*fct)(char character, void* arg); + void* arg; +} out_fct_wrap_type; + + +// internal buffer output +static inline void _out_buffer(char character, void* buffer, size_t idx, size_t maxlen) +{ + if (idx < maxlen) { + ((char*)buffer)[idx] = character; + } +} + + +// internal null output +static inline void _out_null(char character, void* buffer, size_t idx, size_t maxlen) +{ + (void)character; (void)buffer; (void)idx; (void)maxlen; +} + + +// internal _putchar wrapper +static inline void _out_char(char character, void* buffer, size_t idx, size_t maxlen) +{ + (void)buffer; (void)idx; (void)maxlen; + if (character) { + _putchar(character); + } +} + + +// internal output function wrapper +static inline void _out_fct(char character, void* buffer, size_t idx, size_t maxlen) +{ + (void)idx; (void)maxlen; + // buffer is the output fct pointer + ((out_fct_wrap_type*)buffer)->fct(character, ((out_fct_wrap_type*)buffer)->arg); +} + + +// internal strlen +// \return The length of the string (excluding the terminating 0) +static inline unsigned int _strlen(const char* str) +{ + const char* s; + for (s = str; *s; ++s); + return (unsigned int)(s - str); +} + + +// internal test if char is a digit (0-9) +// \return true if char is a digit +static inline bool _is_digit(char ch) +{ + return (ch >= '0') && (ch <= '9'); +} + + +// internal ASCII string to unsigned int conversion +static unsigned int _atoi(const char** str) +{ + unsigned int i = 0U; + while (_is_digit(**str)) { + i = i * 10U + (unsigned int)(*((*str)++) - '0'); + } + return i; +} + + +// internal itoa format +static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t maxlen, char* buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags) +{ + const size_t start_idx = idx; + + // pad leading zeros + while (!(flags & FLAGS_LEFT) && (len < prec) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = '0'; + } + while (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = '0'; + } + + // handle hash + if (flags & FLAGS_HASH) { + if (!(flags & FLAGS_PRECISION) && len && ((len == prec) || (len == width))) { + len--; + if (len && (base == 16U)) { + len--; + } + } + if ((base == 16U) && !(flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = 'x'; + } + else if ((base == 16U) && (flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = 'X'; + } + else if ((base == 2U) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = 'b'; + } + if (len < PRINTF_NTOA_BUFFER_SIZE) { + buf[len++] = '0'; + } + } + + // handle sign + if (len && (len == width) && (negative || (flags & FLAGS_PLUS) || (flags & FLAGS_SPACE))) { + len--; + } + if (len < PRINTF_NTOA_BUFFER_SIZE) { + if (negative) { + buf[len++] = '-'; + } + else if (flags & FLAGS_PLUS) { + buf[len++] = '+'; // ignore the space if the '+' exists + } + else if (flags & FLAGS_SPACE) { + buf[len++] = ' '; + } + } + + // pad spaces up to given width + if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) { + for (size_t i = len; i < width; i++) { + out(' ', buffer, idx++, maxlen); + } + } + + // reverse string + for (size_t i = 0U; i < len; i++) { + out(buf[len - i - 1U], buffer, idx++, maxlen); + } + + // append pad spaces up to given width + if (flags & FLAGS_LEFT) { + while (idx - start_idx < width) { + out(' ', buffer, idx++, maxlen); + } + } + + return idx; +} + + +// internal itoa for 'long' type +static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags) +{ + char buf[PRINTF_NTOA_BUFFER_SIZE]; + size_t len = 0U; + + // no hash for 0 values + if (!value) { + flags &= ~FLAGS_HASH; + } + + // write if precision != 0 and value is != 0 + if (!(flags & FLAGS_PRECISION) || value) { + do { + const char digit = (char)(value % base); + buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; + value /= base; + } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); + } + + return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); +} + + +// internal itoa for 'long long' type +#if defined(PRINTF_SUPPORT_LONG_LONG) +static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long long value, bool negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags) +{ + char buf[PRINTF_NTOA_BUFFER_SIZE]; + size_t len = 0U; + + // no hash for 0 values + if (!value) { + flags &= ~FLAGS_HASH; + } + + // write if precision != 0 and value is != 0 + if (!(flags & FLAGS_PRECISION) || value) { + do { + const char digit = (char)(value % base); + buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; + value /= base; + } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); + } + + return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); +} +#endif // PRINTF_SUPPORT_LONG_LONG + + +#if defined(PRINTF_SUPPORT_FLOAT) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" + +static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) +{ + const size_t start_idx = idx; + + char buf[PRINTF_FTOA_BUFFER_SIZE]; + size_t len = 0U; + double diff = 0.0; + + // if input is larger than thres_max, revert to exponential + const double thres_max = (double)0x7FFFFFFF; + + // powers of 10 + static const double pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; + + // test for negative + bool negative = false; + if (value < 0) { + negative = true; + value = 0 - value; + } + + // set default precision to 6, if not set explicitly + if (!(flags & FLAGS_PRECISION)) { + prec = 6U; + } + // limit precision to 9, cause a prec >= 10 can lead to overflow errors + while ((len < PRINTF_FTOA_BUFFER_SIZE) && (prec > 9U)) { + buf[len++] = '0'; + prec--; + } + + int whole = (int)value; + double tmp = (value - whole) * pow10[prec]; + unsigned long frac = (unsigned long)tmp; + diff = tmp - frac; + + if (diff > 0.5l) { + ++frac; + // handle rollover, e.g. case 0.99 with prec 1 is 1.0 + if (frac >= pow10[prec]) { + frac = 0; + ++whole; + } + } + else if ((diff == 0.5l) && ((frac == 0U) || (frac & 1U))) { + // if halfway, round up if odd, OR if last digit is 0 + ++frac; + } + + // TBD: for very large numbers switch back to native sprintf for exponentials. Anyone want to write code to replace this? + // Normal printf behavior is to print EVERY whole number digit which can be 100s of characters overflowing your buffers == bad + if (value > thres_max) { + return 0U; + } + + if (prec == 0U) { + diff = value - (double)whole; + if (diff > 0.5l) { + // greater than 0.5, round up, e.g. 1.6 -> 2 + ++whole; + } + else if ((diff == 0.5l) && (whole & 1)) { + // exactly 0.5 and ODD, then round up + // 1.5 -> 2, but 2.5 -> 2 + ++whole; + } + } + else { + unsigned int count = prec; + // now do fractional part, as an unsigned number + while (len < PRINTF_FTOA_BUFFER_SIZE) { + --count; + buf[len++] = (char)(48U + (frac % 10U)); + if (!(frac /= 10U)) { + break; + } + } + // add extra 0s + while ((len < PRINTF_FTOA_BUFFER_SIZE) && (count-- > 0U)) { + buf[len++] = '0'; + } + if (len < PRINTF_FTOA_BUFFER_SIZE) { + // add decimal + buf[len++] = '.'; + } + } + + // do whole part, number is reversed + while (len < PRINTF_FTOA_BUFFER_SIZE) { + buf[len++] = (char)(48 + (whole % 10)); + if (!(whole /= 10)) { + break; + } + } + + // pad leading zeros + while (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_FTOA_BUFFER_SIZE)) { + buf[len++] = '0'; + } + + // handle sign + if ((len == width) && (negative || (flags & FLAGS_PLUS) || (flags & FLAGS_SPACE))) { + len--; + } + if (len < PRINTF_FTOA_BUFFER_SIZE) { + if (negative) { + buf[len++] = '-'; + } + else if (flags & FLAGS_PLUS) { + buf[len++] = '+'; // ignore the space if the '+' exists + } + else if (flags & FLAGS_SPACE) { + buf[len++] = ' '; + } + } + + // pad spaces up to given width + if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) { + for (size_t i = len; i < width; i++) { + out(' ', buffer, idx++, maxlen); + } + } + + // reverse string + for (size_t i = 0U; i < len; i++) { + out(buf[len - i - 1U], buffer, idx++, maxlen); + } + + // append pad spaces up to given width + if (flags & FLAGS_LEFT) { + while (idx - start_idx < width) { + out(' ', buffer, idx++, maxlen); + } + } + + return idx; +} +#pragma GCC diagnostic pop +#endif // PRINTF_SUPPORT_FLOAT + + +// internal vsnprintf +static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const char* format, va_list va) +{ + unsigned int flags, width, precision, n; + size_t idx = 0U; + + if (!buffer) { + // use null output function + out = _out_null; + } + + while (*format) + { + // format specifier? %[flags][width][.precision][length] + if (*format != '%') { + // no + out(*format, buffer, idx++, maxlen); + format++; + continue; + } + else { + // yes, evaluate it + format++; + } + + // evaluate flags + flags = 0U; + do { + switch (*format) { + case '0': flags |= FLAGS_ZEROPAD; format++; n = 1U; break; + case '-': flags |= FLAGS_LEFT; format++; n = 1U; break; + case '+': flags |= FLAGS_PLUS; format++; n = 1U; break; + case ' ': flags |= FLAGS_SPACE; format++; n = 1U; break; + case '#': flags |= FLAGS_HASH; format++; n = 1U; break; + default : n = 0U; break; + } + } while (n); + + // evaluate width field + width = 0U; + if (_is_digit(*format)) { + width = _atoi(&format); + } + else if (*format == '*') { + const int w = va_arg(va, int); + if (w < 0) { + flags |= FLAGS_LEFT; // reverse padding + width = (unsigned int)-w; + } + else { + width = (unsigned int)w; + } + format++; + } + + // evaluate precision field + precision = 0U; + if (*format == '.') { + flags |= FLAGS_PRECISION; + format++; + if (_is_digit(*format)) { + precision = _atoi(&format); + } + else if (*format == '*') { + const int prec = (int)va_arg(va, int); + precision = prec > 0 ? (unsigned int)prec : 0U; + format++; + } + } + + // evaluate length field + switch (*format) { + case 'l' : + flags |= FLAGS_LONG; + format++; + if (*format == 'l') { + flags |= FLAGS_LONG_LONG; + format++; + } + break; + case 'h' : + flags |= FLAGS_SHORT; + format++; + if (*format == 'h') { + flags |= FLAGS_CHAR; + format++; + } + break; +#if defined(PRINTF_SUPPORT_PTRDIFF_T) + case 't' : + flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); + format++; + break; +#endif + case 'j' : + flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); + format++; + break; + case 'z' : + flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); + format++; + break; + default : + break; + } + + // evaluate specifier + switch (*format) { + case 'd' : + case 'i' : + case 'u' : + case 'x' : + case 'X' : + case 'o' : + case 'b' : { + // set the base + unsigned int base; + if (*format == 'x' || *format == 'X') { + base = 16U; + } + else if (*format == 'o') { + base = 8U; + } + else if (*format == 'b') { + base = 2U; + } + else { + base = 10U; + flags &= ~FLAGS_HASH; // no hash for dec format + } + // uppercase + if (*format == 'X') { + flags |= FLAGS_UPPERCASE; + } + + // no plus or space flag for u, x, X, o, b + if ((*format != 'i') && (*format != 'd')) { + flags &= ~(FLAGS_PLUS | FLAGS_SPACE); + } + + // ignore '0' flag when precision is given + if (flags & FLAGS_PRECISION) { + flags &= ~FLAGS_ZEROPAD; + } + + // convert the integer + if ((*format == 'i') || (*format == 'd')) { + // signed + if (flags & FLAGS_LONG_LONG) { +#if defined(PRINTF_SUPPORT_LONG_LONG) + const long long value = va_arg(va, long long); + idx = _ntoa_long_long(out, buffer, idx, maxlen, (unsigned long long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); +#endif + } + else if (flags & FLAGS_LONG) { + const long value = va_arg(va, long); + idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); + } + else { + const int value = (flags & FLAGS_CHAR) ? (char)va_arg(va, int) : (flags & FLAGS_SHORT) ? (short int)va_arg(va, int) : va_arg(va, int); + idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); + } + } + else { + // unsigned + if (flags & FLAGS_LONG_LONG) { +#if defined(PRINTF_SUPPORT_LONG_LONG) + idx = _ntoa_long_long(out, buffer, idx, maxlen, va_arg(va, unsigned long long), false, base, precision, width, flags); +#endif + } + else if (flags & FLAGS_LONG) { + idx = _ntoa_long(out, buffer, idx, maxlen, va_arg(va, unsigned long), false, base, precision, width, flags); + } + else { + const unsigned int value = (flags & FLAGS_CHAR) ? (unsigned char)va_arg(va, unsigned int) : (flags & FLAGS_SHORT) ? (unsigned short int)va_arg(va, unsigned int) : va_arg(va, unsigned int); + idx = _ntoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags); + } + } + format++; + break; + } +#if defined(PRINTF_SUPPORT_FLOAT) + case 'f' : + case 'F' : + idx = _ftoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); + format++; + break; +#endif // PRINTF_SUPPORT_FLOAT + case 'c' : { + unsigned int l = 1U; + // pre padding + if (!(flags & FLAGS_LEFT)) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + // char output + out((char)va_arg(va, int), buffer, idx++, maxlen); + // post padding + if (flags & FLAGS_LEFT) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + format++; + break; + } + + case 's' : { + char* p = va_arg(va, char*); + unsigned int l = _strlen(p); + // pre padding + if (flags & FLAGS_PRECISION) { + l = (l < precision ? l : precision); + } + if (!(flags & FLAGS_LEFT)) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + // string output + while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision--)) { + out(*(p++), buffer, idx++, maxlen); + } + // post padding + if (flags & FLAGS_LEFT) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + format++; + break; + } + + case 'p' : { + width = sizeof(void*) * 2U; + flags |= FLAGS_ZEROPAD | FLAGS_UPPERCASE; +#if defined(PRINTF_SUPPORT_LONG_LONG) + const bool is_ll = sizeof(uintptr_t) == sizeof(long long); + if (is_ll) { + idx = _ntoa_long_long(out, buffer, idx, maxlen, (uintptr_t)va_arg(va, void*), false, 16U, precision, width, flags); + } + else { +#endif + idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)((uintptr_t)va_arg(va, void*)), false, 16U, precision, width, flags); +#if defined(PRINTF_SUPPORT_LONG_LONG) + } +#endif + format++; + break; + } + + case '%' : + out('%', buffer, idx++, maxlen); + format++; + break; + + default : + out(*format, buffer, idx++, maxlen); + format++; + break; + } + } + + // termination + out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen); + + // return written chars without terminating \0 + return (int)idx; +} + + +/////////////////////////////////////////////////////////////////////////////// + + +int printf(const char* format, ...) +{ + va_list va; + va_start(va, format); + char buffer[1]; + const int ret = _vsnprintf(_out_char, buffer, (size_t)-1, format, va); + va_end(va); + return ret; +} + + +int sprintf(char* buffer, const char* format, ...) +{ + va_list va; + va_start(va, format); + const int ret = _vsnprintf(_out_buffer, buffer, (size_t)-1, format, va); + va_end(va); + return ret; +} + + +int snprintf(char* buffer, size_t count, const char* format, ...) +{ + va_list va; + va_start(va, format); + const int ret = _vsnprintf(_out_buffer, buffer, count, format, va); + va_end(va); + return ret; +} + + +int vsnprintf(char* buffer, size_t count, const char* format, va_list va) +{ + return _vsnprintf(_out_buffer, buffer, count, format, va); +} + + +int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...) +{ + va_list va; + va_start(va, format); + out_fct_wrap_type out_fct_wrap = { out, arg }; + const int ret = _vsnprintf(_out_fct, (char*)&out_fct_wrap, (size_t)-1, format, va); + va_end(va); + return ret; +} diff --git a/hw/mcu/allwinner/f1c100s/machine/exception.c b/hw/mcu/allwinner/f1c100s/machine/exception.c new file mode 100644 index 000000000..ffc61bf47 --- /dev/null +++ b/hw/mcu/allwinner/f1c100s/machine/exception.c @@ -0,0 +1,76 @@ +/* + * exception.c + * + * Copyright(c) 2007-2018 Jianjun Jiang <8192542@qq.com> + * Official site: http://xboot.org + * Mobile phone: +86-18665388956 + * QQ: 8192542 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include +#include +#include + +static void show_regs(struct arm_regs_t * regs) +{ + int i; + + printf("pc : [<%08lx>] lr : [<%08lx>] cpsr: %08lx\r\n", regs->pc, regs->lr, regs->cpsr); + printf("sp : %08lx\r\n", regs->sp); + for(i = 12; i >= 0; i--) + { + printf("r%-2d: %08lx ", i, regs->r[i]); + if(i % 2 == 0) + printf("\r\n"); + } + printf("\r\n"); +} + +void arm32_do_undefined_instruction(struct arm_regs_t * regs) +{ + //gdbserver_handle_exception(regs); +} + +void arm32_do_software_interrupt(struct arm_regs_t * regs) +{ + show_regs(regs); + regs->pc += 4; +} + +void arm32_do_prefetch_abort(struct arm_regs_t * regs) +{ + show_regs(regs); + regs->pc += 4; +} + +void arm32_do_data_abort(struct arm_regs_t * regs) +{ + show_regs(regs); + regs->pc += 4; +} + +_Noreturn void __fatal_error(const char *msg) { + printf("%s\n", msg); + while (1); +} + +#ifndef NDEBUG +_Noreturn void __assert_func(const char *file, int line, const char *func, const char *expr) { + //printf("Assertion '%s' failed, at file %s:%d\n", expr, file, line); + __fatal_error("Assertion failed"); +} +#endif \ No newline at end of file diff --git a/hw/mcu/allwinner/f1c100s/machine/f1c100s-intc.c b/hw/mcu/allwinner/f1c100s/machine/f1c100s-intc.c new file mode 100644 index 000000000..2993f0b60 --- /dev/null +++ b/hw/mcu/allwinner/f1c100s/machine/f1c100s-intc.c @@ -0,0 +1,173 @@ +// Originally designed by Hong Xuyao + +#include +#include +#include +#include + +#define __irq __attribute__ ((interrupt ("IRQ"))) + +#ifndef __IO +#define __IO volatile +#endif + +typedef struct { + __IO uint32_t INTC_VECTOR_REG; // 0x00 + __IO uint32_t INTC_BASE_ADDR_REG; // 0x04 + uint32_t resv1[1]; // 0x08 + __IO uint32_t NMI_INT_CTRL_REG; // 0x0c + __IO uint32_t INTC_PEND_REG[2]; // 0x10 + uint32_t resv2[2]; // 0x18 + __IO uint32_t INTC_EN_REG[2]; // 0x20 + uint32_t resv3[2]; // 0x28 + __IO uint32_t INTC_MASK_REG[2]; // 0x30 + uint32_t resv4[2]; // 0x38 + __IO uint32_t INTC_RESP_REG[2]; // 0x40 + uint32_t resv5[2]; // 0x48 + __IO uint32_t INTC_FF_REG[2]; // 0x50 + uint32_t resv6[2]; // 0x58 + __IO uint32_t INTC_PRIO_REG[4]; // 0x60 +} INTC_TypeDef; + +#ifndef COUNTOF +#define COUNTOF(ar) (sizeof(ar)/sizeof(ar[0])) +#endif + +#define INTC ((INTC_TypeDef*)0x01C20400) + +static IRQHandleTypeDef irq_table[64] __attribute__((used, aligned(32))); + +void arm32_do_irq(struct arm_regs_t * regs) +{ + uint8_t nIRQ = f1c100s_intc_get_nirq(); + + // ForceIRQ flag must be cleared by ISR + // Otherwise ISR will be entered repeatedly + INTC->INTC_FF_REG[nIRQ / 32] &= ~(1 << nIRQ); + // Call the drivers ISR + f1c100s_intc_dispatch(nIRQ); + // Clear pending at the end of ISR + f1c100s_intc_clear_pend(nIRQ); +} + +void arm32_do_fiq(struct arm_regs_t * regs) +{ + // Call the drivers ISR + f1c100s_intc_dispatch(0); + // Clear pending at the end of ISR. + f1c100s_intc_clear_pend(0); +} + +/* +* Read active IRQ number +* @return: none +*/ +uint8_t f1c100s_intc_get_nirq(void) +{ + return ((INTC->INTC_VECTOR_REG >> 2) & 0x3F); +} + +/* +* Execute ISR corresponding to IRQ number +* @nIRQ: IRQ number +* @return: none +*/ +void f1c100s_intc_dispatch(uint8_t nIRQ) +{ + IRQHandleTypeDef handle = irq_table[nIRQ]; + if (handle) + handle(); +} + +/* +* Set handler function for specified IRQ +* @nIRQ: IRQ number +* @handle: Handle function +* @return: none +*/ +void f1c100s_intc_set_isr(uint8_t nIRQ, IRQHandleTypeDef handle) +{ + if (nIRQ < COUNTOF(irq_table)) { + irq_table[nIRQ] = handle; + } +} + +/* +* Enable IRQ +* @nIRQ: IRQ number +* @return: none +*/ +void f1c100s_intc_enable_irq(uint8_t nIRQ) +{ + INTC->INTC_EN_REG[nIRQ / 32] |= (1 << (nIRQ % 32)); +} + +/* +* Disable IRQ +* @nIRQ: IRQ number +* @return: none +*/ +void f1c100s_intc_disable_irq(uint8_t nIRQ) +{ + INTC->INTC_EN_REG[nIRQ / 32] &= ~(1 << (nIRQ % 32)); +} + +/* +* Mask IRQ +* @nIRQ: IRQ number +* @return: none +*/ +void f1c100s_intc_mask_irq(uint8_t nIRQ) +{ + INTC->INTC_MASK_REG[nIRQ / 32] |= (1 << (nIRQ % 32)); +} + +/* +* Unmask IRQ +* @nIRQ: IRQ number +* @return: none +*/ +void f1c100s_intc_unmask_irq(uint8_t nIRQ) +{ + INTC->INTC_MASK_REG[nIRQ / 32] &= ~(1 << (nIRQ % 32)); +} + +/* +* Immediately trigger IRQ +* @nIRQ: IRQ number +* @return: none +*/ +void f1c100s_intc_force_irq(uint8_t nIRQ) +{ + // This bit is to be cleared in IRQ handler + INTC->INTC_FF_REG[nIRQ / 32] = (1 << (nIRQ % 32)); +} + +/* +* Clear pending flag +* @nIRQ: IRQ number +* @return: none +*/ +void f1c100s_intc_clear_pend(uint8_t nIRQ) +{ + INTC->INTC_PEND_REG[nIRQ / 32] = (1 << (nIRQ % 32)); +} + + +/* +* Initialize IRQ module +* @return: none +*/ +void f1c100s_intc_init(void) +{ + INTC->INTC_EN_REG[0] = INTC->INTC_EN_REG[1] = 0; + INTC->INTC_MASK_REG[0] = INTC->INTC_MASK_REG[1] = 0; + INTC->INTC_FF_REG[0] = INTC->INTC_FF_REG[1] = 0; + INTC->INTC_RESP_REG[0] = INTC->INTC_RESP_REG[1] = 0; + INTC->INTC_PEND_REG[0] = INTC->INTC_PEND_REG[1] = ~0UL; + INTC->INTC_BASE_ADDR_REG = 0; + INTC->NMI_INT_CTRL_REG = 0; + for (unsigned int i = 0; i < COUNTOF(irq_table); i++) { + irq_table[i] = 0; + } +} diff --git a/hw/mcu/allwinner/f1c100s/machine/start.S b/hw/mcu/allwinner/f1c100s/machine/start.S new file mode 100644 index 000000000..1fd7cb1f9 --- /dev/null +++ b/hw/mcu/allwinner/f1c100s/machine/start.S @@ -0,0 +1,313 @@ +/* + * start.S + * + * Copyright(c) 2007-2018 Jianjun Jiang <8192542@qq.com> + * Official site: http://xboot.org + * Mobile phone: +86-18665388956 + * QQ: 8192542 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* + * Exception vector table + */ +.text + .arm + + .global _start +_start: + /* Boot head information for BROM */ + .long 0xea000016 + .byte 'e', 'G', 'O', 'N', '.', 'B', 'T', '0' + .long 0, __bootloader_size + .byte 'S', 'P', 'L', 2 + .long 0, 0 + .long 0, 0, 0, 0, 0, 0, 0, 0 + .long 0, 0, 0, 0, 0, 0, 0, 0 /* 0x40 - boot params, 0x58 - fel boot type, 0x5c - dram size */ + +_vector: + b reset + ldr pc, _undefined_instruction + ldr pc, _software_interrupt + ldr pc, _prefetch_abort + ldr pc, _data_abort + ldr pc, _not_used + ldr pc, _irq + ldr pc, _fiq + +_undefined_instruction: + .word undefined_instruction +_software_interrupt: + .word software_interrupt +_prefetch_abort: + .word prefetch_abort +_data_abort: + .word data_abort +_not_used: + .word not_used +_irq: + .word irq +_fiq: + .word fiq + +/* + * The actual reset code + */ +reset: + /* Save boot params to 0x00000040 */ + ldr r0, =0x00000040 + str sp, [r0, #0] + str lr, [r0, #4] + mrs lr, cpsr + str lr, [r0, #8] + mrc p15, 0, lr, c1, c0, 0 + str lr, [r0, #12] + mrc p15, 0, lr, c1, c0, 0 + str lr, [r0, #16] + + /* Check boot type just for fel */ + mov r0, #0x0 + ldr r1, [r0, #8] + ldr r2, =0x4c45462e + cmp r1, r2 + bne 1f + ldr r1, =0x1 + str r1, [r0, #0x58] +1: nop + + /* Enter svc mode and mask interrupts */ + mrs r0, cpsr + bic r0, r0, #0x1f + orr r0, r0, #0xd3 + msr cpsr, r0 + + /* Set vector to the low address */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, #(1<<13) + mcr p15, 0, r0, c1, c0, 0 + + /* Copy vector to the correct address */ + adr r0, _vector + mrc p15, 0, r2, c1, c0, 0 + ands r2, r2, #(1 << 13) + ldreq r1, =0x00000000 + ldrne r1, =0xffff0000 + ldmia r0!, {r2-r8, r10} + stmia r1!, {r2-r8, r10} + ldmia r0!, {r2-r8, r10} + stmia r1!, {r2-r8, r10} + + /* Initial system clock, ddr add uart */ + bl sys_clock_init + bl sys_dram_init + bl sys_uart_init + + /* Boot speed up, leave slower sram */ + adr r0, _start + ldr r1, =_start + cmp r0, r1 + beq _speedup + ldr r0, =0x81f80000 + adr r1, _start + mov r2, #0x4000 + bl memcpy + ldr r0, =_speedup + ldr r1, =_start + sub r0, r0, r1 + ldr r1, =0x81f80000 + add r0, r0, r1 + mov pc, r0 +_speedup: + nop + + /* Copyself to link address */ + adr r0, _start + ldr r1, =_start + cmp r0, r1 + beq 1f + bl sys_copyself +1: nop + + /* Initialize stacks */ + mrs r0, cpsr + bic r0, r0, #0x1f + orr r1, r0, #0x1b + msr cpsr_cxsf, r1 + ldr sp, _stack_und_end + + bic r0, r0, #0x1f + orr r1, r0, #0x17 + msr cpsr_cxsf, r1 + ldr sp, _stack_abt_end + + bic r0, r0, #0x1f + orr r1, r0, #0x12 + msr cpsr_cxsf, r1 + ldr sp, _stack_irq_end + + bic r0, r0, #0x1f + orr r1, r0, #0x11 + msr cpsr_cxsf, r1 + ldr sp, _stack_fiq_end + + bic r0, r0, #0x1f + orr r1, r0, #0x13 + msr cpsr_cxsf, r1 + ldr sp, _stack_srv_end + + /* Copy data section */ + ldr r0, _data_start + ldr r1, _data_shadow_start + ldr r2, _data_shadow_end + sub r2, r2, r1 + bl memcpy + + /* Clear bss section */ + ldr r0, _bss_start + ldr r2, _bss_end + sub r2, r2, r0 + mov r1, #0 + bl memset + + /* Call _main */ + ldr r1, =_main + mov pc, r1 +_main: + bl main + b _main + + .global return_to_fel +return_to_fel: + mov r0, #0x4 + mov r1, #'e' + strb r1, [r0, #0] + mov r1, #'G' + strb r1, [r0, #1] + mov r1, #'O' + strb r1, [r0, #2] + mov r1, #'N' + strb r1, [r0, #3] + mov r1, #'.' + strb r1, [r0, #4] + mov r1, #'F' + strb r1, [r0, #5] + mov r1, #'E' + strb r1, [r0, #6] + mov r1, #'L' + strb r1, [r0, #7] + ldr r0, =0x00000040 + ldr sp, [r0, #0] + ldr lr, [r0, #4] + ldr r1, [r0, #16] + mcr p15, 0, r1, c1, c0, 0 + ldr r1, [r0, #12] + mcr p15, 0, r1, c1, c0, 0 + ldr r1, [r0, #8] + msr cpsr, r1 + bx lr + +/* + * Exception handlers + */ + .align 5 +undefined_instruction: + b . + + .align 5 +software_interrupt: + b . + + .align 5 +prefetch_abort: + b . + + .align 5 +data_abort: + b . + + .align 5 +not_used: + b . + + .align 5 +irq: + ldr sp, _stack_irq_end + sub sp, sp, #72 + stmia sp, {r0 - r12} + add r8, sp, #60 + stmdb r8, {sp, lr}^ + str lr, [r8, #0] + mrs r6, spsr + str r6, [r8, #4] + str r0, [r8, #8] + mov r0, sp + bl arm32_do_irq + ldmia sp, {r0 - lr}^ + mov r0, r0 + ldr lr, [sp, #60] + add sp, sp, #72 + subs pc, lr, #4 + + .align 5 +fiq: + ldr sp, _stack_irq_end + sub sp, sp, #72 + stmia sp, {r0 - r12} + add r8, sp, #60 + stmdb r8, {sp, lr}^ + str lr, [r8, #0] + mrs r6, spsr + str r6, [r8, #4] + str r0, [r8, #8] + mov r0, sp + bl arm32_do_fiq + ldmia sp, {r0 - lr}^ + mov r0, r0 + ldr lr, [sp, #60] + add sp, sp, #72 + subs pc, lr, #4 + +/* + * The location of section + */ + .align 4 +_image_start: + .long __image_start +_image_end: + .long __image_end +_data_shadow_start: + .long __data_shadow_start +_data_shadow_end: + .long __data_shadow_end +_data_start: + .long __data_start +_data_end: + .long __data_end +_bss_start: + .long __bss_start +_bss_end: + .long __bss_end +_stack_und_end: + .long __stack_und_end +_stack_abt_end: + .long __stack_abt_end +_stack_irq_end: + .long __stack_irq_end +_stack_fiq_end: + .long __stack_fiq_end +_stack_srv_end: + .long __stack_srv_end diff --git a/hw/mcu/allwinner/f1c100s/machine/sys-clock.c b/hw/mcu/allwinner/f1c100s/machine/sys-clock.c new file mode 100644 index 000000000..d151dd0c1 --- /dev/null +++ b/hw/mcu/allwinner/f1c100s/machine/sys-clock.c @@ -0,0 +1,124 @@ +/* + * sys-clock.c + * + * Copyright(c) 2007-2018 Jianjun Jiang <8192542@qq.com> + * Official site: http://xboot.org + * Mobile phone: +86-18665388956 + * QQ: 8192542 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +//#include +#include +#include +#include + +static inline void sdelay(int loops) +{ + __asm__ __volatile__ ("1:\n" "subs %0, %1, #1\n" + "bne 1b":"=r" (loops):"0"(loops)); +} + +static void wait_pll_stable(uint32_t base) +{ + uint32_t rval = 0; + uint32_t time = 0xfff; + + do { + rval = read32(base); + time--; + } while(time && !(rval & (1 << 28))); +} + +static void clock_set_pll_cpu(uint32_t clk) +{ + uint32_t n, k, m, p; + uint32_t rval = 0; + uint32_t div = 0; + + if(clk > 720000000) + clk = 720000000; + + if((clk % 24000000) == 0) + { + div = clk / 24000000; + n = div - 1; + k = 0; + m = 0; + p = 0; + } + else if((clk % 12000000) == 0) + { + m = 1; + div = clk / 12000000; + if((div % 3) == 0) + k = 2; + else if((div % 4) == 0) + k = 3; + else + k = 1; + n = (div / (k + 1)) - 1; + p = 0; + } + else + { + div = clk / 24000000; + n = div - 1; + k = 0; + m = 0; + p = 0; + } + + rval = read32(F1C100S_CCU_BASE + CCU_PLL_CPU_CTRL); + rval &= ~((0x3 << 16) | (0x1f << 8) | (0x3 << 4) | (0x3 << 0)); + rval |= (1U << 31) | (p << 16) | (n << 8) | (k << 4) | m; + write32(F1C100S_CCU_BASE + CCU_PLL_CPU_CTRL, rval); + wait_pll_stable(F1C100S_CCU_BASE + CCU_PLL_CPU_CTRL); +} + +void sys_clock_init(void) +{ + uint32_t val; + + write32(F1C100S_CCU_BASE + CCU_PLL_STABLE_TIME0, 0x1ff); + write32(F1C100S_CCU_BASE + CCU_PLL_STABLE_TIME1, 0x1ff); + + val = read32(F1C100S_CCU_BASE + CCU_CPU_CFG); + val &= ~(0x3 << 16); + val |= (0x1 << 16); + write32(F1C100S_CCU_BASE + CCU_CPU_CFG, val); + sdelay(100); + + write32(F1C100S_CCU_BASE + CCU_PLL_VIDEO_CTRL, 0x81004107); + sdelay(100); + write32(F1C100S_CCU_BASE + CCU_PLL_PERIPH_CTRL, 0x80041800); + sdelay(100); + write32(F1C100S_CCU_BASE + CCU_AHB_APB_CFG, 0x00003180); + sdelay(100); + + val = read32(F1C100S_CCU_BASE + CCU_DRAM_CLK_GATE); + val |= (0x1 << 26) | (0x1 << 24); + write32(F1C100S_CCU_BASE + CCU_DRAM_CLK_GATE, val); + sdelay(100); + + clock_set_pll_cpu(408000000); + val = read32(F1C100S_CCU_BASE + CCU_CPU_CFG); + val &= ~(0x3 << 16); + val |= (0x2 << 16); + write32(F1C100S_CCU_BASE + CCU_CPU_CFG, val); + sdelay(100); +} diff --git a/hw/mcu/allwinner/f1c100s/machine/sys-copyself.c b/hw/mcu/allwinner/f1c100s/machine/sys-copyself.c new file mode 100644 index 000000000..4116e1265 --- /dev/null +++ b/hw/mcu/allwinner/f1c100s/machine/sys-copyself.c @@ -0,0 +1,111 @@ +/* + * sys-copyself.c + * + * Copyright(c) 2007-2018 Jianjun Jiang <8192542@qq.com> + * Official site: http://xboot.org + * Mobile phone: +86-18665388956 + * QQ: 8192542 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include + +extern unsigned char __image_start; +extern unsigned char __image_end; +extern void return_to_fel(void); +extern void sys_mmu_init(void); +extern void sys_uart_putc(char c); +extern void sys_spi_flash_init(void); +extern void sys_spi_flash_exit(void); +extern void sys_spi_flash_read(int addr, void * buf, int count); + +enum { + BOOT_DEVICE_FEL = 0, + BOOT_DEVICE_SPI = 1, + BOOT_DEVICE_MMC = 2, +}; + +static int get_boot_device(void) +{ + uint32_t * t = (void *)0x00000058; + + if(t[0] == 0x1) + return BOOT_DEVICE_FEL; + return BOOT_DEVICE_SPI; +} + +void sys_copyself(void) +{ + int d = get_boot_device(); + void * mem; + uint32_t size; + + if(d == BOOT_DEVICE_FEL) + { + sys_uart_putc('B'); + sys_uart_putc('o'); + sys_uart_putc('o'); + sys_uart_putc('t'); + sys_uart_putc(' '); + sys_uart_putc('t'); + sys_uart_putc('o'); + sys_uart_putc(' '); + sys_uart_putc('F'); + sys_uart_putc('E'); + sys_uart_putc('L'); + sys_uart_putc(' '); + sys_uart_putc('m'); + sys_uart_putc('o'); + sys_uart_putc('d'); + sys_uart_putc('e'); + sys_uart_putc('\r'); + sys_uart_putc('\n'); + return_to_fel(); + } + else if(d == BOOT_DEVICE_SPI) + { + sys_uart_putc('B'); + sys_uart_putc('o'); + sys_uart_putc('o'); + sys_uart_putc('t'); + sys_uart_putc(' '); + sys_uart_putc('t'); + sys_uart_putc('o'); + sys_uart_putc(' '); + sys_uart_putc('S'); + sys_uart_putc('P'); + sys_uart_putc('I'); + sys_uart_putc(' '); + sys_uart_putc('m'); + sys_uart_putc('o'); + sys_uart_putc('d'); + sys_uart_putc('e'); + sys_uart_putc('\r'); + sys_uart_putc('\n'); + mem = (void *)&__image_start; + size = &__image_end - &__image_start; + sys_mmu_init(); + + sys_spi_flash_init(); + sys_spi_flash_read(0, mem, size); + sys_spi_flash_exit(); + } + else if(d == BOOT_DEVICE_MMC) + { + mem = (void *)&__image_start; + size = (&__image_end - &__image_start + 512) >> 9; + } +} diff --git a/hw/mcu/allwinner/f1c100s/machine/sys-dram.c b/hw/mcu/allwinner/f1c100s/machine/sys-dram.c new file mode 100644 index 000000000..a819520a5 --- /dev/null +++ b/hw/mcu/allwinner/f1c100s/machine/sys-dram.c @@ -0,0 +1,506 @@ +/* + * sys-dram.c + * + * Copyright(c) 2007-2018 Jianjun Jiang <8192542@qq.com> + * Official site: http://xboot.org + * Mobile phone: +86-18665388956 + * QQ: 8192542 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include +#include +#include +#include + +#define PLL_DDR_CLK (156000000) +#define SDR_T_CAS (0x2) +#define SDR_T_RAS (0x8) +#define SDR_T_RCD (0x3) +#define SDR_T_RP (0x3) +#define SDR_T_WR (0x3) +#define SDR_T_RFC (0xd) +#define SDR_T_XSR (0xf9) +#define SDR_T_RC (0xb) +#define SDR_T_INIT (0x8) +#define SDR_T_INIT_REF (0x7) +#define SDR_T_WTR (0x2) +#define SDR_T_RRD (0x2) +#define SDR_T_XP (0x0) + +enum dram_type_t +{ + DRAM_TYPE_SDR = 0, + DRAM_TYPE_DDR = 1, + DRAM_TYPE_MDDR = 2, +}; + +struct dram_para_t +{ + uint32_t base; /* dram base address */ + uint32_t size; /* dram size (unit: MByte) */ + uint32_t clk; /* dram work clock (unit: MHz) */ + uint32_t access_mode; /* 0: interleave mode 1: sequence mode */ + uint32_t cs_num; /* dram chip count 1: one chip 2: two chip */ + uint32_t ddr8_remap; /* for 8bits data width DDR 0: normal 1: 8bits */ + enum dram_type_t sdr_ddr; + uint32_t bwidth; /* dram bus width */ + uint32_t col_width; /* column address width */ + uint32_t row_width; /* row address width */ + uint32_t bank_size; /* dram bank count */ + uint32_t cas; /* dram cas */ +}; + +static inline void sdelay(int loops) +{ + __asm__ __volatile__ ("1:\n" "subs %0, %1, #1\n" + "bne 1b":"=r" (loops):"0"(loops)); +} + +static void dram_delay(int ms) +{ + sdelay(ms * 2 * 1000); +} + +static int dram_initial(void) +{ + unsigned int time = 0xffffff; + + write32(F1C100S_DRAM_BASE + DRAM_SCTLR, read32(F1C100S_DRAM_BASE + DRAM_SCTLR) | 0x1); + while((read32(F1C100S_DRAM_BASE + DRAM_SCTLR) & 0x1) && time--) + { + if(time == 0) + return 0; + } + return 1; +} + +static int dram_delay_scan(void) +{ + unsigned int time = 0xffffff; + + write32(F1C100S_DRAM_BASE + DRAM_DDLYR, read32(F1C100S_DRAM_BASE + DRAM_DDLYR) | 0x1); + while((read32(F1C100S_DRAM_BASE + DRAM_DDLYR) & 0x1) && time--) + { + if(time == 0) + return 0; + } + return 1; +} + +static void dram_set_autofresh_cycle(uint32_t clk) +{ + uint32_t val = 0; + uint32_t row = 0; + uint32_t temp = 0; + + row = read32(F1C100S_DRAM_BASE + DRAM_SCONR); + row &= 0x1e0; + row >>= 0x5; + + if(row == 0xc) + { + if(clk >= 1000000) + { + temp = clk + (clk >> 3) + (clk >> 4) + (clk >> 5); + while(temp >= (10000000 >> 6)) + { + temp -= (10000000 >> 6); + val++; + } + } + else + { + val = (clk * 499) >> 6; + } + } + else if(row == 0xb) + { + if(clk >= 1000000) + { + temp = clk + (clk >> 3) + (clk >> 4) + (clk >> 5); + while(temp >= (10000000 >> 7)) + { + temp -= (10000000 >> 7); + val++; + } + } + else + { + val = (clk * 499) >> 5; + } + } + write32(F1C100S_DRAM_BASE + DRAM_SREFR, val); +} + +static int dram_para_setup(struct dram_para_t * para) +{ + uint32_t val = 0; + + val = (para->ddr8_remap) | + (0x1 << 1) | + ((para->bank_size >> 2) << 3) | + ((para->cs_num >> 1) << 4) | + ((para->row_width - 1) << 5) | + ((para->col_width - 1) << 9) | + ((para->sdr_ddr ? (para->bwidth >> 4) : (para->bwidth >> 5)) << 13) | + (para->access_mode << 15) | + (para->sdr_ddr << 16); + + write32(F1C100S_DRAM_BASE + DRAM_SCONR, val); + write32(F1C100S_DRAM_BASE + DRAM_SCTLR, read32(F1C100S_DRAM_BASE + DRAM_SCTLR) | (0x1 << 19)); + return dram_initial(); +} + +static uint32_t dram_check_delay(uint32_t bwidth) +{ + uint32_t dsize; + uint32_t i,j; + uint32_t num = 0; + uint32_t dflag = 0; + + dsize = ((bwidth == 16) ? 4 : 2); + for(i = 0; i < dsize; i++) + { + if(i == 0) + dflag = read32(F1C100S_DRAM_BASE + DRAM_DRPTR0); + else if(i == 1) + dflag = read32(F1C100S_DRAM_BASE + DRAM_DRPTR1); + else if(i == 2) + dflag = read32(F1C100S_DRAM_BASE + DRAM_DRPTR2); + else if(i == 3) + dflag = read32(F1C100S_DRAM_BASE + DRAM_DRPTR3); + + for(j = 0; j < 32; j++) + { + if(dflag & 0x1) + num++; + dflag >>= 1; + } + } + return num; +} + +static int sdr_readpipe_scan(void) +{ + uint32_t k = 0; + + for(k = 0; k < 32; k++) + { + write32(0x80000000 + 4 * k, k); + } + for(k = 0; k < 32; k++) + { + if(read32(0x80000000 + 4 * k) != k) + return 0; + } + return 1; +} + +static uint32_t sdr_readpipe_select(void) +{ + uint32_t value = 0; + uint32_t i = 0; + for(i = 0; i < 8; i++) + { + write32(F1C100S_DRAM_BASE + DRAM_SCTLR, (read32(F1C100S_DRAM_BASE + DRAM_SCTLR) & (~(0x7 << 6))) | (i << 6)); + if(sdr_readpipe_scan()) + { + value = i; + return value; + } + } + return value; +} + +static uint32_t dram_check_type(struct dram_para_t * para) +{ + uint32_t val = 0; + uint32_t times = 0; + uint32_t i; + + for(i = 0; i < 8; i++) + { + val = read32(F1C100S_DRAM_BASE + DRAM_SCTLR); + val &= ~(0x7 << 6); + val |= (i << 6); + write32(F1C100S_DRAM_BASE + DRAM_SCTLR, val); + + dram_delay_scan(); + if(read32(F1C100S_DRAM_BASE + DRAM_DDLYR) & 0x30) + times++; + } + + if(times == 8) + { + para->sdr_ddr = DRAM_TYPE_SDR; + return 0; + } + else + { + para->sdr_ddr = DRAM_TYPE_DDR; + return 1; + } +} + +static uint32_t dram_scan_readpipe(struct dram_para_t * para) +{ + uint32_t i, rp_best = 0, rp_val = 0; + uint32_t val = 0; + uint32_t readpipe[8]; + + if(para->sdr_ddr == DRAM_TYPE_DDR) + { + for(i = 0; i < 8; i++) + { + val = read32(F1C100S_DRAM_BASE + DRAM_SCTLR); + val &= ~(0x7 << 6); + val |= (i << 6); + write32(F1C100S_DRAM_BASE + DRAM_SCTLR, val); + dram_delay_scan(); + readpipe[i] = 0; + if((((read32(F1C100S_DRAM_BASE + DRAM_DDLYR) >> 4) & 0x3) == 0x0) && + (((read32(F1C100S_DRAM_BASE + DRAM_DDLYR) >> 4) & 0x1) == 0x0)) + { + readpipe[i] = dram_check_delay(para->bwidth); + } + if(rp_val < readpipe[i]) + { + rp_val = readpipe[i]; + rp_best = i; + } + } + val = read32(F1C100S_DRAM_BASE + DRAM_SCTLR); + val &= ~(0x7 << 6); + val |= (rp_best << 6); + write32(F1C100S_DRAM_BASE + DRAM_SCTLR, val); + dram_delay_scan(); + } + else + { + val = read32(F1C100S_DRAM_BASE + DRAM_SCONR); + val &= (~(0x1 << 16)); + val &= (~(0x3 << 13)); + write32(F1C100S_DRAM_BASE + DRAM_SCONR, val); + rp_best = sdr_readpipe_select(); + val = read32(F1C100S_DRAM_BASE + DRAM_SCTLR); + val &= ~(0x7 << 6); + val |= (rp_best << 6); + write32(F1C100S_DRAM_BASE + DRAM_SCTLR, val); + } + return 0; +} + +static uint32_t dram_get_dram_size(struct dram_para_t * para) +{ + uint32_t colflag = 10, rowflag = 13; + uint32_t i = 0; + uint32_t val1 = 0; + uint32_t count = 0; + uint32_t addr1, addr2; + + para->col_width = colflag; + para->row_width = rowflag; + dram_para_setup(para); + dram_scan_readpipe(para); + for(i = 0; i < 32; i++) + { + *((uint32_t *)(0x80000200 + i)) = 0x11111111; + *((uint32_t *)(0x80000600 + i)) = 0x22222222; + } + for(i = 0; i < 32; i++) + { + val1 = *((uint32_t *)(0x80000200 + i)); + if(val1 == 0x22222222) + count++; + } + if(count == 32) + { + colflag = 9; + } + else + { + colflag = 10; + } + count = 0; + para->col_width = colflag; + para->row_width = rowflag; + dram_para_setup(para); + if(colflag == 10) + { + addr1 = 0x80400000; + addr2 = 0x80c00000; + } + else + { + addr1 = 0x80200000; + addr2 = 0x80600000; + } + for(i = 0; i < 32; i++) + { + *((uint32_t *)(addr1 + i)) = 0x33333333; + *((uint32_t *)(addr2 + i)) = 0x44444444; + } + for(i = 0; i < 32; i++) + { + val1 = *((uint32_t *)(addr1 + i)); + if(val1 == 0x44444444) + { + count++; + } + } + if(count == 32) + { + rowflag = 12; + } + else + { + rowflag = 13; + } + para->col_width = colflag; + para->row_width = rowflag; + if(para->row_width != 13) + { + para->size = 16; + } + else if(para->col_width == 10) + { + para->size = 64; + } + else + { + para->size = 32; + } + dram_set_autofresh_cycle(para->clk); + para->access_mode = 0; + dram_para_setup(para); + + return 0; +} + +static int dram_init(struct dram_para_t * para) +{ + uint32_t val = 0; + uint32_t i; + + write32(0x01c20800 + 0x24, read32(0x01c20800 + 0x24) | (0x7 << 12)); + dram_delay(5); + if(((para->cas) >> 3) & 0x1) + { + write32(0x01c20800 + 0x2c4, read32(0x01c20800 + 0x2c4) | (0x1 << 23) | (0x20 << 17)); + } + if((para->clk >= 144) && (para->clk <= 180)) + { + write32(0x01c20800 + 0x2c0, 0xaaa); + } + if(para->clk >= 180) + { + write32(0x01c20800 + 0x2c0, 0xfff); + } + if((para->clk) <= 96) + { + val = (0x1 << 0) | (0x0 << 4) | (((para->clk * 2) / 12 - 1) << 8) | (0x1u << 31); + } + else + { + val = (0x0 << 0) | (0x0 << 4) | (((para->clk * 2) / 24 - 1) << 8) | (0x1u << 31); + } + + if(para->cas & (0x1 << 4)) + { + write32(F1C100S_CCU_BASE + CCU_PLL_DDR0_PAT, 0xd1303333); + } + else if(para->cas & (0x1 << 5)) + { + write32(F1C100S_CCU_BASE + CCU_PLL_DDR0_PAT, 0xcce06666); + } + else if(para->cas & (0x1 << 6)) + { + write32(F1C100S_CCU_BASE + CCU_PLL_DDR0_PAT, 0xc8909999); + } + else if(para->cas & (0x1 << 7)) + { + write32(F1C100S_CCU_BASE + CCU_PLL_DDR0_PAT, 0xc440cccc); + } + if(para->cas & (0xf << 4)) + { + val |= 0x1 << 24; + } + write32(F1C100S_CCU_BASE + CCU_PLL_DDR_CTRL, val); + write32(F1C100S_CCU_BASE + CCU_PLL_DDR_CTRL, read32(F1C100S_CCU_BASE + CCU_PLL_DDR_CTRL) | (0x1 << 20)); + while((read32(F1C100S_CCU_BASE + CCU_PLL_DDR_CTRL) & (1 << 28)) == 0); + dram_delay(5); + write32(F1C100S_CCU_BASE + CCU_BUS_CLK_GATE0, read32(F1C100S_CCU_BASE + CCU_BUS_CLK_GATE0) | (0x1 << 14)); + write32(F1C100S_CCU_BASE + CCU_BUS_SOFT_RST0, read32(F1C100S_CCU_BASE + CCU_BUS_SOFT_RST0) & ~(0x1 << 14)); + for(i = 0; i < 10; i++) + continue; + write32(F1C100S_CCU_BASE + CCU_BUS_SOFT_RST0, read32(F1C100S_CCU_BASE + CCU_BUS_SOFT_RST0) | (0x1 << 14)); + + val = read32(0x01c20800 + 0x2c4); + (para->sdr_ddr == DRAM_TYPE_DDR) ? (val |= (0x1 << 16)) : (val &= ~(0x1 << 16)); + write32(0x01c20800 + 0x2c4, val); + + val = (SDR_T_CAS << 0) | (SDR_T_RAS << 3) | (SDR_T_RCD << 7) | (SDR_T_RP << 10) | (SDR_T_WR << 13) | (SDR_T_RFC << 15) | (SDR_T_XSR << 19) | (SDR_T_RC << 28); + write32(F1C100S_DRAM_BASE + DRAM_STMG0R, val); + val = (SDR_T_INIT << 0) | (SDR_T_INIT_REF << 16) | (SDR_T_WTR << 20) | (SDR_T_RRD << 22) | (SDR_T_XP << 25); + write32(F1C100S_DRAM_BASE + DRAM_STMG1R, val); + dram_para_setup(para); + dram_check_type(para); + + val = read32(0x01c20800 + 0x2c4); + (para->sdr_ddr == DRAM_TYPE_DDR) ? (val |= (0x1 << 16)) : (val &= ~(0x1 << 16)); + write32(0x01c20800 + 0x2c4, val); + + dram_set_autofresh_cycle(para->clk); + dram_scan_readpipe(para); + dram_get_dram_size(para); + + for(i = 0; i < 128; i++) + { + *((volatile uint32_t *)(para->base + 4 * i)) = para->base + 4 * i; + } + + for(i = 0; i < 128; i++) + { + if(*((volatile uint32_t *)(para->base + 4 * i)) != (para->base + 4 * i)) + return 0; + } + return 1; +} + +void sys_dram_init(void) +{ + struct dram_para_t para; + uint32_t * dsz = (void *)0x0000005c; + + para.base = 0x80000000; + para.size = 32; + para.clk = PLL_DDR_CLK / 1000000; + para.access_mode = 1; + para.cs_num = 1; + para.ddr8_remap = 0; + para.sdr_ddr = DRAM_TYPE_DDR; + para.bwidth = 16; + para.col_width = 10; + para.row_width = 13; + para.bank_size = 4; + para.cas = 0x3; + + if((dsz[0] >> 24) == 'X') + return; + if(dram_init(¶)) + dsz[0] = (((uint32_t)'X') << 24) | (para.size << 0); +} diff --git a/hw/mcu/allwinner/f1c100s/machine/sys-mmu.c b/hw/mcu/allwinner/f1c100s/machine/sys-mmu.c new file mode 100644 index 000000000..3c89c7255 --- /dev/null +++ b/hw/mcu/allwinner/f1c100s/machine/sys-mmu.c @@ -0,0 +1,57 @@ +/* + * sys-mmu.c + * + * Copyright(c) 2007-2018 Jianjun Jiang <8192542@qq.com> + * Official site: http://xboot.org + * Mobile phone: +86-18665388956 + * QQ: 8192542 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include + +static void map_l1_section(uint32_t * ttb, virtual_addr_t virt, physical_addr_t phys, physical_size_t size, int type) +{ + physical_size_t i; + + virt >>= 20; + phys >>= 20; + size >>= 20; + type &= 0x3; + + for(i = size; i > 0; i--, virt++, phys++) + ttb[virt] = (phys << 20) | (0x3 << 10) | (0x0 << 5) | (type << 2) | (0x2 << 0); +} + +void sys_mmu_init(void) +{ + uint32_t * ttb = (uint32_t *)(0x80000000 + SZ_1M * 31); + + map_l1_section(ttb, 0x00000000, 0x00000000, SZ_2G, 0); + map_l1_section(ttb, 0x80000000, 0x80000000, SZ_2G, 0); + map_l1_section(ttb, 0x80000000, 0x80000000, SZ_1M * 32, 3); + + arm32_ttb_set((uint32_t)(ttb)); + arm32_tlb_invalidate(); + arm32_domain_set(0x3); + arm32_mmu_enable(); + arm32_icache_enable(); + arm32_dcache_enable(); +} \ No newline at end of file diff --git a/hw/mcu/allwinner/f1c100s/machine/sys-spi-flash.c b/hw/mcu/allwinner/f1c100s/machine/sys-spi-flash.c new file mode 100644 index 000000000..5c3b0f0aa --- /dev/null +++ b/hw/mcu/allwinner/f1c100s/machine/sys-spi-flash.c @@ -0,0 +1,204 @@ +/* + * sys-spi-flash.c + * + * Copyright(c) 2007-2018 Jianjun Jiang <8192542@qq.com> + * Official site: http://xboot.org + * Mobile phone: +86-18665388956 + * QQ: 8192542 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include + +enum { + SPI_GCR = 0x04, + SPI_TCR = 0x08, + SPI_IER = 0x10, + SPI_ISR = 0x14, + SPI_FCR = 0x18, + SPI_FSR = 0x1c, + SPI_WCR = 0x20, + SPI_CCR = 0x24, + SPI_MBC = 0x30, + SPI_MTC = 0x34, + SPI_BCC = 0x38, + SPI_TXD = 0x200, + SPI_RXD = 0x300, +}; + +void sys_spi_flash_init(void) +{ + virtual_addr_t addr; + uint32_t val; + + /* Config GPIOC0, GPIOC1, GPIOC2 and GPIOC3 */ + addr = 0x01c20848 + 0x00; + val = read32(addr); + val &= ~(0xf << ((0 & 0x7) << 2)); + val |= ((0x2 & 0x7) << ((0 & 0x7) << 2)); + write32(addr, val); + + val = read32(addr); + val &= ~(0xf << ((1 & 0x7) << 2)); + val |= ((0x2 & 0x7) << ((1 & 0x7) << 2)); + write32(addr, val); + + val = read32(addr); + val &= ~(0xf << ((2 & 0x7) << 2)); + val |= ((0x2 & 0x7) << ((2 & 0x7) << 2)); + write32(addr, val); + + val = read32(addr); + val &= ~(0xf << ((3 & 0x7) << 2)); + val |= ((0x2 & 0x7) << ((3 & 0x7) << 2)); + write32(addr, val); + + /* Deassert spi0 reset */ + addr = 0x01c202c0; + val = read32(addr); + val |= (1 << 20); + write32(addr, val); + + /* Open the spi0 bus gate */ + addr = 0x01c20000 + 0x60; + val = read32(addr); + val |= (1 << 20); + write32(addr, val); + + /* Set spi clock rate control register, divided by 4 */ + addr = 0x01c05000; + write32(addr + SPI_CCR, 0x00001001); + + /* Enable spi0 and do a soft reset */ + addr = 0x01c05000; + val = read32(addr + SPI_GCR); + val |= (1 << 31) | (1 << 7) | (1 << 1) | (1 << 0); + write32(addr + SPI_GCR, val); + while(read32(addr + SPI_GCR) & (1 << 31)); + + val = read32(addr + SPI_TCR); + val &= ~(0x3 << 0); + val |= (1 << 6) | (1 << 2); + write32(addr + SPI_TCR, val); + + val = read32(addr + SPI_FCR); + val |= (1 << 31) | (1 << 15); + write32(addr + SPI_FCR, val); +} + +void sys_spi_flash_exit(void) +{ + virtual_addr_t addr = 0x01c05000; + uint32_t val; + + /* Disable the spi0 controller */ + val = read32(addr + SPI_GCR); + val &= ~((1 << 1) | (1 << 0)); + write32(addr + SPI_GCR, val); +} + +static void sys_spi_select(void) +{ + virtual_addr_t addr = 0x01c05000; + uint32_t val; + + val = read32(addr + SPI_TCR); + val &= ~((0x3 << 4) | (0x1 << 7)); + val |= ((0 & 0x3) << 4) | (0x0 << 7); + write32(addr + SPI_TCR, val); +} + +static void sys_spi_deselect(void) +{ + virtual_addr_t addr = 0x01c05000; + uint32_t val; + + val = read32(addr + SPI_TCR); + val &= ~((0x3 << 4) | (0x1 << 7)); + val |= ((0 & 0x3) << 4) | (0x1 << 7); + write32(addr + SPI_TCR, val); +} + +static void sys_spi_write_txbuf(uint8_t * buf, int len) +{ + virtual_addr_t addr = 0x01c05000; + int i; + + if(!buf) + len = 0; + + write32(addr + SPI_MTC, len & 0xffffff); + write32(addr + SPI_BCC, len & 0xffffff); + for(i = 0; i < len; ++i) + write8(addr + SPI_TXD, *buf++); +} + +static int sys_spi_transfer(void * txbuf, void * rxbuf, int len) +{ + virtual_addr_t addr = 0x01c05000; + int count = len; + uint8_t * tx = txbuf; + uint8_t * rx = rxbuf; + uint8_t val; + unsigned int n, i; + + while(count > 0) + { + n = (count <= 64) ? count : 64; + write32(addr + SPI_MBC, n); + sys_spi_write_txbuf(tx, n); + write32(addr + SPI_TCR, read32(addr + SPI_TCR) | (1 << 31)); + + while((read32(addr + SPI_FSR) & 0xff) < n); + for(i = 0; i < n; i++) + { + val = read8(addr + SPI_RXD); + if(rx) + *rx++ = val; + } + + if(tx) + tx += n; + count -= n; + } + return len; +} + +static int sys_spi_write_then_read(void * txbuf, int txlen, void * rxbuf, int rxlen) +{ + if(sys_spi_transfer(txbuf, NULL, txlen) != txlen) + return -1; + if(sys_spi_transfer(NULL, rxbuf, rxlen) != rxlen) + return -1; + return 0; +} + +void sys_spi_flash_read(int addr, void * buf, int count) +{ + uint8_t tx[4]; + + tx[0] = 0x03; + tx[1] = (uint8_t)(addr >> 16); + tx[2] = (uint8_t)(addr >> 8); + tx[3] = (uint8_t)(addr >> 0); + sys_spi_select(); + sys_spi_write_then_read(tx, 4, buf, count); + sys_spi_deselect(); +} diff --git a/hw/mcu/allwinner/f1c100s/machine/sys-uart.c b/hw/mcu/allwinner/f1c100s/machine/sys-uart.c new file mode 100644 index 000000000..0e61627b7 --- /dev/null +++ b/hw/mcu/allwinner/f1c100s/machine/sys-uart.c @@ -0,0 +1,83 @@ +/* + * sys-uart.c + * + * Copyright(c) 2007-2018 Jianjun Jiang <8192542@qq.com> + * Official site: http://xboot.org + * Mobile phone: +86-18665388956 + * QQ: 8192542 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include + +void sys_uart_init(void) +{ + virtual_addr_t addr; + uint32_t val; + + /* Config GPIOE1 and GPIOE0 to txd0 and rxd0 */ + addr = 0x01c20890 + 0x00; + val = read32(addr); + val &= ~(0xf << ((1 & 0x7) << 2)); + val |= ((0x5 & 0x7) << ((1 & 0x7) << 2)); + write32(addr, val); + + val = read32(addr); + val &= ~(0xf << ((0 & 0x7) << 2)); + val |= ((0x5 & 0x7) << ((0 & 0x7) << 2)); + write32(addr, val); + + /* Open the clock gate for uart0 */ + addr = 0x01c20068; + val = read32(addr); + val |= 1 << 20; + write32(addr, val); + + /* Deassert uart0 reset */ + addr = 0x01c202d0; + val = read32(addr); + val |= 1 << 20; + write32(addr, val); + + /* Config uart0 to 115200-8-1-0 */ + addr = 0x01c25000; + write32(addr + 0x04, 0x0); + write32(addr + 0x08, 0xf7); + write32(addr + 0x10, 0x0); + val = read32(addr + 0x0c); + val |= (1 << 7); + write32(addr + 0x0c, val); + write32(addr + 0x00, 0x36 & 0xff); + write32(addr + 0x04, (0x36 >> 8) & 0xff); + val = read32(addr + 0x0c); + val &= ~(1 << 7); + write32(addr + 0x0c, val); + val = read32(addr + 0x0c); + val &= ~0x1f; + val |= (0x3 << 0) | (0 << 2) | (0x0 << 3); + write32(addr + 0x0c, val); +} + +void sys_uart_putc(char c) +{ + virtual_addr_t addr = 0x01c25000; + + while((read32(addr + 0x7c) & (0x1 << 1)) == 0); + write32(addr + 0x00, c); +} diff --git a/src/portable/sunxi/dcd_sunxi_musb.c b/src/portable/sunxi/dcd_sunxi_musb.c index b13842de1..71d0b92b2 100644 --- a/src/portable/sunxi/dcd_sunxi_musb.c +++ b/src/portable/sunxi/dcd_sunxi_musb.c @@ -4,6 +4,7 @@ #include #include #include "musb_def.h" +#include "bsp/board.h" typedef uint32_t u32; typedef uint16_t u16; @@ -69,8 +70,8 @@ static void usb_phy_write(int addr, int data, int len) static void delay_ms(uint32_t ms) { #if CFG_TUSB_OS == OPT_OS_NONE - int cnt = ms * 1000 * 1000 / 2; - while (cnt--) asm("nop"); + int now = board_millis(); + while (board_millis() - now <= ms) asm("nop"); #else osal_task_delay(ms); #endif From 28fb51c180e644cfb0be4b980b71850b19fe2ab9 Mon Sep 17 00:00:00 2001 From: Yunhao Tian Date: Sat, 4 Dec 2021 18:08:23 +0800 Subject: [PATCH 045/504] Add TODO to README --- hw/bsp/f1c100s/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/bsp/f1c100s/README.md b/hw/bsp/f1c100s/README.md index a4865b925..893b32ea9 100644 --- a/hw/bsp/f1c100s/README.md +++ b/hw/bsp/f1c100s/README.md @@ -14,4 +14,5 @@ To enter FEL mode, you have to press BOOT button, then press RESET once, and rel ## TODO * Test on Tiny200 v2 (F1C200s) * Make it able to load .bin directly to SPI Flash and boot -* Add F1C100s to `#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX` high speed MCU check in examples (maybe we should extract the logic?) \ No newline at end of file +* Add F1C100s to `#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX` high speed MCU check in examples (maybe we should extract the logic?) +* `cdc_msc` example is not working. Device is only echoing the first character. \ No newline at end of file From 48e1f6d8990e450783f4887e41ce58fe0e463953 Mon Sep 17 00:00:00 2001 From: Valentin Milea Date: Sat, 4 Dec 2021 16:04:48 +0200 Subject: [PATCH 046/504] Handle the closing of endpoints on RP2040 --- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 28 ++++++++++++++++---- src/portable/raspberrypi/rp2040/rp2040_usb.c | 4 ++- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index e084478e0..8be16ad22 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -83,7 +83,7 @@ static void _hw_endpoint_alloc(struct hw_endpoint *ep, uint8_t transfer_type) assert(((uintptr_t )next_buffer_ptr & 0b111111u) == 0); uint dpram_offset = hw_data_offset(ep->hw_data_buf); - assert(hw_data_offset(next_buffer_ptr) <= USB_DPRAM_MAX); + hard_assert(hw_data_offset(next_buffer_ptr) <= USB_DPRAM_MAX); pico_info(" Alloced %d bytes at offset 0x%x (0x%p)\r\n", size, dpram_offset, ep->hw_data_buf); @@ -93,7 +93,6 @@ static void _hw_endpoint_alloc(struct hw_endpoint *ep, uint8_t transfer_type) *ep->endpoint_control = reg; } -#if 0 // todo unused static void _hw_endpoint_close(struct hw_endpoint *ep) { // Clear hardware registers and then zero the struct @@ -103,6 +102,22 @@ static void _hw_endpoint_close(struct hw_endpoint *ep) *ep->buffer_control = 0; // Clear any endpoint state memset(ep, 0, sizeof(struct hw_endpoint)); + + // Reclaim buffer space if all endpoints are closed + bool reclaim_buffers = true; + for ( uint8_t i = 1; i < USB_MAX_ENDPOINTS; i++ ) + { + if (hw_endpoint_get_by_num(i, TUSB_DIR_OUT)->hw_data_buf != NULL || hw_endpoint_get_by_num(i, TUSB_DIR_IN)->hw_data_buf != NULL) + { + reclaim_buffers = false; + break; + } + } + if (reclaim_buffers) + { + pico_info(" reclaim buffer space\n"); + next_buffer_ptr = &usb_dpram->epx_data[0]; + } } static void hw_endpoint_close(uint8_t ep_addr) @@ -110,7 +125,6 @@ static void hw_endpoint_close(uint8_t ep_addr) struct hw_endpoint *ep = hw_endpoint_get_by_addr(ep_addr); _hw_endpoint_close(ep); } -#endif static void hw_endpoint_init(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type) { @@ -224,6 +238,8 @@ static void reset_non_control_endpoints(void) // clear non-control hw endpoints tu_memclr(hw_endpoints[1], sizeof(hw_endpoints) - 2*sizeof(hw_endpoint_t)); + + pico_info(" reclaim buffer space\n"); next_buffer_ptr = &usb_dpram->epx_data[0]; } @@ -479,10 +495,12 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) { (void) rhport; - (void) ep_addr; - // usbd.c says: In progress transfers on this EP may be delivered after this call pico_trace("dcd_edpt_close %02x\n", ep_addr); + + // usbd.c says: In progress transfers on this EP may be delivered after this call. + // If the endpoint is no longer active when the transfer event is delivered, it will be ignored. + hw_endpoint_close(ep_addr); } void dcd_int_handler(uint8_t rhport) diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index c9e2f6b26..0a943b676 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -294,7 +294,9 @@ bool hw_endpoint_xfer_continue(struct hw_endpoint *ep) // Part way through a transfer if (!ep->active) { - panic("Can't continue xfer on inactive ep %d %s", tu_edpt_number(ep->ep_addr), ep_dir_string); + pico_info("Ignore xfer on inactive ep %d %s", tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]); + _hw_endpoint_lock_update(ep, -1); + return false; } // Update EP struct from hardware state From fa0e4d91f9e22b8c7b8f561fe225116b5f6a14a5 Mon Sep 17 00:00:00 2001 From: Yunhao Tian Date: Sun, 5 Dec 2021 18:07:35 +0800 Subject: [PATCH 047/504] Save current EP before querying other EPs --- src/portable/sunxi/dcd_sunxi_musb.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/portable/sunxi/dcd_sunxi_musb.c b/src/portable/sunxi/dcd_sunxi_musb.c index 71d0b92b2..0bb031a80 100644 --- a/src/portable/sunxi/dcd_sunxi_musb.c +++ b/src/portable/sunxi/dcd_sunxi_musb.c @@ -185,6 +185,11 @@ static void USBC_SelectActiveEp(u8 ep_index) USBC_Writeb(ep_index, USBC_REG_EPIND(USBC0_BASE)); } +static u8 USBC_GetActiveEp(void) +{ + return USBC_Readb(USBC_REG_EPIND(USBC0_BASE)); +} + static void __USBC_Dev_ep0_SendStall(void) { USBC_REG_set_bit_w(USBC_BP_CSR0_D_SEND_STALL, USBC_REG_CSR0(USBC0_BASE)); @@ -387,6 +392,8 @@ static unsigned find_free_memory(uint_fast16_t size_in_log2_minus3) { free_block_t free_blocks[2 * (DCD_ATTR_ENDPOINT_MAX - 1)]; unsigned num_blocks = 1; + /* Backup current EP to restore later */ + u8 backup_ep = USBC_GetActiveEp(); /* Initialize free memory block list */ free_blocks[0].beg = 64 / 8; @@ -416,6 +423,8 @@ static unsigned find_free_memory(uint_fast16_t size_in_log2_minus3) } print_block_list(free_blocks, num_blocks); + USBC_SelectActiveEp(backup_ep); + /* Find the best fit memory block */ uint_fast16_t size_in_8byte_unit = 1 << size_in_log2_minus3; free_block_t const *min = NULL; From 64b81fd4d316ff8e0390c843bdff236ed4151147 Mon Sep 17 00:00:00 2001 From: Yunhao Tian Date: Sun, 5 Dec 2021 18:08:01 +0800 Subject: [PATCH 048/504] Close all EPs upon reset --- src/portable/sunxi/dcd_sunxi_musb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/portable/sunxi/dcd_sunxi_musb.c b/src/portable/sunxi/dcd_sunxi_musb.c index 0bb031a80..2150403a9 100644 --- a/src/portable/sunxi/dcd_sunxi_musb.c +++ b/src/portable/sunxi/dcd_sunxi_musb.c @@ -839,6 +839,7 @@ void dcd_init(uint8_t rhport) USBC_ForceIdToHigh(); // Force device mode USBC_ForceVbusValidToHigh(); USBC_SelectBus(USBC_IO_TYPE_PIO, 0, 0); + dcd_edpt_close_all(rhport); #if TUD_OPT_HIGH_SPEED USBC_REG_set_bit_b(USBC_BP_POWER_D_HIGH_SPEED_EN, USBC_REG_PCTL(USBC0_BASE)); From 702698ee293727d31efb0c7134a15a261d878cb9 Mon Sep 17 00:00:00 2001 From: Yunhao Tian Date: Sun, 5 Dec 2021 18:18:41 +0800 Subject: [PATCH 049/504] Add FIFO size check --- src/portable/sunxi/dcd_sunxi_musb.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/portable/sunxi/dcd_sunxi_musb.c b/src/portable/sunxi/dcd_sunxi_musb.c index 2150403a9..ecc076658 100644 --- a/src/portable/sunxi/dcd_sunxi_musb.c +++ b/src/portable/sunxi/dcd_sunxi_musb.c @@ -388,6 +388,12 @@ static inline void print_block_list(free_block_t const *blk, unsigned num) #define print_block_list(a,b) #endif +#if CFG_TUSB_MCU == OPT_MCU_F1C100S +#define USB_FIFO_SIZE_KB 2 +#else +#error "Unsupported MCU" +#endif + static unsigned find_free_memory(uint_fast16_t size_in_log2_minus3) { free_block_t free_blocks[2 * (DCD_ATTR_ENDPOINT_MAX - 1)]; @@ -397,7 +403,7 @@ static unsigned find_free_memory(uint_fast16_t size_in_log2_minus3) /* Initialize free memory block list */ free_blocks[0].beg = 64 / 8; - free_blocks[0].end = (4 << 10) / 8; /* 4KiB / 8 bytes */ + free_blocks[0].end = (USB_FIFO_SIZE_KB << 10) / 8; /* 2KiB / 8 bytes */ for (int i = 1; i < DCD_ATTR_ENDPOINT_MAX; ++i) { uint_fast16_t addr; int num; From f308603a3aeffcf77e83d2cfb1c76a28e543272d Mon Sep 17 00:00:00 2001 From: Yunhao Tian Date: Sun, 5 Dec 2021 22:31:09 +0800 Subject: [PATCH 050/504] Fix a typo that leads to incorrect RX handling --- src/portable/sunxi/dcd_sunxi_musb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/portable/sunxi/dcd_sunxi_musb.c b/src/portable/sunxi/dcd_sunxi_musb.c index ecc076658..420ce1de0 100644 --- a/src/portable/sunxi/dcd_sunxi_musb.c +++ b/src/portable/sunxi/dcd_sunxi_musb.c @@ -598,7 +598,7 @@ static bool handle_xfer_out(uint_fast8_t ep_addr) pipe->buf = buf + len; } pipe->remaining = rem - len; - __USBC_Dev_ep0_ReadDataComplete(); + __USBC_Dev_Rx_ReadDataComplete(); } if ((len < mps) || (rem == len)) { pipe->buf = NULL; From 1ffc366aa9bb9c2dda8210956c2ac9a6fbafc88b Mon Sep 17 00:00:00 2001 From: Yunhao Tian Date: Sun, 5 Dec 2021 22:40:05 +0800 Subject: [PATCH 051/504] Change FIFO size to 4KB (not sure) The datasheet says 2KB FIFO, but accroding to many code examples, the F1C100s has at least 4KB of FIFO memory. This is working with cdc_msc example, but I'm not sure, this should be checked. --- src/portable/sunxi/dcd_sunxi_musb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/portable/sunxi/dcd_sunxi_musb.c b/src/portable/sunxi/dcd_sunxi_musb.c index 420ce1de0..e164f2c19 100644 --- a/src/portable/sunxi/dcd_sunxi_musb.c +++ b/src/portable/sunxi/dcd_sunxi_musb.c @@ -389,7 +389,7 @@ static inline void print_block_list(free_block_t const *blk, unsigned num) #endif #if CFG_TUSB_MCU == OPT_MCU_F1C100S -#define USB_FIFO_SIZE_KB 2 +#define USB_FIFO_SIZE_KB 4 #else #error "Unsupported MCU" #endif From 96979a2c4a43902a3051c678858e788e7ffc8c60 Mon Sep 17 00:00:00 2001 From: Yunhao Tian Date: Mon, 6 Dec 2021 19:56:27 +0800 Subject: [PATCH 052/504] Fix handling of RXRDY bit --- src/portable/sunxi/dcd_sunxi_musb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/portable/sunxi/dcd_sunxi_musb.c b/src/portable/sunxi/dcd_sunxi_musb.c index e164f2c19..be1847b21 100644 --- a/src/portable/sunxi/dcd_sunxi_musb.c +++ b/src/portable/sunxi/dcd_sunxi_musb.c @@ -598,12 +598,12 @@ static bool handle_xfer_out(uint_fast8_t ep_addr) pipe->buf = buf + len; } pipe->remaining = rem - len; - __USBC_Dev_Rx_ReadDataComplete(); } if ((len < mps) || (rem == len)) { pipe->buf = NULL; return NULL != buf; } + __USBC_Dev_Rx_ReadDataComplete(); return false; } From ef879e8a8a43dfa34160f50d7f432c3140dec7fa Mon Sep 17 00:00:00 2001 From: Valentin Milea Date: Mon, 6 Dec 2021 18:49:58 +0200 Subject: [PATCH 053/504] Support disabling feedback format correction #1234 --- src/class/audio/audio_device.c | 3 ++- src/class/audio/audio_device.h | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index d9f2e284e..a461e97c5 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -2248,12 +2248,13 @@ static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // Input value feedback has to be in 16.16 format - the format will be converted according to speed settings automatically +// unless format correction is disabled. bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) { TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); // Format the feedback value -#if !TUD_OPT_HIGH_SPEED +#if !TUD_OPT_HIGH_SPEED && !CFG_TUD_AUDIO_DISABLE_FEEDBACK_FORMAT_CORRECTION uint8_t * fb = (uint8_t *) &_audiod_fct[func_id].fb_val; // For FS format is 10.14 diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index 5a469523c..731fd6c01 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -186,6 +186,11 @@ #define CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP 0 // Feedback - 0 or 1 #endif +// Disable/enable conversion from 16.16 to 10.14 format on high-speed devices. See tud_audio_n_fb_set(). +#ifndef CFG_TUD_AUDIO_DISABLE_FEEDBACK_FORMAT_CORRECTION +#define CFG_TUD_AUDIO_DISABLE_FEEDBACK_FORMAT_CORRECTION 0 // 0 or 1 +#endif + // Audio interrupt control EP size - disabled if 0 #ifndef CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN #define CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN 0 // Audio interrupt control - if required - 6 Bytes according to UAC 2 specification (p. 74) @@ -458,6 +463,11 @@ TU_ATTR_WEAK bool tud_audio_fb_done_cb(uint8_t rhport); // Value will be corrected for FS to 10.14 format automatically. // (see Universal Serial Bus Specification Revision 2.0 5.12.4.2). // Feedback value will be sent at FB endpoint interval till it's changed. +// +// Note that the USB Audio 2.0 driver on Windows 10 is not following the spec and expects 16.16 +// format for FS. You can define CFG_TUD_AUDIO_DISABLE_FEEDBACK_FORMAT_CORRECTION=1 as a workaround +// to transmit the feedback value unchanged. Be aware that this might break feedback on other hosts, +// though at least on Linux the ALSA driver will happily accept either format. bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); static inline bool tud_audio_fb_set(uint32_t feedback); #endif From 03835c818361bb6c5eafd8cb51e8a9bb6b4f16fb Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 7 Dec 2021 16:27:48 +0700 Subject: [PATCH 054/504] move hcd_musb.c include to family.mk --- examples/host/cdc_msc_hid/.only.MCU_MSP432E4 | 0 examples/host/cdc_msc_hid/.only.MCU_TM4C123 | 0 examples/host/cdc_msc_hid/Makefile | 3 +-- examples/host/hid_controller/.only.MCU_MSP432E4 | 0 examples/host/hid_controller/.only.MCU_TM4C123 | 0 examples/host/hid_controller/Makefile | 3 +-- hw/bsp/msp432e4/family.mk | 1 + 7 files changed, 3 insertions(+), 4 deletions(-) create mode 100644 examples/host/cdc_msc_hid/.only.MCU_MSP432E4 create mode 100644 examples/host/cdc_msc_hid/.only.MCU_TM4C123 create mode 100644 examples/host/hid_controller/.only.MCU_MSP432E4 create mode 100644 examples/host/hid_controller/.only.MCU_TM4C123 diff --git a/examples/host/cdc_msc_hid/.only.MCU_MSP432E4 b/examples/host/cdc_msc_hid/.only.MCU_MSP432E4 new file mode 100644 index 000000000..e69de29bb diff --git a/examples/host/cdc_msc_hid/.only.MCU_TM4C123 b/examples/host/cdc_msc_hid/.only.MCU_TM4C123 new file mode 100644 index 000000000..e69de29bb diff --git a/examples/host/cdc_msc_hid/Makefile b/examples/host/cdc_msc_hid/Makefile index 8c8735a56..ce0dd1a40 100644 --- a/examples/host/cdc_msc_hid/Makefile +++ b/examples/host/cdc_msc_hid/Makefile @@ -21,7 +21,6 @@ SRC_C += \ src/host/usbh.c \ src/host/usbh_control.c \ src/portable/ohci/ohci.c \ - src/portable/nxp/lpc17_40/hcd_lpc17_40.c \ - src/portable/mentor/musb/hcd_musb.c + src/portable/nxp/lpc17_40/hcd_lpc17_40.c include ../../rules.mk diff --git a/examples/host/hid_controller/.only.MCU_MSP432E4 b/examples/host/hid_controller/.only.MCU_MSP432E4 new file mode 100644 index 000000000..e69de29bb diff --git a/examples/host/hid_controller/.only.MCU_TM4C123 b/examples/host/hid_controller/.only.MCU_TM4C123 new file mode 100644 index 000000000..e69de29bb diff --git a/examples/host/hid_controller/Makefile b/examples/host/hid_controller/Makefile index 909abe8a6..c58df562b 100644 --- a/examples/host/hid_controller/Makefile +++ b/examples/host/hid_controller/Makefile @@ -24,7 +24,6 @@ SRC_C += \ src/host/usbh.c \ src/host/usbh_control.c \ src/portable/ohci/ohci.c \ - src/portable/nxp/lpc17_40/hcd_lpc17_40.c \ - src/portable/mentor/musb/hcd_musb.c + src/portable/nxp/lpc17_40/hcd_lpc17_40.c include ../../rules.mk diff --git a/hw/bsp/msp432e4/family.mk b/hw/bsp/msp432e4/family.mk index b664c4c1b..e3cb90abc 100644 --- a/hw/bsp/msp432e4/family.mk +++ b/hw/bsp/msp432e4/family.mk @@ -23,6 +23,7 @@ MCU_DIR = hw/mcu/ti/msp432e4 SRC_C += \ src/portable/mentor/musb/dcd_musb.c \ + src/portable/mentor/musb/hcd_musb.c \ $(MCU_DIR)/Source/system_msp432e401y.c INC += \ From 8e0400d531bbbb8faf45576a3b5e55be9406cf6b Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 7 Dec 2021 16:28:24 +0700 Subject: [PATCH 055/504] change uart baudrate for tm4c123 to 115200 --- hw/bsp/tm4c123/family.c | 25 ++++++++++++++++++------- hw/bsp/tm4c123/family.mk | 1 + 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/hw/bsp/tm4c123/family.c b/hw/bsp/tm4c123/family.c index 048832dc9..449781ce1 100644 --- a/hw/bsp/tm4c123/family.c +++ b/hw/bsp/tm4c123/family.c @@ -7,7 +7,13 @@ //--------------------------------------------------------------------+ void USB0_Handler(void) { +#if TUSB_OPT_HOST_ENABLED + tuh_int_handler(0); +#endif + +#if TUSB_OPT_DEVICE_ENABLED tud_int_handler(0); +#endif } //--------------------------------------------------------------------+ @@ -23,10 +29,12 @@ static void board_uart_init (void) 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 - /** BAUDRATE = 9600 bits per second, refer manual for calculation **/ + // BAUDRATE = 115200, with SystemCoreClock = 50 Mhz refer manual for calculation + // - BRDI = SystemCoreClock / (16* baud) + // - BRDF = int(fraction*64 + 0.5) UART0->CTL &= ~(1 << 0); // Disable UART0 by clearing UARTEN bit in the UARTCTL register - UART0->IBRD = 325; // Write the integer portion of the BRD to the UARTIRD register - UART0->FBRD = 33; // Write the fractional portion of the BRD to the UARTFBRD registerer + UART0->IBRD = 27; // Write the integer portion of the BRD to the UARTIRD register + UART0->FBRD = 8; // Write the fractional portion of the BRD to the UARTFBRD registerer UART0->LCRH = (0x3 << 5); // 8-bit, no parity, 1 stop bit UART0->CC = 0x0; // Configure the UART clock source as system clock @@ -40,8 +48,7 @@ static void initialize_board_led (GPIOA_Type *port, uint8_t PinMsk, uint8_t dirm SYSCTL->RCGCGPIO |= (1 << 5); /* Let the clock stabilize */ - while ( !((SYSCTL->PRGPIO) & (1 << 5)) ) - ; + while ( !((SYSCTL->PRGPIO) & (1 << 5)) ) {} /* Port Digital Enable */ port->DEN |= PinMsk; @@ -60,9 +67,13 @@ static void board_switch_init (void) static void WriteGPIOPin (GPIOA_Type *port, uint8_t PinMsk, bool state) { if ( state ) + { port->DATA |= PinMsk; + } else + { port->DATA &= ~(PinMsk); + } } static uint32_t ReadGPIOPin (GPIOA_Type *port, uint8_t pinMsk) @@ -99,8 +110,7 @@ void board_init (void) SYSCTL->RCGCGPIO |= (1u << 3); /* Let the clock stabilize */ - while ( !(SYSCTL->PRGPIO & (1u << 3)) ) - ; + while ( !(SYSCTL->PRGPIO & (1u << 3)) ) {} /* USB IOs to Analog Mode */ GPIOD->AFSEL &= ~((1u << 4) | (1u << 5)); @@ -119,6 +129,7 @@ void board_init (void) /* Initialize board UART */ board_uart_init(); + TU_LOG1_INT(SystemCoreClock); } void board_led_write (bool state) diff --git a/hw/bsp/tm4c123/family.mk b/hw/bsp/tm4c123/family.mk index 9665a2d7d..751076196 100644 --- a/hw/bsp/tm4c123/family.mk +++ b/hw/bsp/tm4c123/family.mk @@ -28,6 +28,7 @@ INC += \ SRC_C += \ src/portable/mentor/musb/dcd_musb.c \ + src/portable/mentor/musb/hcd_musb.c \ $(MCU_DIR)/Source/system_TM4C123.c \ $(MCU_DIR)/Source/GCC/tm4c123_startup.c From a5251cb86bb35a2da1248e6d32106c694891b02b Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 7 Dec 2021 17:14:20 +0700 Subject: [PATCH 056/504] skip host ci for tm4c due to sram overflow --- examples/host/cdc_msc_hid/.only.MCU_TM4C123 | 0 examples/host/hid_controller/.only.MCU_TM4C123 | 0 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 examples/host/cdc_msc_hid/.only.MCU_TM4C123 delete mode 100644 examples/host/hid_controller/.only.MCU_TM4C123 diff --git a/examples/host/cdc_msc_hid/.only.MCU_TM4C123 b/examples/host/cdc_msc_hid/.only.MCU_TM4C123 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/hid_controller/.only.MCU_TM4C123 b/examples/host/hid_controller/.only.MCU_TM4C123 deleted file mode 100644 index e69de29bb..000000000 From 36e69b86bf0f95916a66a35874da15fb420296e1 Mon Sep 17 00:00:00 2001 From: Valentin Milea Date: Tue, 7 Dec 2021 15:35:30 +0200 Subject: [PATCH 057/504] Remove buffer reclaim logs --- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index 8be16ad22..3a3bef6a5 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -115,7 +115,6 @@ static void _hw_endpoint_close(struct hw_endpoint *ep) } if (reclaim_buffers) { - pico_info(" reclaim buffer space\n"); next_buffer_ptr = &usb_dpram->epx_data[0]; } } @@ -239,7 +238,7 @@ static void reset_non_control_endpoints(void) // clear non-control hw endpoints tu_memclr(hw_endpoints[1], sizeof(hw_endpoints) - 2*sizeof(hw_endpoint_t)); - pico_info(" reclaim buffer space\n"); + // reclaim buffer space next_buffer_ptr = &usb_dpram->epx_data[0]; } From 75f7fb3d9d267f168bc45fc218e1c443701ff11d Mon Sep 17 00:00:00 2001 From: Yunhao Tian Date: Tue, 7 Dec 2021 22:53:52 +0800 Subject: [PATCH 058/504] Add mksunxi tool to make flashable image --- examples/rules.mk | 10 +++--- hw/bsp/f1c100s/board.mk | 7 ++++- hw/mcu/allwinner/f1c100s/f1c100s.ld | 19 ++++++------ tools/mksunxi.py | 48 +++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 15 deletions(-) create mode 100644 tools/mksunxi.py diff --git a/examples/rules.mk b/examples/rules.mk index 6314380ec..55e39f4ed 100644 --- a/examples/rules.mk +++ b/examples/rules.mk @@ -182,10 +182,12 @@ flash-jlink: $(BUILD)/$(PROJECT).hex flash-stlink: $(BUILD)/$(PROJECT).elf STM32_Programmer_CLI --connect port=swd --write $< --go -flash-xfel: $(BUILD)/$(PROJECT).bin - xfel ddr - xfel write 0x80000000 $< - xfel exec 0x80000000 +$(BUILD)/$(PROJECT)-sunxi.bin: $(BUILD)/$(PROJECT).bin + $(PYTHON) $(TOP)/tools/mksunxi.py $< $@ + +flash-xfel: $(BUILD)/$(PROJECT)-sunxi.bin + xfel spinor write 0 $< + xfel reset # Flash using pyocd PYOCD_OPTION ?= diff --git a/hw/bsp/f1c100s/board.mk b/hw/bsp/f1c100s/board.mk index 993aa0d24..9bd9380a7 100644 --- a/hw/bsp/f1c100s/board.mk +++ b/hw/bsp/f1c100s/board.mk @@ -41,5 +41,10 @@ INC += \ $(TOP)/$(MCU_DIR)/include \ $(TOP)/$(BOARD_PATH) -# flash target using on-board stlink +# flash target using xfel flash: flash-xfel + +exec: $(BUILD)/$(PROJECT).bin + xfel ddr + xfel write 0x80000000 $< + xfel exec 0x80000000 \ No newline at end of file diff --git a/hw/mcu/allwinner/f1c100s/f1c100s.ld b/hw/mcu/allwinner/f1c100s/f1c100s.ld index a261618e5..43c353bbd 100644 --- a/hw/mcu/allwinner/f1c100s/f1c100s.ld +++ b/hw/mcu/allwinner/f1c100s/f1c100s.ld @@ -21,15 +21,15 @@ SECTIONS PROVIDE(__bootloader_start = .); PROVIDE(__image_start = .); PROVIDE(__text_start = .); - */machine/start.o (.text) - */lib/memcpy.o (.text) - */lib/memset.o (.text) - */machine/sys-uart.o (.text) - */machine/sys-clock.o (.text) - */machine/sys-dram.o (.text) - */machine/sys-mmu.o (.text) - */machine/sys-spi-flash.o (.text) - */machine/sys-copyself.o (.text) + _build/*/obj/hw/mcu/allwinner/*/machine/start_asm.o (.text) + _build/*/obj/hw/mcu/allwinner/*/lib/memcpy_asm.o (.text) + _build/*/obj/hw/mcu/allwinner/*/lib/memset_asm.o (.text) + _build/*/obj/hw/mcu/allwinner/*/machine/sys-uart.o (.text*) + _build/*/obj/hw/mcu/allwinner/*/machine/sys-clock.o (.text*) + _build/*/obj/hw/mcu/allwinner/*/machine/sys-dram.o (.text*) + _build/*/obj/hw/mcu/allwinner/*/machine/sys-mmu.o (.text*) + _build/*/obj/hw/mcu/allwinner/*/machine/sys-spi-flash.o (.text*) + _build/*/obj/hw/mcu/allwinner/*/machine/sys-copyself.o (.text*) PROVIDE(__bootloader_end = .); } > ram @@ -37,7 +37,6 @@ SECTIONS .text : { - */main.o (.text) *(.text*) *(.glue*) *(.note.gnu.build-id) diff --git a/tools/mksunxi.py b/tools/mksunxi.py new file mode 100644 index 000000000..04786f429 --- /dev/null +++ b/tools/mksunxi.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +import sys +import struct + +def align(num, alignment): + if num % alignment != 0: + num += (alignment - num % alignment) + return num + + +def process_file(input, output): + with open(input, 'rb') as fin: + content = bytearray(fin.read()) + + align_value = 512 + padded_length = align(len(content), align_value) + # pad file to actual length + content += b'\x00' * (padded_length - len(content)) + + struct_format = ' Date: Tue, 7 Dec 2021 22:58:19 +0800 Subject: [PATCH 059/504] Update README --- hw/bsp/f1c100s/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/hw/bsp/f1c100s/README.md b/hw/bsp/f1c100s/README.md index 893b32ea9..cc33ca1f4 100644 --- a/hw/bsp/f1c100s/README.md +++ b/hw/bsp/f1c100s/README.md @@ -6,13 +6,13 @@ Currently tested on: * Lichee Pi Nano (F1C100s) -## make flash -`make flash` will use [xfel](https://github.com/xboot/xfel) to write the code to onchip DDR memory and execute it. It will not write the program to SPI Flash. +## Flashing +There are two options to put your code into the MCU: `flash` and `exec`. Both modes require you to install [xfel](https://github.com/xboot/xfel) tool to your PATH. You must enter FEL mode before any operation can be done. To enter FEL mode, press BOOT button, then press RESET once, and release BOOT button. You will find VID/PID=1f3a:efe8 on your PC. -To enter FEL mode, you have to press BOOT button, then press RESET once, and release BOOT button. You will find VID/PID=1f3a:efe8 on your PC. +Exec: `make BOARD=f1c100s exec` will just upload the image to the DDR ram and execute it. It will not touch anything in the SPI flash. + +Flash: `make BOARD=f1c100s flash` will write the image to SPI flash, and then reset the chip to execute it. ## TODO * Test on Tiny200 v2 (F1C200s) -* Make it able to load .bin directly to SPI Flash and boot -* Add F1C100s to `#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX` high speed MCU check in examples (maybe we should extract the logic?) -* `cdc_msc` example is not working. Device is only echoing the first character. \ No newline at end of file +* Add F1C100s to `#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX` high speed MCU check in examples (maybe we should extract the logic?) \ No newline at end of file From cd76193f3c82a4d1cd870f91e5538bebd147e710 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 8 Dec 2021 10:37:46 +0700 Subject: [PATCH 060/504] try updating clock configure for g4 nucleo (not work yet) --- hw/bsp/stm32g4/boards/stm32g474nucleo/board.h | 16 ++++++++++------ hw/bsp/stm32g4/family.c | 14 +++++++------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/hw/bsp/stm32g4/boards/stm32g474nucleo/board.h b/hw/bsp/stm32g4/boards/stm32g474nucleo/board.h index fd9d50183..e4088023d 100644 --- a/hw/bsp/stm32g4/boards/stm32g474nucleo/board.h +++ b/hw/bsp/stm32g4/boards/stm32g474nucleo/board.h @@ -61,18 +61,19 @@ static inline void board_clock_init(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; // Configure the main internal regulator output voltage HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST); // Initializes the CPU, AHB and APB busses clocks - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; - RCC_OscInitStruct.HSIState = RCC_HSI_ON; - RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV4; - RCC_OscInitStruct.PLL.PLLN = 85; + RCC_OscInitStruct.PLL.PLLN = 50; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; @@ -84,9 +85,12 @@ static inline void board_clock_init(void) RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; - HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_8); + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB; + PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) ; + #if 0 // TODO need to check if USB clock is enabled /* Enable HSI48 */ memset(&RCC_OscInitStruct, 0, sizeof(RCC_OscInitStruct)); diff --git a/hw/bsp/stm32g4/family.c b/hw/bsp/stm32g4/family.c index 318f50746..461dc61a1 100644 --- a/hw/bsp/stm32g4/family.c +++ b/hw/bsp/stm32g4/family.c @@ -118,13 +118,13 @@ void board_init(void) // USB Pins TODO double check USB clock and pin setup // Configure USB DM and DP pins. This is optional, and maintained only for user guidance. -// GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); -// GPIO_InitStruct.Mode = GPIO_MODE_INPUT; -// GPIO_InitStruct.Pull = GPIO_NOPULL; -// GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; -// HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); -// -// __HAL_RCC_USB_CLK_ENABLE(); + GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + __HAL_RCC_USB_CLK_ENABLE(); board_vbus_sense_init(); } From 527036b1f5a3f0aa3994f62e3ab18fa990a40cf8 Mon Sep 17 00:00:00 2001 From: Yunhao Tian Date: Wed, 8 Dec 2021 13:39:27 +0800 Subject: [PATCH 061/504] Initialize MMU if we are executing from DDR --- hw/mcu/allwinner/f1c100s/machine/start.S | 27 ++++++++++++------------ 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/hw/mcu/allwinner/f1c100s/machine/start.S b/hw/mcu/allwinner/f1c100s/machine/start.S index 1fd7cb1f9..befb22148 100644 --- a/hw/mcu/allwinner/f1c100s/machine/start.S +++ b/hw/mcu/allwinner/f1c100s/machine/start.S @@ -111,37 +111,38 @@ reset: ldmia r0!, {r2-r8, r10} stmia r1!, {r2-r8, r10} - /* Initial system clock, ddr add uart */ + /* Initial system clock, ddr and uart */ bl sys_clock_init - bl sys_dram_init bl sys_uart_init - /* Boot speed up, leave slower sram */ + /* Check if we are already running from dram */ adr r0, _start ldr r1, =_start cmp r0, r1 - beq _speedup + beq _init_mmu + + /* Init dram if not running from dram */ + bl sys_dram_init + + /* Copy bootloader to faster dram (sram is slower) */ ldr r0, =0x81f80000 adr r1, _start mov r2, #0x4000 bl memcpy - ldr r0, =_speedup + ldr r0, =_copy_self ldr r1, =_start sub r0, r0, r1 ldr r1, =0x81f80000 add r0, r0, r1 mov pc, r0 -_speedup: - nop - +_init_mmu: + bl sys_mmu_init + b 1f +_copy_self: /* Copyself to link address */ - adr r0, _start - ldr r1, =_start - cmp r0, r1 - beq 1f bl sys_copyself -1: nop +1: nop /* Initialize stacks */ mrs r0, cpsr bic r0, r0, #0x1f From 21db2351fdd3edd560e14d2949b9b0d217a51f93 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Wed, 1 Dec 2021 13:38:20 +0100 Subject: [PATCH 062/504] nrf5x: Fix race condition during startup When NRF5x device is reset by software (after DFU for example), power event is ready from the beginning. When power interrupt is triggered before tud_init() finished USBD_IRQn is enabled before it would be enabled in tud_init(). This in turn may result in BUS RESET event being sent from USB interrupt to USB task when queue is not initialized yet. This scenario often happens in Mynewt build where queue creation takes more time. To prevent this scenario USBD_IRQn is not enabled in power event interrupt handler before dcd_init() was called. --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 2bcd56b8a..ed597a34f 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -1059,7 +1059,13 @@ void tusb_hal_nrf_power_event (uint32_t event) // Enable interrupt, priorities should be set by application NVIC_ClearPendingIRQ(USBD_IRQn); - NVIC_EnableIRQ(USBD_IRQn); + // Don't enable USBD interrupt yet, if dcd_init() did not finish yet + // Interrupt will be enabled by tud_init(), when USB stack is ready + // to handle interrupts. + if (tud_inited()) + { + NVIC_EnableIRQ(USBD_IRQn); + } // Wait for HFCLK while ( !hfclk_running() ) { } From 5039a5e54c184d6cc281890b6f328caef116bce7 Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Wed, 8 Dec 2021 09:34:29 +0000 Subject: [PATCH 063/504] Update code to implement changes from upstream master --- hw/bsp/brtmm90x/family.c | 8 ++++++-- src/device/dcd_attr.h | 4 ++-- src/portable/bridgetek/ft9xx/dcd_ft9xx.c | 18 +++++++++--------- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/hw/bsp/brtmm90x/family.c b/hw/bsp/brtmm90x/family.c index ed169655e..739a8358d 100644 --- a/hw/bsp/brtmm90x/family.c +++ b/hw/bsp/brtmm90x/family.c @@ -63,7 +63,8 @@ void board_init(void) // Use sizeof to avoid pulling in strlen unnecessarily. board_uart_write(WELCOME_MSG, sizeof(WELCOME_MSG)); -#if 1 +#if 0 + // Ethernet LEDs gpio_function(GPIO_ETH_LED0, pad_gpio4); /* ETH LED0 */ gpio_dir(GPIO_ETH_LED0, pad_dir_open_drain); gpio_function(GPIO_ETH_LED1, pad_gpio5); /* ETH LED1 */ @@ -192,7 +193,10 @@ int board_uart_read(uint8_t *buf, int len) // Send characters to UART int board_uart_write(void const *buf, int len) { - int r = uart_writen(UART0, (uint8_t *)buf, len); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" // uart_writen does not have const for buffer parameter. + int r = uart_writen(UART0, (uint8_t *)((const void *)buf), len); +#pragma GCC diagnostic pop return r; } diff --git a/src/device/dcd_attr.h b/src/device/dcd_attr.h index c51940573..21bfbb545 100644 --- a/src/device/dcd_attr.h +++ b/src/device/dcd_attr.h @@ -198,10 +198,10 @@ #define DCD_ATTR_ENDPOINT_MAX 8 //------------- BridgeTek -------------// -#elif TU_CHECK_MCU(FT90X) +#elif TU_CHECK_MCU(OPT_MCU_FT90X) #define DCD_ATTR_ENDPOINT_MAX 8 -#elif TU_CHECK_MCU(FT93X) +#elif TU_CHECK_MCU(OPT_MCU_FT93X) #define DCD_ATTR_ENDPOINT_MAX 16 #else diff --git a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c index 3235d0ef1..aa45aa1dd 100644 --- a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c +++ b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c @@ -56,10 +56,10 @@ static uint8_t _ft90x_setup_packet[8]; struct ft90x_xfer_state { - volatile int16_t total_size; // Total transfer size in bytes for this transfer. - volatile int16_t remain_size; // Total remaining in transfer. - volatile uint8_t *buff_ptr; // Pointer to buffer to transmit from or receive to. - volatile uint8_t valid; // Transfer is pending and total_size, remain_size, and buff_ptr are valid. + uint8_t valid; // Transfer is pending and total_size, remain_size, and buff_ptr are valid. + int16_t total_size; // Total transfer size in bytes for this transfer. + int16_t remain_size; // Total remaining in transfer. + uint8_t *buff_ptr; // Pointer to buffer to transmit from or receive to. uint8_t type; // Endpoint type. Of type USBD_ENDPOINT_TYPE from endpoint descriptor. uint8_t dir; // Endpoint direction. TUSB_DIR_OUT or TUSB_DIR_IN. For control endpoint this is the current direction. @@ -399,7 +399,7 @@ static uint16_t _ft90x_dusb_in(uint8_t ep_number, const uint8_t *buffer, uint16_ #ifdef USBD_USE_STREAMS volatile uint8_t *data_reg; - data_reg = (uint8_t *)&(USBD->ep[ep_number].epxfifo); + data_reg = (volatile uint8_t *)&(USBD->ep[ep_number].epxfifo); if (buff_size) { if (((uint32_t)buffer) % 4 == 0) @@ -476,7 +476,7 @@ static uint16_t _ft90x_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t len buff_size = length; #ifdef USBD_USE_STREAMS - data_reg = (uint8_t *)&(USBD->ep[ep_number].epxfifo); + data_reg = (volatile uint8_t *)&(USBD->ep[ep_number].epxfifo); if (buff_size) { if ((uint32_t)buffer % 4 == 0) @@ -656,7 +656,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc) uint8_t const ep_number = tu_edpt_number(ep_desc->bEndpointAddress); uint8_t const ep_dir = tu_edpt_dir(ep_desc->bEndpointAddress); uint8_t const ep_type = ep_desc->bmAttributes.xfer; - uint16_t const ep_size = ep_desc->wMaxPacketSize.size; + uint16_t const ep_size = tu_edpt_packet_size(ep_desc); // Mask size per packet, bits 10..0. uint16_t ep_buff_size; uint8_t ep_reg_size = USBD_EP_MAX_SIZE_8; uint8_t ep_reg_data = 0; @@ -673,13 +673,13 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc) // Calculate the physical size of the endpoint as a power of 2. This may be more than // the requested size. - while (ep_desc->wMaxPacketSize.size > (8 * (1 << ep_reg_size))) + while (ep_size > (8 * (1 << ep_reg_size))) { ep_reg_size++; } if (ep_reg_size > USBD_EP_MAX_SIZE_1024) { - TU_LOG1("FT90x endpoint size not valid: requested %d max 1024\r\n", ep_desc->wMaxPacketSize.size); + TU_LOG1("FT90x endpoint size not valid: requested %d max 1024\r\n", ep_size); return false; } // Calculate actual amount of buffer RAM used by this endpoint. This may be more than the From 45869958f6066fe4d195c62423cba2fec1886cbc Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Wed, 8 Dec 2021 10:03:33 +0000 Subject: [PATCH 064/504] Add FT9xx to more examples which support High-Speed --- examples/device/hid_boot_interface/src/tusb_config.h | 3 ++- examples/device/hid_composite/src/tusb_config.h | 3 ++- examples/device/hid_multiple_interface/src/tusb_config.h | 3 ++- examples/device/midi_test/src/tusb_config.h | 3 ++- hw/bsp/brtmm90x/family.c | 3 ++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/examples/device/hid_boot_interface/src/tusb_config.h b/examples/device/hid_boot_interface/src/tusb_config.h index 59fb9962c..1381dd6b2 100644 --- a/examples/device/hid_boot_interface/src/tusb_config.h +++ b/examples/device/hid_boot_interface/src/tusb_config.h @@ -48,7 +48,8 @@ // Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed #ifndef BOARD_DEVICE_RHPORT_SPEED #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ - CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56 || CFG_TUSB_MCU == OPT_MCU_SAMX7X) + CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56 || CFG_TUSB_MCU == OPT_MCU_SAMX7X || \ + CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X) #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED #else #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED diff --git a/examples/device/hid_composite/src/tusb_config.h b/examples/device/hid_composite/src/tusb_config.h index 8fa5e5cd4..449efbc7e 100644 --- a/examples/device/hid_composite/src/tusb_config.h +++ b/examples/device/hid_composite/src/tusb_config.h @@ -48,7 +48,8 @@ // Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed #ifndef BOARD_DEVICE_RHPORT_SPEED #if TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX, OPT_MCU_MIMXRT10XX, OPT_MCU_NUC505) ||\ - TU_CHECK_MCU(OPT_MCU_CXD56, OPT_MCU_SAMX7X, OPT_MCU_BCM2711) + TU_CHECK_MCU(OPT_MCU_CXD56, OPT_MCU_SAMX7X, OPT_MCU_BCM2711) ||\ + TU_CHECK_MCU(OPT_MCU_FT90X, OPT_MCU_FT93X) #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED #else #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED diff --git a/examples/device/hid_multiple_interface/src/tusb_config.h b/examples/device/hid_multiple_interface/src/tusb_config.h index a0aa17a90..c034b086e 100644 --- a/examples/device/hid_multiple_interface/src/tusb_config.h +++ b/examples/device/hid_multiple_interface/src/tusb_config.h @@ -48,7 +48,8 @@ // Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed #ifndef BOARD_DEVICE_RHPORT_SPEED #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ - CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56) + CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56 || \ + CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X) #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED #else #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED diff --git a/examples/device/midi_test/src/tusb_config.h b/examples/device/midi_test/src/tusb_config.h index 61b9b6552..a40d7605c 100644 --- a/examples/device/midi_test/src/tusb_config.h +++ b/examples/device/midi_test/src/tusb_config.h @@ -48,7 +48,8 @@ // Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed #ifndef BOARD_DEVICE_RHPORT_SPEED #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ - CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56) + CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56 || \ + CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X) #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED #else #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED diff --git a/hw/bsp/brtmm90x/family.c b/hw/bsp/brtmm90x/family.c index 739a8358d..803a62a95 100644 --- a/hw/bsp/brtmm90x/family.c +++ b/hw/bsp/brtmm90x/family.c @@ -24,8 +24,9 @@ * This file is part of the TinyUSB stack. */ -#include "board.h" #include "bsp/board.h" +#include "board.h" + #include #include From fa06bd01c97a3a14215ea145764c09aecaa0dd79 Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Wed, 8 Dec 2021 10:05:32 +0000 Subject: [PATCH 065/504] Merge in upstream changes Merge upstream changes and expand example support to hid examples. --- .vscode/c_cpp_properties.json | 41 ++++++++ .vscode/launch.json | 32 +++++++ .vscode/settings.json | 17 ++++ .vscode/tasks.json | 176 ++++++++++++++++++++++++++++++++++ examples/make.mk | 3 +- examples/rules.mk | 4 +- 6 files changed, 270 insertions(+), 3 deletions(-) create mode 100644 .vscode/c_cpp_properties.json create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json create mode 100644 .vscode/tasks.json diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 000000000..28d4718b2 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,41 @@ +{ + "configurations": [ + { + "name": "FT900", + "includePath": [ + // Toolchain installed FT90X SDK. + "C:/Program Files (x86)/Bridgetek/FT9xx Toolchain/Toolchain/hardware/include", + // Submodule for FT90X SDK. + //"${workspaceFolder}/hw/mcu/bridgetek/ft9xx/hardware/Source/include", + // Board headers. + "${workspaceFolder}/hw/bsp/brtmm90x/boards/mm900evxb", + // Hardware abstraction headers. + "${workspaceFolder}/hw/", + // Local header files. + ".", + "${workspaceFolder}/src", + // Example headers. + "${workspaceFolder}/examples/device/cdc_msc/src" + //"${workspaceFolder}/examples/host/hid_controller/src" + ], + "defines": [ + "__FT900__", + "BOARD=mm900evxb", + //"FT32_PORT", "FT32_PORT_HEAP=4", // For FreeRTOS + "CFG_TUSB_MCU=OPT_MCU_FT90X", // For FT90x + //"CFG_TUSB_RHPORT0_MODE=(OPT_MODE_HOST|OPT_MODE_HIGH_SPEED)", + //"CFG_TUSB_RHPORT1_MODE=(OPT_MODE_DEVICE|OPT_MODE_HIGH_SPEED)", + //"BOARD_DEVICE_RHPORT_NUM=1", + //"BOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED", + "CFG_TUSB_DEBUG=0" + ], + "windowsSdkVersion": "10.0.18362.0", + "compilerPath": "C:/Program Files (x86)/Bridgetek/FT9xx Toolchain/Toolchain/tools/bin/ft32-elf-gcc", + "cStandard": "c11", + "cppStandard": "c++11", + "intelliSenseMode": "windows-gcc-x64", + "configurationProvider": "ms-vscode.makefile-tools" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..7aa6e0616 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,32 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Debug TinyUSB CDC_MSC", + "type": "cppdbg", + "MIMode": "gdb", + "request": "launch", + "cwd": "${workspaceFolder}", + "program": "examples/device/program.elf", + //"program": "examples/device/cdc_msc/_build/mm900ev1b/cdc_msc.elf", + "preLaunchTask": "Build and Program (Memory)", + "target": "localhost:9998", + "remote": true, + "gdbpath": "C:/Program Files (x86)/Bridgetek/FT9xx Toolchain/Toolchain/tools/bin/ft32-elf-gdb.exe", + "stopAtEntry": true, + "environment": [], + "console": "externalTerminal", + "miDebuggerPath": "C:/Program Files (x86)/Bridgetek/FT9xx Toolchain/Toolchain/tools/bin/ft32-elf-gdb.exe", + //"miDebuggerArgs": "-x lib\\FreeRTOS\\.gdbinit-FreeRTOS-helpers", + "miDebuggerServerAddress": "localhost:9998", + "launchCompleteCommand": "None", + "debugServerPath": "C:\\Users\\gordon.mcnab\\AppData\\Local\\Programs\\Python\\Python37\\python.exe", + "debugServerArgs": + "\"C:/Program Files (x86)/Bridgetek/FT9xx Toolchain/Toolchain/utilities/gdb_bridge.py\" live pm", + //"rtos": "FreeRTOS", + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..b0aef0cf8 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,17 @@ +{ + "files.associations": { + "tusb_option.h": "c", + "ft900.h": "c", + "ft900_usbd.h": "c", + "ft900_registers.h": "c", + "ft900_usbd_registers.h": "c", + "dcd.h": "c", + "stdint.h": "c", + "board.h": "c", + "ft900_ehci_registers.h": "c", + "stdint-gcc.h": "c", + "ft900_memctl.h": "c", + "stddef.h": "c" + }, + "cmake.configureOnOpen": true +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 000000000..459351c4f --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,176 @@ +{ + "version": "2.0.0", + + "options": { + "env": { + // Set this to the type of example. + // Choices can be "device" or "host". + "exampleType": "device", + // Set this to the name of the example. + // The name is the folder name in the examples directory. + "exampleName": "cdc_msc", + // Set this to the name of the board to target. + "boardName": "mm900evxb" + } + }, + + "inputs": [ + { + "type": "pickString", + "id": "pickExampleName", + "description": "Which example project do you want to use?", + "options": [ + "board_test", + "cdc_msc", + "hid_boot_interface", + "hid_composite", + + ], + "default": "board_test" + }, + { + "type": "pickString", + "id": "pickBoardName", + "description": "Which board type do you want to use?", + "options": [ + "mm900ev1b", + "mm900ev2b", + "mm900ev3b" + ], + "default": "mm900ev1b" + } + ], + + "tasks": [ + { + "label": "test env", + "type": "shell", + "command": "echo", + "args": [ + "$env:exampleName" + ], + "problemMatcher": [] + }, + { + "label": "Build and Program (Memory)", + "dependsOrder": "sequence", + "dependsOn": [ + "Build Project", + "Program Project (Memory)" + ], + "type": "shell", + "options": { + "cwd": "${workspaceFolder}" + }, + "command": "copy", + "args": [ + "examples\\$env:exampleType\\$env:exampleName\\_build\\$env:boardName\\$env:exampleName.elf", + "examples\\$env:exampleType\\program.elf" + ], + "problemMatcher": { + "pattern": { + "regexp": "^Error:\\s+(.*)$", + "message": 1 + } + } + }, + { + "label": "Build Project", + "type": "shell", + "options": { + "cwd": "${workspaceFolder}" + }, + "command": "make.exe", + "args": [ + "-C", + "examples\\$env:exampleType\\$env:exampleName", + "BOARD=$env:boardName" + ], + "problemMatcher": [ + "$gcc" + ], + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "label": "Rebuild Project", + "type": "shell", + "options": { + "cwd": "${workspaceFolder}" + }, + "command": "make.exe", + "args": [ + "-C", + "examples\\$env:exampleType\\$env:exampleName", + "BOARD=$env:boardName", + "-B" + ], + "problemMatcher": [ + "$gcc" + ], + "group": "build" + }, + { + "label": "Clean Project", + "type": "shell", + "options": { + "cwd": "${workspaceFolder}" + }, + "command": "make.exe", + "args": [ + "-C", + "examples\\$env:exampleType\\$env:exampleName", + "BOARD=$env:boardName", + "clean" + ], + "problemMatcher": [ + "$gcc" + ], + "group": "build" + }, + { + "label": "Program Project (Flash)", + "type": "shell", + "options": { + "cwd": "${workspaceFolder}" + }, + "command": "C:\\Program Files (x86)\\Bridgetek\\FT9xx Toolchain\\Toolchain\\programmer\\dist\\FT900Prog.exe", + "args": [ + "--loadflash", + "examples\\$env:exampleType\\$env:exampleName\\_build\\$env:boardName\\$env:exampleName.bin", + "--onewire", + "--noReset" + ], + "problemMatcher": { + "pattern": { + "regexp": "^Error:\\s+(.*)$", + "message": 1 + } + }, + "dependsOn": "${defaultBuildTask}" + }, + { + "label": "Program Project (Memory)", + "type": "shell", + "options": { + "cwd": "${workspaceFolder}" + }, + "command": "C:\\Program Files (x86)\\Bridgetek\\FT9xx Toolchain\\Toolchain\\programmer\\dist\\FT900Prog.exe", + "args": [ + "--loadpm", + "examples\\$env:exampleType\\$env:exampleName\\_build\\$env:boardName\\$env:exampleName.bin", + "--onewire", + "--noReset" + ], + "problemMatcher": { + "pattern": { + "regexp": "^Error:\\s+(.*)$", + "message": 1 + } + }, + "dependsOn": "${defaultBuildTask}" + } + ], +} \ No newline at end of file diff --git a/examples/make.mk b/examples/make.mk index 793c40aa2..e1cd0af2a 100644 --- a/examples/make.mk +++ b/examples/make.mk @@ -104,10 +104,11 @@ CFLAGS += \ -Wmissing-format-attribute \ -Wunreachable-code \ -Wcast-align \ - -Wcast-function-type \ -Wcast-qual \ -Wnull-dereference +# -Wcast-function-type \ + # Debugging/Optimization ifeq ($(DEBUG), 1) CFLAGS += -Og diff --git a/examples/rules.mk b/examples/rules.mk index 4cc35cb22..a12a75d60 100644 --- a/examples/rules.mk +++ b/examples/rules.mk @@ -84,7 +84,7 @@ OBJ_DIRS = $(sort $(dir $(OBJ))) $(OBJ): | $(OBJ_DIRS) $(OBJ_DIRS): ifeq ($(CMDEXE),1) - @$(MKDIR) $(subst /,\,$@) + -@$(MKDIR) $(subst /,\,$@) else @$(MKDIR) -p $@ endif @@ -207,7 +207,7 @@ debug-bmp: $(BUILD)/$(PROJECT).elf # Create binary directory $(BIN): - @$(MKDIR) -p $@ + -@$(MKDIR) -p $@ # Copy binaries .elf, .bin, .hex, .uf2 to BIN for upload # due to large size of combined artifacts, only uf2 is uploaded for now From ae970ba2e2cc83881c52e66cd79fad5947e5e59e Mon Sep 17 00:00:00 2001 From: Valentin Milea Date: Wed, 8 Dec 2021 12:33:30 +0200 Subject: [PATCH 066/504] Handle xfer events before closing EP --- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 17 ++++++++--------- src/portable/raspberrypi/rp2040/rp2040_usb.c | 4 +--- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index 3a3bef6a5..42add3167 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -247,6 +247,14 @@ static void dcd_rp2040_irq(void) uint32_t const status = usb_hw->ints; uint32_t handled = 0; + // xfer events are handled before setup req. So if a transfer completes immediately + // 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(); + } + if (status & USB_INTS_SETUP_REQ_BITS) { handled |= USB_INTS_SETUP_REQ_BITS; @@ -260,12 +268,6 @@ static void dcd_rp2040_irq(void) usb_hw_clear->sie_status = USB_SIE_STATUS_SETUP_REC_BITS; } - if (status & USB_INTS_BUFF_STATUS_BITS) - { - handled |= USB_INTS_BUFF_STATUS_BITS; - hw_handle_buff_status(); - } - #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 @@ -496,9 +498,6 @@ void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) (void) rhport; pico_trace("dcd_edpt_close %02x\n", ep_addr); - - // usbd.c says: In progress transfers on this EP may be delivered after this call. - // If the endpoint is no longer active when the transfer event is delivered, it will be ignored. hw_endpoint_close(ep_addr); } diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index 0a943b676..9d833e65f 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -294,9 +294,7 @@ bool hw_endpoint_xfer_continue(struct hw_endpoint *ep) // Part way through a transfer if (!ep->active) { - pico_info("Ignore xfer on inactive ep %d %s", tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]); - _hw_endpoint_lock_update(ep, -1); - return false; + panic("Can't continue xfer on inactive ep %d %s", tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]); } // Update EP struct from hardware state From 79f1f4e171393397f25e884792ecc33b2480e050 Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Wed, 8 Dec 2021 11:17:05 +0000 Subject: [PATCH 067/504] Revert "Merge in upstream changes" This reverts commit fa06bd01c97a3a14215ea145764c09aecaa0dd79. --- .vscode/c_cpp_properties.json | 41 -------- .vscode/launch.json | 32 ------- .vscode/settings.json | 17 ---- .vscode/tasks.json | 176 ---------------------------------- examples/make.mk | 3 +- examples/rules.mk | 4 +- 6 files changed, 3 insertions(+), 270 deletions(-) delete mode 100644 .vscode/c_cpp_properties.json delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json deleted file mode 100644 index 28d4718b2..000000000 --- a/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "configurations": [ - { - "name": "FT900", - "includePath": [ - // Toolchain installed FT90X SDK. - "C:/Program Files (x86)/Bridgetek/FT9xx Toolchain/Toolchain/hardware/include", - // Submodule for FT90X SDK. - //"${workspaceFolder}/hw/mcu/bridgetek/ft9xx/hardware/Source/include", - // Board headers. - "${workspaceFolder}/hw/bsp/brtmm90x/boards/mm900evxb", - // Hardware abstraction headers. - "${workspaceFolder}/hw/", - // Local header files. - ".", - "${workspaceFolder}/src", - // Example headers. - "${workspaceFolder}/examples/device/cdc_msc/src" - //"${workspaceFolder}/examples/host/hid_controller/src" - ], - "defines": [ - "__FT900__", - "BOARD=mm900evxb", - //"FT32_PORT", "FT32_PORT_HEAP=4", // For FreeRTOS - "CFG_TUSB_MCU=OPT_MCU_FT90X", // For FT90x - //"CFG_TUSB_RHPORT0_MODE=(OPT_MODE_HOST|OPT_MODE_HIGH_SPEED)", - //"CFG_TUSB_RHPORT1_MODE=(OPT_MODE_DEVICE|OPT_MODE_HIGH_SPEED)", - //"BOARD_DEVICE_RHPORT_NUM=1", - //"BOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED", - "CFG_TUSB_DEBUG=0" - ], - "windowsSdkVersion": "10.0.18362.0", - "compilerPath": "C:/Program Files (x86)/Bridgetek/FT9xx Toolchain/Toolchain/tools/bin/ft32-elf-gcc", - "cStandard": "c11", - "cppStandard": "c++11", - "intelliSenseMode": "windows-gcc-x64", - "configurationProvider": "ms-vscode.makefile-tools" - } - ], - "version": 4 -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 7aa6e0616..000000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "Debug TinyUSB CDC_MSC", - "type": "cppdbg", - "MIMode": "gdb", - "request": "launch", - "cwd": "${workspaceFolder}", - "program": "examples/device/program.elf", - //"program": "examples/device/cdc_msc/_build/mm900ev1b/cdc_msc.elf", - "preLaunchTask": "Build and Program (Memory)", - "target": "localhost:9998", - "remote": true, - "gdbpath": "C:/Program Files (x86)/Bridgetek/FT9xx Toolchain/Toolchain/tools/bin/ft32-elf-gdb.exe", - "stopAtEntry": true, - "environment": [], - "console": "externalTerminal", - "miDebuggerPath": "C:/Program Files (x86)/Bridgetek/FT9xx Toolchain/Toolchain/tools/bin/ft32-elf-gdb.exe", - //"miDebuggerArgs": "-x lib\\FreeRTOS\\.gdbinit-FreeRTOS-helpers", - "miDebuggerServerAddress": "localhost:9998", - "launchCompleteCommand": "None", - "debugServerPath": "C:\\Users\\gordon.mcnab\\AppData\\Local\\Programs\\Python\\Python37\\python.exe", - "debugServerArgs": - "\"C:/Program Files (x86)/Bridgetek/FT9xx Toolchain/Toolchain/utilities/gdb_bridge.py\" live pm", - //"rtos": "FreeRTOS", - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index b0aef0cf8..000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "files.associations": { - "tusb_option.h": "c", - "ft900.h": "c", - "ft900_usbd.h": "c", - "ft900_registers.h": "c", - "ft900_usbd_registers.h": "c", - "dcd.h": "c", - "stdint.h": "c", - "board.h": "c", - "ft900_ehci_registers.h": "c", - "stdint-gcc.h": "c", - "ft900_memctl.h": "c", - "stddef.h": "c" - }, - "cmake.configureOnOpen": true -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 459351c4f..000000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,176 +0,0 @@ -{ - "version": "2.0.0", - - "options": { - "env": { - // Set this to the type of example. - // Choices can be "device" or "host". - "exampleType": "device", - // Set this to the name of the example. - // The name is the folder name in the examples directory. - "exampleName": "cdc_msc", - // Set this to the name of the board to target. - "boardName": "mm900evxb" - } - }, - - "inputs": [ - { - "type": "pickString", - "id": "pickExampleName", - "description": "Which example project do you want to use?", - "options": [ - "board_test", - "cdc_msc", - "hid_boot_interface", - "hid_composite", - - ], - "default": "board_test" - }, - { - "type": "pickString", - "id": "pickBoardName", - "description": "Which board type do you want to use?", - "options": [ - "mm900ev1b", - "mm900ev2b", - "mm900ev3b" - ], - "default": "mm900ev1b" - } - ], - - "tasks": [ - { - "label": "test env", - "type": "shell", - "command": "echo", - "args": [ - "$env:exampleName" - ], - "problemMatcher": [] - }, - { - "label": "Build and Program (Memory)", - "dependsOrder": "sequence", - "dependsOn": [ - "Build Project", - "Program Project (Memory)" - ], - "type": "shell", - "options": { - "cwd": "${workspaceFolder}" - }, - "command": "copy", - "args": [ - "examples\\$env:exampleType\\$env:exampleName\\_build\\$env:boardName\\$env:exampleName.elf", - "examples\\$env:exampleType\\program.elf" - ], - "problemMatcher": { - "pattern": { - "regexp": "^Error:\\s+(.*)$", - "message": 1 - } - } - }, - { - "label": "Build Project", - "type": "shell", - "options": { - "cwd": "${workspaceFolder}" - }, - "command": "make.exe", - "args": [ - "-C", - "examples\\$env:exampleType\\$env:exampleName", - "BOARD=$env:boardName" - ], - "problemMatcher": [ - "$gcc" - ], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "Rebuild Project", - "type": "shell", - "options": { - "cwd": "${workspaceFolder}" - }, - "command": "make.exe", - "args": [ - "-C", - "examples\\$env:exampleType\\$env:exampleName", - "BOARD=$env:boardName", - "-B" - ], - "problemMatcher": [ - "$gcc" - ], - "group": "build" - }, - { - "label": "Clean Project", - "type": "shell", - "options": { - "cwd": "${workspaceFolder}" - }, - "command": "make.exe", - "args": [ - "-C", - "examples\\$env:exampleType\\$env:exampleName", - "BOARD=$env:boardName", - "clean" - ], - "problemMatcher": [ - "$gcc" - ], - "group": "build" - }, - { - "label": "Program Project (Flash)", - "type": "shell", - "options": { - "cwd": "${workspaceFolder}" - }, - "command": "C:\\Program Files (x86)\\Bridgetek\\FT9xx Toolchain\\Toolchain\\programmer\\dist\\FT900Prog.exe", - "args": [ - "--loadflash", - "examples\\$env:exampleType\\$env:exampleName\\_build\\$env:boardName\\$env:exampleName.bin", - "--onewire", - "--noReset" - ], - "problemMatcher": { - "pattern": { - "regexp": "^Error:\\s+(.*)$", - "message": 1 - } - }, - "dependsOn": "${defaultBuildTask}" - }, - { - "label": "Program Project (Memory)", - "type": "shell", - "options": { - "cwd": "${workspaceFolder}" - }, - "command": "C:\\Program Files (x86)\\Bridgetek\\FT9xx Toolchain\\Toolchain\\programmer\\dist\\FT900Prog.exe", - "args": [ - "--loadpm", - "examples\\$env:exampleType\\$env:exampleName\\_build\\$env:boardName\\$env:exampleName.bin", - "--onewire", - "--noReset" - ], - "problemMatcher": { - "pattern": { - "regexp": "^Error:\\s+(.*)$", - "message": 1 - } - }, - "dependsOn": "${defaultBuildTask}" - } - ], -} \ No newline at end of file diff --git a/examples/make.mk b/examples/make.mk index e1cd0af2a..793c40aa2 100644 --- a/examples/make.mk +++ b/examples/make.mk @@ -104,11 +104,10 @@ CFLAGS += \ -Wmissing-format-attribute \ -Wunreachable-code \ -Wcast-align \ + -Wcast-function-type \ -Wcast-qual \ -Wnull-dereference -# -Wcast-function-type \ - # Debugging/Optimization ifeq ($(DEBUG), 1) CFLAGS += -Og diff --git a/examples/rules.mk b/examples/rules.mk index a12a75d60..4cc35cb22 100644 --- a/examples/rules.mk +++ b/examples/rules.mk @@ -84,7 +84,7 @@ OBJ_DIRS = $(sort $(dir $(OBJ))) $(OBJ): | $(OBJ_DIRS) $(OBJ_DIRS): ifeq ($(CMDEXE),1) - -@$(MKDIR) $(subst /,\,$@) + @$(MKDIR) $(subst /,\,$@) else @$(MKDIR) -p $@ endif @@ -207,7 +207,7 @@ debug-bmp: $(BUILD)/$(PROJECT).elf # Create binary directory $(BIN): - -@$(MKDIR) -p $@ + @$(MKDIR) -p $@ # Copy binaries .elf, .bin, .hex, .uf2 to BIN for upload # due to large size of combined artifacts, only uf2 is uploaded for now From bcbcdf87de303a4db1724de2a813b80f13d7d906 Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Wed, 8 Dec 2021 11:24:39 +0000 Subject: [PATCH 068/504] Fix spelling mistakes and verify endpoint numbering. --- examples/device/cdc_msc/src/usb_descriptors.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/device/cdc_msc/src/usb_descriptors.c b/examples/device/cdc_msc/src/usb_descriptors.c index 3c3e9c891..09894cf1b 100644 --- a/examples/device/cdc_msc/src/usb_descriptors.c +++ b/examples/device/cdc_msc/src/usb_descriptors.c @@ -118,7 +118,7 @@ enum #define EPNUM_MSC_IN 0x84 #elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X - // FT9XX don't support a same endpoint number with different direction IN and OUT + // FT9XX doesn't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 From 21fa7ea468cf34e6d775c92de580796d2c7eec4f Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Wed, 8 Dec 2021 13:56:23 +0000 Subject: [PATCH 069/504] Correct path for using the ft90x-sdk submodule (BRTSG-FOSS / ft90x-sdk). Default to ft90x-sdk instead of pre-built library. --- hw/bsp/brtmm90x/family.mk | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/hw/bsp/brtmm90x/family.mk b/hw/bsp/brtmm90x/family.mk index d47f4820c..3933f15cc 100644 --- a/hw/bsp/brtmm90x/family.mk +++ b/hw/bsp/brtmm90x/family.mk @@ -3,23 +3,24 @@ CROSS_COMPILE = ft32-elf- SKIP_NANOLIB = 1 # Set to use FT90X prebuilt libraries. -FT90X_PREBUILT_LIBS = 1 +FT90X_PREBUILT_LIBS = 0 ifeq ($(FT90X_PREBUILT_LIBS),1) # If the FT90X toolchain is installed on Windows systems then the SDK # include files and prebuilt libraries are at: %FT90X_TOOLCHAIN%/hardware FT9XX_SDK = $(FT90X_TOOLCHAIN)/hardware +INC += $(FT9XX_SDK)/include else # The submodule BRTSG-FOSS/ft90x-sdk contains header files and source # code for the Bridgetek SDK. This can be used instead of the prebuilt # library. -DEPS_SUBMODULES += hw/mcu/bridgetek/ft9xx/hardware +DEPS_SUBMODULES += hw/mcu/bridgetek/ft9xx/ft90x-sdk # The SDK can be used to load specific files from the Bridgetek SDK. -FT9XX_SDK = hw/mcu/bridgetek/ft9xx/hardware/Source +FT9XX_SDK = hw/mcu/bridgetek/ft9xx/ft90x-sdk/Source +INC += $(TOP)/$(FT9XX_SDK)/include endif # Add include files which are within the TinyUSB directory structure. INC += \ - $(TOP)/hw/mcu/bridgetek/ft9xx/hardware/Source/include \ $(TOP)/$(BOARD_PATH) # Add required C Compiler flags for FT90X. From 59dcf2062f77137d0246944ed2279d30a4907627 Mon Sep 17 00:00:00 2001 From: Greg Steiert Date: Wed, 8 Dec 2021 14:31:44 -0800 Subject: [PATCH 070/504] adding support for KUIIC board --- hw/bsp/kuiic/K32L2B31xxxxA_flash.ld | 217 ++++++++++++++++++++++++++++ hw/bsp/kuiic/board.h | 45 ++++++ hw/bsp/kuiic/board.mk | 49 +++++++ hw/bsp/kuiic/kuiic.c | 203 ++++++++++++++++++++++++++ 4 files changed, 514 insertions(+) create mode 100644 hw/bsp/kuiic/K32L2B31xxxxA_flash.ld create mode 100644 hw/bsp/kuiic/board.h create mode 100644 hw/bsp/kuiic/board.mk create mode 100644 hw/bsp/kuiic/kuiic.c diff --git a/hw/bsp/kuiic/K32L2B31xxxxA_flash.ld b/hw/bsp/kuiic/K32L2B31xxxxA_flash.ld new file mode 100644 index 000000000..5420ffc00 --- /dev/null +++ b/hw/bsp/kuiic/K32L2B31xxxxA_flash.ld @@ -0,0 +1,217 @@ +/* +** ################################################################### +** Processors: K32L2B31VFM0A +** K32L2B31VFT0A +** K32L2B31VLH0A +** K32L2B31VMP0A +** +** Compiler: GNU C Compiler +** Reference manual: K32L2B3xRM, Rev.0, July 2019 +** Version: rev. 1.0, 2019-07-30 +** Build: b190930 +** +** Abstract: +** Linker file for the GNU C Compiler +** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2019 NXP +** All rights reserved. +** +** SPDX-License-Identifier: BSD-3-Clause +** +** http: www.nxp.com +** mail: support@nxp.com +** +** ################################################################### +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400; + +/* Specify the memory areas */ +MEMORY +{ + m_interrupts (RX) : ORIGIN = 0x00008000, LENGTH = 0x00000200 + m_flash_config (RX) : ORIGIN = 0x00008400, LENGTH = 0x00000010 + m_text (RX) : ORIGIN = 0x00008410, LENGTH = 0x00037BF0 + m_data (RW) : ORIGIN = 0x1FFFE000, LENGTH = 0x00008000 +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into internal flash */ + .interrupts : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } > m_interrupts + + .flash_config : + { + . = ALIGN(4); + KEEP(*(.FlashConfig)) /* Flash Configuration Field (FCF) */ + . = ALIGN(4); + } > m_flash_config + + /* The program code and other data goes into internal flash */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + KEEP (*(.init)) + KEEP (*(.fini)) + . = ALIGN(4); + } > m_text + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > m_text + + .ARM : + { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } > m_text + + .ctors : + { + __CTOR_LIST__ = .; + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + from the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + __CTOR_END__ = .; + } > m_text + + .dtors : + { + __DTOR_LIST__ = .; + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + __DTOR_END__ = .; + } > m_text + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } > m_text + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } > m_text + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } > m_text + + __etext = .; /* define a global symbol at end of code */ + __DATA_ROM = .; /* Symbol is used by startup for data initialization */ + + /* reserve MTB memory at the beginning of m_data */ + .mtb : /* MTB buffer address as defined by the hardware */ + { + . = ALIGN(8); + _mtb_start = .; + KEEP(*(.mtb_buf)) /* need to KEEP Micro Trace Buffer as not referenced by application */ + . = ALIGN(8); + _mtb_end = .; + } > m_data + + .data : AT(__DATA_ROM) + { + . = ALIGN(4); + __DATA_RAM = .; + __data_start__ = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + KEEP(*(.jcr*)) + . = ALIGN(4); + __data_end__ = .; /* define a global symbol at data end */ + } > m_data + + __DATA_END = __DATA_ROM + (__data_end__ - __data_start__); + text_end = ORIGIN(m_text) + LENGTH(m_text); + ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data") + + /* Uninitialized data section */ + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + . = ALIGN(4); + __START_BSS = .; + __bss_start__ = .; + *(.bss) + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + __END_BSS = .; + } > m_data + + .heap : + { + . = ALIGN(8); + __end__ = .; + PROVIDE(end = .); + __HeapBase = .; + . += HEAP_SIZE; + __HeapLimit = .; + __heap_limit = .; /* Add for _sbrk */ + } > m_data + + .stack : + { + . = ALIGN(8); + . += STACK_SIZE; + } > m_data + + /* Initializes stack on the end of block */ + __StackTop = ORIGIN(m_data) + LENGTH(m_data); + __StackLimit = __StackTop - STACK_SIZE; + PROVIDE(__stack = __StackTop); + + .ARM.attributes 0 : { *(.ARM.attributes) } + + ASSERT(__StackLimit >= __HeapLimit, "region m_data overflowed with stack and heap") +} + diff --git a/hw/bsp/kuiic/board.h b/hw/bsp/kuiic/board.h new file mode 100644 index 000000000..78ad83a2e --- /dev/null +++ b/hw/bsp/kuiic/board.h @@ -0,0 +1,45 @@ +/* + * 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 BOARD_H_ +#define BOARD_H_ + +#include "fsl_device_registers.h" + +// LED +#define LED_PIN_CLOCK kCLOCK_PortA +#define LED_GPIO GPIOA +#define LED_PORT PORTA +#define LED_PIN 2 +#define LED_STATE_ON 1 + +// UART +#define UART_PORT LPUART1 +#define UART_PIN_RX 3u +#define UART_PIN_TX 0u + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/kuiic/board.mk b/hw/bsp/kuiic/board.mk new file mode 100644 index 000000000..3a46728f1 --- /dev/null +++ b/hw/bsp/kuiic/board.mk @@ -0,0 +1,49 @@ +SDK_DIR = hw/mcu/nxp/mcux-sdk +DEPS_SUBMODULES += $(SDK_DIR) + +CFLAGS += \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m0plus \ + -DCPU_K32L2B31VLH0A \ + -DCFG_TUSB_MCU=OPT_MCU_K32L2BXX + +# mcu driver cause following warnings +CFLAGS += -Wno-error=unused-parameter + +MCU_DIR = $(SDK_DIR)/devices/K32L2B31A + +# All source paths should be relative to the top level. +LD_FILE = /hw/bsp/$(BOARD)/K32L2B31xxxxA_flash.ld + +SRC_C += \ + src/portable/nxp/khci/dcd_khci.c \ + $(MCU_DIR)/system_K32L2B31A.c \ + $(MCU_DIR)/drivers/fsl_clock.c \ + $(SDK_DIR)/drivers/gpio/fsl_gpio.c \ + $(SDK_DIR)/drivers/lpuart/fsl_lpuart.c + +INC += \ + $(TOP)/hw/bsp/$(BOARD) \ + $(TOP)/$(SDK_DIR)/CMSIS/Include \ + $(TOP)/$(SDK_DIR)/drivers/smc \ + $(TOP)/$(SDK_DIR)/drivers/common \ + $(TOP)/$(SDK_DIR)/drivers/gpio \ + $(TOP)/$(SDK_DIR)/drivers/port \ + $(TOP)/$(SDK_DIR)/drivers/lpuart \ + $(TOP)/$(MCU_DIR) \ + $(TOP)/$(MCU_DIR)/drivers + +SRC_S += $(MCU_DIR)/gcc/startup_K32L2B31A.S + +# For freeRTOS port source +FREERTOS_PORT = ARM_CM0 + +# For flash-jlink target +JLINK_DEVICE = MKL25Z128xxx4 + +# For flash-pyocd target +PYOCD_TARGET = K32L2B + +# flash using pyocd +flash: flash-pyocd diff --git a/hw/bsp/kuiic/kuiic.c b/hw/bsp/kuiic/kuiic.c new file mode 100644 index 000000000..737ef3f5c --- /dev/null +++ b/hw/bsp/kuiic/kuiic.c @@ -0,0 +1,203 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2018, hathach (tinyusb.org) + * Copyright (c) 2020, Koji Kitayama + * + * 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 "../board.h" +#include "board.h" +#include "fsl_smc.h" +#include "fsl_gpio.h" +#include "fsl_port.h" +#include "fsl_clock.h" +#include "fsl_lpuart.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define SIM_OSC32KSEL_LPO_CLK 3U /*!< OSC32KSEL select: LPO clock */ +#define SOPT5_LPUART1RXSRC_LPUART_RX 0x00u /*!<@brief LPUART1 Receive Data Source Select: LPUART_RX pin */ +#define SOPT5_LPUART1TXSRC_LPUART_TX 0x00u /*!<@brief LPUART1 Transmit Data Source Select: LPUART_TX pin */ +#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* System clock frequency. */ +extern uint32_t SystemCoreClock; + +/******************************************************************************* + * Variables for BOARD_BootClockRUN configuration + ******************************************************************************/ +const mcglite_config_t mcgliteConfig_BOARD_BootClockRUN = { + .outSrc = kMCGLITE_ClkSrcHirc, /* MCGOUTCLK source is HIRC */ + .irclkEnableMode = kMCGLITE_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */ + .ircs = kMCGLITE_Lirc8M, /* Slow internal reference (LIRC) 8 MHz clock selected */ + .fcrdiv = kMCGLITE_LircDivBy1, /* Low-frequency Internal Reference Clock Divider: divided by 1 */ + .lircDiv2 = kMCGLITE_LircDivBy1, /* Second Low-frequency Internal Reference Clock Divider: divided by 1 */ + .hircEnableInNotHircMode = true, /* HIRC source is enabled */ +}; +const sim_clock_config_t simConfig_BOARD_BootClockRUN = { + .er32kSrc = SIM_OSC32KSEL_LPO_CLK, /* OSC32KSEL select: LPO clock */ + .clkdiv1 = 0x10000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV4: /2 */ +}; + +/******************************************************************************* + * Code for BOARD_BootClockRUN configuration + ******************************************************************************/ +void BOARD_BootClockRUN(void) +{ + /* Set the system clock dividers in SIM to safe value. */ + CLOCK_SetSimSafeDivs(); + /* Set MCG to HIRC mode. */ + CLOCK_SetMcgliteConfig(&mcgliteConfig_BOARD_BootClockRUN); + /* Set the clock configuration in SIM module. */ + CLOCK_SetSimConfig(&simConfig_BOARD_BootClockRUN); + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; +} + + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void USB0_IRQHandler(void) +{ + tud_int_handler(0); +} + +void board_init(void) +{ + /* Enable port clocks for GPIO pins */ + CLOCK_EnableClock(kCLOCK_PortA); + CLOCK_EnableClock(kCLOCK_PortB); + CLOCK_EnableClock(kCLOCK_PortC); + CLOCK_EnableClock(kCLOCK_PortD); + CLOCK_EnableClock(kCLOCK_PortE); + + + gpio_pin_config_t led_config = { kGPIO_DigitalOutput, 1 }; + GPIO_PinInit(GPIOA, 1U, &led_config); + PORT_SetPinMux(PORTA, 1U, kPORT_MuxAsGpio); + led_config.outputLogic = 0; + GPIO_PinInit(GPIOA, 2U, &led_config); + PORT_SetPinMux(PORTA, 2U, kPORT_MuxAsGpio); + +#ifdef BUTTON_PIN + gpio_pin_config_t button_config = { kGPIO_DigitalInput, 0 }; + GPIO_PinInit(BUTTON_GPIO, BUTTON_PIN, &button_config); + const port_pin_config_t BUTTON_CFG = { + kPORT_PullUp, + kPORT_FastSlewRate, + kPORT_PassiveFilterDisable, + kPORT_LowDriveStrength, + kPORT_MuxAsGpio + }; + PORT_SetPinConfig(BUTTON_PORT, BUTTON_PIN, &BUTTON_CFG); +#endif + + /* PORTC3 is configured as LPUART0_RX */ + PORT_SetPinMux(PORTC, 3U, kPORT_MuxAlt3); + /* PORTA2 (pin 24) is configured as LPUART0_TX */ + PORT_SetPinMux(PORTE, 0U, kPORT_MuxAlt3); + + SIM->SOPT5 = ((SIM->SOPT5 & + /* Mask bits to zero which are setting */ + (~(SIM_SOPT5_LPUART1TXSRC_MASK | SIM_SOPT5_LPUART1RXSRC_MASK))) + /* LPUART0 Transmit Data Source Select: LPUART0_TX pin. */ + | SIM_SOPT5_LPUART1TXSRC(SOPT5_LPUART1TXSRC_LPUART_TX) + /* LPUART0 Receive Data Source Select: LPUART_RX pin. */ + | SIM_SOPT5_LPUART1RXSRC(SOPT5_LPUART1RXSRC_LPUART_RX)); + + BOARD_BootClockRUN(); + SystemCoreClockUpdate(); + CLOCK_SetLpuart1Clock(1); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); +#endif + + lpuart_config_t uart_config; + LPUART_GetDefaultConfig(&uart_config); + uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE; + uart_config.enableTx = true; + uart_config.enableRx = true; + LPUART_Init(UART_PORT, &uart_config, CLOCK_GetFreq(kCLOCK_McgIrc48MClk)); + + // USB + CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcIrc48M, 48000000U); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + if (state) { + LED_GPIO->PDDR |= GPIO_FIT_REG((1UL << LED_PIN)); + } else { + LED_GPIO->PDDR &= GPIO_FIT_REG(~(1UL << LED_PIN)); + } +// GPIO_PinWrite(GPIOA, 1, state ? LED_STATE_ON : (1-LED_STATE_ON) ); +// GPIO_PinWrite(GPIOA, 2, state ? (1-LED_STATE_ON) : LED_STATE_ON ); +} + +uint32_t board_button_read(void) +{ +#ifdef BUTTON_PIN + return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_GPIO, BUTTON_PIN); +#else + return 0; +#endif +} + +int board_uart_read(uint8_t* buf, int len) +{ + LPUART_ReadBlocking(UART_PORT, buf, len); + return len; +} + +int board_uart_write(void const * buf, int len) +{ + LPUART_WriteBlocking(UART_PORT, (uint8_t const*) buf, len); + return len; +} + +#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; +} +#endif From e72a6e90b99bcb4318bed67fbfd5bd5fc52a1d48 Mon Sep 17 00:00:00 2001 From: Greg Steiert Date: Wed, 8 Dec 2021 15:24:14 -0800 Subject: [PATCH 071/504] added support for building uf2 file --- hw/bsp/kuiic/board.mk | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hw/bsp/kuiic/board.mk b/hw/bsp/kuiic/board.mk index 3a46728f1..39e9d9deb 100644 --- a/hw/bsp/kuiic/board.mk +++ b/hw/bsp/kuiic/board.mk @@ -1,5 +1,8 @@ SDK_DIR = hw/mcu/nxp/mcux-sdk -DEPS_SUBMODULES += $(SDK_DIR) +DEPS_SUBMODULES += $(SDK_DIR) tools/uf2 + +# This board uses TinyUF2 for updates +UF2_FAMILY_ID = 0x7f83e793 CFLAGS += \ -mthumb \ From 51acc3e1b90f42ebb80881a143fe36a4ce45821c Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 9 Dec 2021 12:42:08 +0700 Subject: [PATCH 072/504] update g4 bsp --- examples/device/hid_generic_inout/hid_test.py | 32 ++++++++++--------- hw/bsp/stm32g4/boards/stm32g474nucleo/board.h | 28 ++++++++-------- .../stm32g4/boards/stm32g474nucleo/board.mk | 4 ++- 3 files changed, 34 insertions(+), 30 deletions(-) diff --git a/examples/device/hid_generic_inout/hid_test.py b/examples/device/hid_generic_inout/hid_test.py index a42930fb5..21fd3f421 100644 --- a/examples/device/hid_generic_inout/hid_test.py +++ b/examples/device/hid_generic_inout/hid_test.py @@ -1,20 +1,22 @@ # Install python3 HID package https://pypi.org/project/hid/ import hid -USB_VID = 0xcafe +# default is TinyUSB (0xcafe), Adafruit (0x239a), RaspberryPi (0x2e8a), Espressif (0x303a) VID +USB_VID = (0xcafe, 0x239a, 0x2e8a, 0x303a) -print("Openning HID device with VID = 0x%X" % USB_VID) +print("VID list: " + ", ".join('%02x' % v for v in USB_VID)) -for dict in hid.enumerate(USB_VID): - print(dict) - dev = hid.Device(dict['vendor_id'], dict['product_id']) - if dev: - while True: - # Get input from console and encode to UTF8 for array of chars. - # hid generic inout is single report therefore by HIDAPI requirement - # it must be preceeded with 0x00 as dummy reportID - str_out = b'\x00' - str_out += input("Send text to HID Device : ").encode('utf-8') - dev.write(str_out) - str_in = dev.read(64) - print("Received from HID Device:", str_in, '\n') +for vid in USB_VID: + for dict in hid.enumerate(vid): + print(dict) + dev = hid.Device(dict['vendor_id'], dict['product_id']) + if dev: + while True: + # Get input from console and encode to UTF8 for array of chars. + # hid generic inout is single report therefore by HIDAPI requirement + # it must be preceeded with 0x00 as dummy reportID + str_out = b'\x00' + str_out += input("Send text to HID Device : ").encode('utf-8') + dev.write(str_out) + str_in = dev.read(64) + print("Received from HID Device:", str_in, '\n') diff --git a/hw/bsp/stm32g4/boards/stm32g474nucleo/board.h b/hw/bsp/stm32g4/boards/stm32g474nucleo/board.h index e4088023d..998100cf3 100644 --- a/hw/bsp/stm32g4/boards/stm32g474nucleo/board.h +++ b/hw/bsp/stm32g4/boards/stm32g474nucleo/board.h @@ -67,28 +67,28 @@ static inline void board_clock_init(void) HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST); // Initializes the CPU, AHB and APB busses clocks - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSE; - RCC_OscInitStruct.HSEState = RCC_HSE_ON; - RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; - RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV4; - RCC_OscInitStruct.PLL.PLLN = 50; - RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; - RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; - RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48 | RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV4; + RCC_OscInitStruct.PLL.PLLN = 50; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; + RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; HAL_RCC_OscConfig(&RCC_OscInitStruct); // Initializes the CPU, AHB and APB busses clocks - RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; - RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; - RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_8); PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB; - PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL; + PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) ; #if 0 // TODO need to check if USB clock is enabled diff --git a/hw/bsp/stm32g4/boards/stm32g474nucleo/board.mk b/hw/bsp/stm32g4/boards/stm32g474nucleo/board.mk index 1951fcba0..e41edd3b7 100644 --- a/hw/bsp/stm32g4/boards/stm32g474nucleo/board.mk +++ b/hw/bsp/stm32g4/boards/stm32g474nucleo/board.mk @@ -1,4 +1,6 @@ -CFLAGS += -DSTM32G474xx +CFLAGS += \ + -DSTM32G474xx \ + -DHSE_VALUE=24000000 LD_FILE = $(BOARD_PATH)/STM32G474RETx_FLASH.ld From 69bdd703c20e4a61892dc2ef217d14700b29dc46 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 13 Dec 2021 17:53:38 +0700 Subject: [PATCH 073/504] update doc to include g4 --- README.rst | 2 +- docs/reference/supported.rst | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/README.rst b/README.rst index a8ce9399c..03219db3f 100644 --- a/README.rst +++ b/README.rst @@ -50,7 +50,7 @@ The stack supports the following MCUs: - **Renesas:** RX63N, RX65N, RX72N - **Silabs:** EFM32GG - **Sony:** CXD56 -- **ST:** STM32 series: F0, F1, F2, F3, F4, F7, H7, L0, L1, L4, L4+ +- **ST:** STM32 series: F0, F1, F2, F3, F4, F7, H7, G4, L0, L1, L4, L4+ - **TI:** MSP430, MSP432E4, TM4C123 - **ValentyUSB:** eptri diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index e3cb8c679..a63582dd4 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -82,6 +82,8 @@ Supported MCUs | +-----------------------+--------+------+-----------+-------------------+--------------+ | | H7 | ✔ | | ✔ | dwc2 | | | +-----------------------+--------+------+-----------+-------------------+--------------+ +| | G4 | ✔ | ✖ | ✖ | stm32_fsdev | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ | | L0, L1 | ✔ | ✖ | ✖ | stm32_fsdev | | | +----+------------------+--------+------+-----------+-------------------+--------------+ | | L4 | 4x2, 4x3 | ✔ | ✖ | ✖ | stm32_fsdev | | @@ -352,6 +354,17 @@ F7 - `STM32 F767zi Nucleo `__ - `STM32 F769i Discovery `__ +H7 +^^ +- `STM32 H743zi Nucleo `__ +- `STM32 H743i Evaluation `__ +- `STM32 H745i Discovery `__ +- `Waveshare OpenH743I-C `__ + +G4 +^^ +- `STM32 G474RE Nucleo `__ + L0 ^^ - `STM32 L035c8 Discovery `__ @@ -362,13 +375,6 @@ L4 - `STM32 L4P5zg Nucleo `__ - `STM32 L4R5zi Nucleo `__ -H7 -^^ -- `STM32 H743zi Nucleo `__ -- `STM32 H743i Evaluation `__ -- `STM32 H745i Discovery `__ -- `Waveshare OpenH743I-C `__ - TI -- From d097178ab06ce665972bc2f3222648784eba2f54 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 13 Dec 2021 17:59:43 +0700 Subject: [PATCH 074/504] correct wiring note --- hw/bsp/stm32g4/boards/stm32g474nucleo/board.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/bsp/stm32g4/boards/stm32g474nucleo/board.h b/hw/bsp/stm32g4/boards/stm32g474nucleo/board.h index 998100cf3..eab0bd5f0 100644 --- a/hw/bsp/stm32g4/boards/stm32g474nucleo/board.h +++ b/hw/bsp/stm32g4/boards/stm32g474nucleo/board.h @@ -32,8 +32,8 @@ #endif // G474RE Nucleo does not has usb connection. We need to manually connect -// - PA11 for D+, CN10.14 -// - PA12 for D-, CN10.12 +// - PA12 for D+, CN10.12 +// - PA11 for D-, CN10.14 // LED #define LED_PORT GPIOA From 8d373b08879ac382c59dcbfb2d351d4af35e3d00 Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Wed, 15 Dec 2021 12:23:58 +0000 Subject: [PATCH 075/504] Update midi_test endpoints and FT9xx code --- .../device/midi_test/src/usb_descriptors.c | 14 ++-- src/portable/bridgetek/ft9xx/dcd_ft9xx.c | 64 ++++++++++--------- 2 files changed, 44 insertions(+), 34 deletions(-) diff --git a/examples/device/midi_test/src/usb_descriptors.c b/examples/device/midi_test/src/usb_descriptors.c index bd5a0eeab..8444237c6 100644 --- a/examples/device/midi_test/src/usb_descriptors.c +++ b/examples/device/midi_test/src/usb_descriptors.c @@ -83,9 +83,15 @@ enum #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... - #define EPNUM_MIDI 0x02 + #define EPNUM_MIDI_OUT 0x02 + #define EPNUM_MIDI_IN 0x02 +#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X + // On Bridgetek FT9xx endpoint numbers must be unique... + #define EPNUM_MIDI_OUT 0x02 + #define EPNUM_MIDI_IN 0x03 #else - #define EPNUM_MIDI 0x01 + #define EPNUM_MIDI_OUT 0x01 + #define EPNUM_MIDI_IN 0x01 #endif uint8_t const desc_fs_configuration[] = @@ -94,7 +100,7 @@ uint8_t const desc_fs_configuration[] = TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP Out & EP In address, EP size - TUD_MIDI_DESCRIPTOR(ITF_NUM_MIDI, 0, EPNUM_MIDI, 0x80 | EPNUM_MIDI, 64) + TUD_MIDI_DESCRIPTOR(ITF_NUM_MIDI, 0, EPNUM_MIDI_OUT, (0x80 | EPNUM_MIDI_IN), 64) }; #if TUD_OPT_HIGH_SPEED @@ -104,7 +110,7 @@ uint8_t const desc_hs_configuration[] = TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP Out & EP In address, EP size - TUD_MIDI_DESCRIPTOR(ITF_NUM_MIDI, 0, EPNUM_MIDI, 0x80 | EPNUM_MIDI, 512) + TUD_MIDI_DESCRIPTOR(ITF_NUM_MIDI, 0, EPNUM_MIDI_OUT, (0x80 | EPNUM_MIDI_IN), 512) }; #endif diff --git a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c index aa45aa1dd..793d40f81 100644 --- a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c +++ b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c @@ -56,10 +56,10 @@ static uint8_t _ft90x_setup_packet[8]; struct ft90x_xfer_state { - uint8_t valid; // Transfer is pending and total_size, remain_size, and buff_ptr are valid. - int16_t total_size; // Total transfer size in bytes for this transfer. - int16_t remain_size; // Total remaining in transfer. - uint8_t *buff_ptr; // Pointer to buffer to transmit from or receive to. + volatile uint8_t valid; // Transfer is pending and total_size, remain_size, and buff_ptr are valid. + volatile int16_t total_size; // Total transfer size in bytes for this transfer. + volatile int16_t remain_size; // Total remaining in transfer. + volatile uint8_t *buff_ptr; // Pointer to buffer to transmit from or receive to. uint8_t type; // Endpoint type. Of type USBD_ENDPOINT_TYPE from endpoint descriptor. uint8_t dir; // Endpoint direction. TUSB_DIR_OUT or TUSB_DIR_IN. For control endpoint this is the current direction. @@ -131,6 +131,7 @@ static uint16_t _ft90x_edpt_xfer_in(uint8_t ep_number, uint8_t *buffer, uint16_t uint8_t end = 0; uint16_t ep_size = ep_xfer[ep_number].size; (void)ep_size; + if ((xfer_bytes == 0) || (xfer_bytes < ep_size)) { end = 1; @@ -186,39 +187,21 @@ static uint16_t _ft90x_edpt_xfer_in(uint8_t ep_number, uint8_t *buffer, uint16_t return xfer_bytes; } -// Reset all endpoints to a default state. -// Control endpoint enabled and ready. All others disabled. +// Reset all non-control endpoints to a default state. +// Control endpoint is always enabled and ready. All others disabled. static void _ft90x_reset_edpts(void) { // Disable all endpoints and remove configuration values. - // Clear settings. - tu_memclr(ep_xfer, sizeof(ep_xfer)); - for (int i = 0; i < USBD_MAX_ENDPOINT_COUNT; i++) + for (int i = 1; i < USBD_MAX_ENDPOINT_COUNT; i++) { + // Clear settings. + tu_memclr(&ep_xfer[i], sizeof(struct ft90x_xfer_state)); // Disable hardware. USBD_EP_CR_REG(i) = 0; } - // Setup the control endpoint only. -#if CFG_TUD_ENDPOINT0_SIZE == 64 - USBD_EP_CR_REG(USBD_EP_0) = (USBD_EP0_MAX_SIZE_64 << BIT_USBD_EP0_MAX_SIZE); -#elif CFG_TUD_ENDPOINT0_SIZE == 32 - USBD_EP_CR_REG(USBD_EP_0) = (USBD_EP0_MAX_SIZE_32 << BIT_USBD_EP0_MAX_SIZE); -#elif CFG_TUD_ENDPOINT0_SIZE == 16 - USBD_EP_CR_REG(USBD_EP_0) = (USBD_EP0_MAX_SIZE_16 << BIT_USBD_EP0_MAX_SIZE); -#elif CFG_TUD_ENDPOINT0_SIZE == 8 - USBD_EP_CR_REG(USBD_EP_0) = (USBD_EP0_MAX_SIZE_8 << BIT_USBD_EP0_MAX_SIZE); -#else -#error "CFG_TUD_ENDPOINT0_SIZE must be defined with a value of 8, 16, 32 or 64." -#endif - // Configure the control endpoint. - ep_xfer[USBD_EP_0].size = CFG_TUD_ENDPOINT0_SIZE; - ep_xfer[USBD_EP_0].type = TUSB_XFER_CONTROL; - // Enable interrupts from USB device control. USBD_REG(cmie) = MASK_USBD_CMIE_ALL; - // Enable interrupts on EP0. - USBD_REG(epie) = (MASK_USBD_EPIE_EP0IE); } // Enable or disable the USB PHY. @@ -297,12 +280,13 @@ static void _dcd_ft90x_detach(void) SYS->MSC0CFG = SYS->MSC0CFG & (~MASK_SYS_MSC0CFG_USB_VBUS_EN); #endif CRITICAL_SECTION_BEGIN + // Disable interrupts from USB. USBD_REG(epie) = 0; USBD_REG(cmie) = 0; + // Turn off the device enable bit. + USBD_REG(fctrl) = 0; CRITICAL_SECTION_END; - // Disable the USB function. - USBD_REG(fctrl) = 0; delayms(1); // Disable USB PHY @@ -628,8 +612,28 @@ void dcd_connect(uint8_t rhport) // Determine bus speed and signal speed to tusb. _ft90x_usb_speed(); } - CRITICAL_SECTION_END; + // Setup the control endpoint only. +#if CFG_TUD_ENDPOINT0_SIZE == 64 + USBD_EP_CR_REG(USBD_EP_0) = (USBD_EP0_MAX_SIZE_64 << BIT_USBD_EP0_MAX_SIZE); +#elif CFG_TUD_ENDPOINT0_SIZE == 32 + USBD_EP_CR_REG(USBD_EP_0) = (USBD_EP0_MAX_SIZE_32 << BIT_USBD_EP0_MAX_SIZE); +#elif CFG_TUD_ENDPOINT0_SIZE == 16 + USBD_EP_CR_REG(USBD_EP_0) = (USBD_EP0_MAX_SIZE_16 << BIT_USBD_EP0_MAX_SIZE); +#elif CFG_TUD_ENDPOINT0_SIZE == 8 + USBD_EP_CR_REG(USBD_EP_0) = (USBD_EP0_MAX_SIZE_8 << BIT_USBD_EP0_MAX_SIZE); +#else +#error "CFG_TUD_ENDPOINT0_SIZE must be defined with a value of 8, 16, 32 or 64." +#endif + CRITICAL_SECTION_END; + + // Configure the control endpoint. + ep_xfer[USBD_EP_0].size = CFG_TUD_ENDPOINT0_SIZE; + ep_xfer[USBD_EP_0].type = TUSB_XFER_CONTROL; + + // Enable interrupts on EP0. + USBD_REG(epie) = (MASK_USBD_EPIE_EP0IE); + // Restore default endpoint state. _ft90x_reset_edpts(); } From 469ecdd28c0968fc15fe1d69b943d325d9b89d67 Mon Sep 17 00:00:00 2001 From: Greg Steiert Date: Wed, 15 Dec 2021 14:18:27 -0800 Subject: [PATCH 076/504] added KUIIC to supported boards list --- docs/reference/supported.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index a63582dd4..b8f3ac30d 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -245,6 +245,7 @@ Kinetis - `Freedom FRDM-KL25Z `__ - `Freedom FRDM-K32L2B3 `__ +- `KUIIC `__ LPC 11-13-15 ^^^^^^^^^^^^ From 9b2e78c91555f3e50baaf0df30ab18927a65cb65 Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Mon, 20 Dec 2021 15:43:16 +0800 Subject: [PATCH 077/504] samd21: make uart_init() static Avoids a linker conflict if programs are using the same function name. --- hw/bsp/samd21/family.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/bsp/samd21/family.c b/hw/bsp/samd21/family.c index cead582e9..494dc393a 100644 --- a/hw/bsp/samd21/family.c +++ b/hw/bsp/samd21/family.c @@ -47,7 +47,7 @@ void USB_Handler(void) //--------------------------------------------------------------------+ // UART support //--------------------------------------------------------------------+ -void uart_init(void); +static void uart_init(void); //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION @@ -152,7 +152,7 @@ uint32_t board_button_read(void) #define BOARD_SERCOM2(n) SERCOM ## n #define BOARD_SERCOM(n) BOARD_SERCOM2(n) -void uart_init(void) +static void uart_init(void) { #if UART_SERCOM == 0 gpio_set_pin_function(PIN_PA06, PINMUX_PA06D_SERCOM0_PAD2); @@ -217,7 +217,7 @@ int board_uart_write(void const * buf, int len) } #else // ! defined(UART_SERCOM) -void uart_init(void) +static void uart_init(void) { } From 2ab3988d9fd7e5de6c556752709c3519877bdf7b Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 20 Dec 2021 23:54:28 +0700 Subject: [PATCH 078/504] add s3 devkitm --- .../boards/espressif_addax_1/board.cmake | 10 ----- .../boards/espressif_s3_devkitm/board.cmake | 7 +++ .../boards/espressif_s3_devkitm/board.h | 43 +++++++++++++++++++ 3 files changed, 50 insertions(+), 10 deletions(-) create mode 100644 hw/bsp/esp32s3/boards/espressif_s3_devkitm/board.cmake create mode 100644 hw/bsp/esp32s3/boards/espressif_s3_devkitm/board.h diff --git a/hw/bsp/esp32s3/boards/espressif_addax_1/board.cmake b/hw/bsp/esp32s3/boards/espressif_addax_1/board.cmake index 60f7d19ca..8996ff9dc 100644 --- a/hw/bsp/esp32s3/boards/espressif_addax_1/board.cmake +++ b/hw/bsp/esp32s3/boards/espressif_addax_1/board.cmake @@ -1,16 +1,6 @@ # Apply board specific content here target_include_directories(${COMPONENT_LIB} PRIVATE .) -idf_build_get_property(idf_target IDF_TARGET) - -message(STATUS "Apply ${BOARD}(${idf_target}) specific options for component: ${COMPONENT_TARGET}") - -if(NOT ${idf_target} STREQUAL "esp32s3") - message(FATAL_ERROR "Incorrect target for board ${BOARD}: (${idf_target}), try to clean the build first." ) -endif() - -set(IDF_TARGET "esp32s3" FORCE) - target_compile_options(${COMPONENT_TARGET} PUBLIC "-DCFG_TUSB_MCU=OPT_MCU_ESP32S3" "-DCFG_TUSB_OS=OPT_OS_FREERTOS" diff --git a/hw/bsp/esp32s3/boards/espressif_s3_devkitm/board.cmake b/hw/bsp/esp32s3/boards/espressif_s3_devkitm/board.cmake new file mode 100644 index 000000000..8996ff9dc --- /dev/null +++ b/hw/bsp/esp32s3/boards/espressif_s3_devkitm/board.cmake @@ -0,0 +1,7 @@ +# Apply board specific content here +target_include_directories(${COMPONENT_LIB} PRIVATE .) + +target_compile_options(${COMPONENT_TARGET} PUBLIC + "-DCFG_TUSB_MCU=OPT_MCU_ESP32S3" + "-DCFG_TUSB_OS=OPT_OS_FREERTOS" +) \ No newline at end of file diff --git a/hw/bsp/esp32s3/boards/espressif_s3_devkitm/board.h b/hw/bsp/esp32s3/boards/espressif_s3_devkitm/board.h new file mode 100644 index 000000000..c7940c56e --- /dev/null +++ b/hw/bsp/esp32s3/boards/espressif_s3_devkitm/board.h @@ -0,0 +1,43 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, 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 BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define NEOPIXEL_PIN 48 + +#define BUTTON_PIN 0 +#define BUTTON_STATE_ACTIVE 0 + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ From a4426794594da99093ea1dedf1925f8c22d61e69 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 20 Dec 2021 23:55:04 +0700 Subject: [PATCH 079/504] change ci to s3 to espressif_s3_devkitm --- .github/workflows/build_esp.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_esp.yml b/.github/workflows/build_esp.yml index 57dbf33e3..cc56a8b62 100644 --- a/.github/workflows/build_esp.yml +++ b/.github/workflows/build_esp.yml @@ -18,7 +18,7 @@ jobs: # ESP32-S2 - 'espressif_saola_1' # ESP32-S3 - #- 'espressif_addax_1' + - 'espressif_s3_devkitm' # S3 compile error with "dangerous relocation: call8: call target out of range: memcpy" steps: From 63310d72e189d7a6b3424b2c8d2cab9b2189cd6c Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 21 Dec 2021 00:04:50 +0700 Subject: [PATCH 080/504] skip ci for s3 --- .github/workflows/build_esp.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_esp.yml b/.github/workflows/build_esp.yml index cc56a8b62..1ed76ef4d 100644 --- a/.github/workflows/build_esp.yml +++ b/.github/workflows/build_esp.yml @@ -18,7 +18,7 @@ jobs: # ESP32-S2 - 'espressif_saola_1' # ESP32-S3 - - 'espressif_s3_devkitm' + #- 'espressif_s3_devkitm' # S3 compile error with "dangerous relocation: call8: call target out of range: memcpy" steps: From 311248c8b0976ff4634206dbad5850996e6d3c05 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 21 Dec 2021 00:10:38 +0700 Subject: [PATCH 081/504] add s3 devkitc --- .../boards/espressif_s3_devkitc/board.cmake | 7 +++ .../boards/espressif_s3_devkitc/board.h | 43 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 hw/bsp/esp32s3/boards/espressif_s3_devkitc/board.cmake create mode 100644 hw/bsp/esp32s3/boards/espressif_s3_devkitc/board.h diff --git a/hw/bsp/esp32s3/boards/espressif_s3_devkitc/board.cmake b/hw/bsp/esp32s3/boards/espressif_s3_devkitc/board.cmake new file mode 100644 index 000000000..8996ff9dc --- /dev/null +++ b/hw/bsp/esp32s3/boards/espressif_s3_devkitc/board.cmake @@ -0,0 +1,7 @@ +# Apply board specific content here +target_include_directories(${COMPONENT_LIB} PRIVATE .) + +target_compile_options(${COMPONENT_TARGET} PUBLIC + "-DCFG_TUSB_MCU=OPT_MCU_ESP32S3" + "-DCFG_TUSB_OS=OPT_OS_FREERTOS" +) \ No newline at end of file diff --git a/hw/bsp/esp32s3/boards/espressif_s3_devkitc/board.h b/hw/bsp/esp32s3/boards/espressif_s3_devkitc/board.h new file mode 100644 index 000000000..c7940c56e --- /dev/null +++ b/hw/bsp/esp32s3/boards/espressif_s3_devkitc/board.h @@ -0,0 +1,43 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, 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 BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define NEOPIXEL_PIN 48 + +#define BUTTON_PIN 0 +#define BUTTON_STATE_ACTIVE 0 + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ From 6de423606fc9d512efb830b198c76f095a182a1c Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 21 Dec 2021 18:24:05 +0100 Subject: [PATCH 082/504] nucleo-f439zi support --- docs/reference/supported.rst | 1 + .../stm32f439nucleo/STM32F439ZITX_FLASH.ld | 206 ++++++++ hw/bsp/stm32f4/boards/stm32f439nucleo/board.h | 108 ++++ .../stm32f4/boards/stm32f439nucleo/board.mk | 11 + .../stm32f439nucleo/stm32f4xx_hal_conf.h | 486 ++++++++++++++++++ 5 files changed, 812 insertions(+) create mode 100644 hw/bsp/stm32f4/boards/stm32f439nucleo/STM32F439ZITX_FLASH.ld create mode 100644 hw/bsp/stm32f4/boards/stm32f439nucleo/board.h create mode 100644 hw/bsp/stm32f4/boards/stm32f439nucleo/board.mk create mode 100644 hw/bsp/stm32f4/boards/stm32f439nucleo/stm32f4xx_hal_conf.h diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index b8f3ac30d..4dd172dbe 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -344,6 +344,7 @@ F4 - `STM32 F411ve Discovery `__ - `STM32 F412zg Discovery `__ - `STM32 F412zg Nucleo `__ +- `STM32 F439zg Nucleo `__ F7 ^^ diff --git a/hw/bsp/stm32f4/boards/stm32f439nucleo/STM32F439ZITX_FLASH.ld b/hw/bsp/stm32f4/boards/stm32f439nucleo/STM32F439ZITX_FLASH.ld new file mode 100644 index 000000000..2dc277c77 --- /dev/null +++ b/hw/bsp/stm32f4/boards/stm32f439nucleo/STM32F439ZITX_FLASH.ld @@ -0,0 +1,206 @@ +/* +****************************************************************************** +** +** @file : LinkerScript.ld +** +** @author : Auto-generated by STM32CubeIDE +** +** Abstract : Linker script for NUCLEO-F439ZI Board embedding STM32F439ZITx Device from stm32f4 series +** 2048Kbytes FLASH +** 64Kbytes CCMRAM +** 192Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +****************************************************************************** +** @attention +** +** Copyright (c) 2021 STMicroelectronics. +** All rights reserved. +** +** This software is licensed under terms that can be found in the LICENSE file +** in the root directory of this software component. +** If no LICENSE file comes with this software, it is provided AS-IS. +** +****************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Memories definition */ +MEMORY +{ + CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K + FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K +} + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + + .ARM : { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + _siccmram = LOADADDR(.ccmram); + + /* CCM-RAM section + * + * IMPORTANT NOTE! + * If initialized variables will be placed in this section, + * the startup code needs to be modified to copy the init-values. + */ + .ccmram : + { + . = ALIGN(4); + _sccmram = .; /* create a global symbol at ccmram start */ + *(.ccmram) + *(.ccmram*) + + . = ALIGN(4); + _eccmram = .; /* create a global symbol at ccmram end */ + } >CCMRAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32f4/boards/stm32f439nucleo/board.h b/hw/bsp/stm32f4/boards/stm32f439nucleo/board.h new file mode 100644 index 000000000..e5a822426 --- /dev/null +++ b/hw/bsp/stm32f4/boards/stm32f439nucleo/board.h @@ -0,0 +1,108 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, 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 BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// LED +#define LED_PORT GPIOB +#define LED_PIN GPIO_PIN_14 +#define LED_STATE_ON 0 + +// Button +#define BUTTON_PORT GPIOC +#define BUTTON_PIN GPIO_PIN_13 +#define BUTTON_STATE_ACTIVE 1 + +// UART Enable for STLink VCOM +#define UART_DEV USART3 +#define UART_GPIO_PORT GPIOD +#define UART_GPIO_AF GPIO_AF7_USART3 +#define UART_TX_PIN GPIO_PIN_8 +#define UART_RX_PIN GPIO_PIN_9 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_clock_init(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + /* Enable Power Control clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* The voltage scaling allows optimizing the power consumption when the + * device is clocked below the maximum system frequency, to update the + * voltage scaling value regarding system frequency refer to product + * datasheet. */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; + RCC_OscInitStruct.PLL.PLLN = 336; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = 7; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 + * clocks dividers */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | + RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; + + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); + + // Enable clocks for LED, Button, Uart + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_USART3_CLK_ENABLE(); +} + +static inline void board_vbus_sense_init(void) +{ + // Enable VBUS sense (B device) via pin PA9 + USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS; + USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_VBUSBSEN; +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/stm32f4/boards/stm32f439nucleo/board.mk b/hw/bsp/stm32f4/boards/stm32f439nucleo/board.mk new file mode 100644 index 000000000..b7b36a8a6 --- /dev/null +++ b/hw/bsp/stm32f4/boards/stm32f439nucleo/board.mk @@ -0,0 +1,11 @@ +CFLAGS += -DSTM32F439xx + +LD_FILE = $(BOARD_PATH)/STM32F439ZITX_FLASH.ld + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f439xx.s + +# For flash-jlink target +JLINK_DEVICE = stm32f439zi + +# flash target using on-board stlink +flash: flash-stlink diff --git a/hw/bsp/stm32f4/boards/stm32f439nucleo/stm32f4xx_hal_conf.h b/hw/bsp/stm32f4/boards/stm32f439nucleo/stm32f4xx_hal_conf.h new file mode 100644 index 000000000..a2c11d717 --- /dev/null +++ b/hw/bsp/stm32f4/boards/stm32f439nucleo/stm32f4xx_hal_conf.h @@ -0,0 +1,486 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_conf_template.h + * @author MCD Application Team + * @brief HAL configuration file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_HAL_CONF_H +#define __STM32F4xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/* #define HAL_ADC_MODULE_ENABLED */ +/* #define HAL_CAN_MODULE_ENABLED */ +/* #define HAL_CAN_LEGACY_MODULE_ENABLED */ +/* #define HAL_CRC_MODULE_ENABLED */ +/* #define HAL_CEC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +/* #define HAL_DCMI_MODULE_ENABLED */ +#define HAL_DMA_MODULE_ENABLED +/* #define HAL_DMA2D_MODULE_ENABLED */ +/* #define HAL_ETH_MODULE_ENABLED */ +#define HAL_FLASH_MODULE_ENABLED +/* #define HAL_NAND_MODULE_ENABLED */ +/* #define HAL_NOR_MODULE_ENABLED */ +/* #define HAL_PCCARD_MODULE_ENABLED */ +/* #define HAL_SRAM_MODULE_ENABLED */ +/* #define HAL_SDRAM_MODULE_ENABLED */ +/* #define HAL_HASH_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +/* #define HAL_EXTI_MODULE_ENABLED */ +/* #define HAL_I2C_MODULE_ENABLED */ +/* #define HAL_SMBUS_MODULE_ENABLED */ +/* #define HAL_I2S_MODULE_ENABLED */ +/* #define HAL_IWDG_MODULE_ENABLED */ +/* #define HAL_LTDC_MODULE_ENABLED */ +/* #define HAL_DSI_MODULE_ENABLED */ +#define HAL_PWR_MODULE_ENABLED +/* #define HAL_QSPI_MODULE_ENABLED */ +#define HAL_RCC_MODULE_ENABLED +/* #define HAL_RNG_MODULE_ENABLED */ +/* #define HAL_RTC_MODULE_ENABLED */ +/* #define HAL_SAI_MODULE_ENABLED */ +/* #define HAL_SD_MODULE_ENABLED */ +// #define HAL_SPI_MODULE_ENABLED +/* #define HAL_TIM_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_IRDA_MODULE_ENABLED */ +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED +/* #define HAL_PCD_MODULE_ENABLED */ +/* #define HAL_HCD_MODULE_ENABLED */ +/* #define HAL_FMPI2C_MODULE_ENABLED */ +/* #define HAL_SPDIFRX_MODULE_ENABLED */ +/* #define HAL_DFSDM_MODULE_ENABLED */ +/* #define HAL_LPTIM_MODULE_ENABLED */ +/* #define HAL_MMC_MODULE_ENABLED */ + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE (8000000U) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT (100U) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE (16000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE (32000U) +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature. */ +/** + * @brief External Low Speed oscillator (LSE) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE (32768U) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT (5000U) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for I2S peripheral + * This value is used by the I2S HAL module to compute the I2S clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE (12288000U) /*!< Value of the External oscillator in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE (3300U) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY (0x0FU) /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ +#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */ +#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */ +#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */ +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_FMPI2C_REGISTER_CALLBACKS 0U /* FMPI2C register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ +#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */ +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */ +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ +#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## Ethernet peripheral configuration ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 2U +#define MAC_ADDR1 0U +#define MAC_ADDR2 0U +#define MAC_ADDR3 0U +#define MAC_ADDR4 0U +#define MAC_ADDR5 0U + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB 4U /* 4 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB 4U /* 4 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ + +/* LAN8742A_PHY_ADDRESS Address*/ +#define LAN8742A_PHY_ADDRESS 0U +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY 0x000000FFU +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY 0x00000FFFU + +#define PHY_READ_TO 0x0000FFFFU +#define PHY_WRITE_TO 0x0000FFFFU + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x00U) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x01U) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ +#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */ + +#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */ + +#define PHY_ISFR ((uint16_t)0x001DU) /*!< PHY Interrupt Source Flag register Offset */ +#define PHY_ISFR_INT4 ((uint16_t)0x000BU) /*!< PHY Link down inturrupt */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver +* Activated: CRC code is present inside driver +* Deactivated: CRC code cleaned from driver +*/ + +#define USE_SPI_CRC 0U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f4xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f4xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32f4xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f4xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f4xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f4xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f4xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CAN_LEGACY_MODULE_ENABLED + #include "stm32f4xx_hal_can_legacy.h" +#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f4xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32f4xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32f4xx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f4xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32f4xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "stm32f4xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f4xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32f4xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32f4xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_PCCARD_MODULE_ENABLED + #include "stm32f4xx_hal_pccard.h" +#endif /* HAL_PCCARD_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32f4xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f4xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32f4xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f4xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f4xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED + #include "stm32f4xx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f4xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32f4xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f4xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32f4xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32f4xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f4xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f4xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f4xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f4xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f4xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f4xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f4xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f4xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32f4xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_DSI_MODULE_ENABLED + #include "stm32f4xx_hal_dsi.h" +#endif /* HAL_DSI_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED + #include "stm32f4xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32f4xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_FMPI2C_MODULE_ENABLED + #include "stm32f4xx_hal_fmpi2c.h" +#endif /* HAL_FMPI2C_MODULE_ENABLED */ + +#ifdef HAL_SPDIFRX_MODULE_ENABLED + #include "stm32f4xx_hal_spdifrx.h" +#endif /* HAL_SPDIFRX_MODULE_ENABLED */ + +#ifdef HAL_DFSDM_MODULE_ENABLED + #include "stm32f4xx_hal_dfsdm.h" +#endif /* HAL_DFSDM_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32f4xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_MMC_MODULE_ENABLED + #include "stm32f4xx_hal_mmc.h" +#endif /* HAL_MMC_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ From 103817b8b61115e67addfbd696b647f00e47cd30 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 22 Dec 2021 22:56:53 +0200 Subject: [PATCH 083/504] Fix typo Oops. Made a typo in 6de423606fc9d512efb830b198c76f095a182a1c --- docs/reference/supported.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index 4dd172dbe..1f7f395cb 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -344,7 +344,7 @@ F4 - `STM32 F411ve Discovery `__ - `STM32 F412zg Discovery `__ - `STM32 F412zg Nucleo `__ -- `STM32 F439zg Nucleo `__ +- `STM32 F439zi Nucleo `__ F7 ^^ From 5c5ecea6f17aae16808533aa248671069cdc5fa5 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Sun, 26 Dec 2021 22:19:07 +0100 Subject: [PATCH 084/504] build system: Changes for xc32 compiler Three changes are needed to accommodate xc32 compiler build: - optimized build flag other than -Os added CFLAGS_OPTIMIZED that defaults to -Os but can be overridden in boards - build without -lnosys added LIBS_GCC with default libraries that can be changed in boards - build without LD_FILE specification if LD_FILE is empty -Wl,-T options is not added to LDFLAGS --- examples/make.mk | 4 +++- examples/rules.mk | 10 ++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/examples/make.mk b/examples/make.mk index 793c40aa2..bed46d02b 100644 --- a/examples/make.mk +++ b/examples/make.mk @@ -54,6 +54,8 @@ endif #-------------- Cross Compiler ------------ # Can be set by board, default to ARM GCC CROSS_COMPILE ?= arm-none-eabi- +# Allow for -Os to be changed by board makefiles in case -Os is not allowed +CFLAGS_OPTIMIZED ?= -Os CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ @@ -112,7 +114,7 @@ CFLAGS += \ ifeq ($(DEBUG), 1) CFLAGS += -Og else - CFLAGS += -Os + CFLAGS += $(CFLAGS_OPTIMIZED) endif # Log level is mapped to TUSB DEBUG option diff --git a/examples/rules.mk b/examples/rules.mk index 4cc35cb22..95a9c9879 100644 --- a/examples/rules.mk +++ b/examples/rules.mk @@ -12,8 +12,10 @@ ifeq (,$(findstring $(FAMILY),esp32s2 esp32s3 rp2040)) # Compiler Flags # --------------------------------------- +LIBS_GCC ?= -lgcc -lm -lnosys + # libc -LIBS += -lgcc -lm -lnosys +LIBS += $(LIBS_GCC) ifneq ($(BOARD), spresense) LIBS += -lc @@ -49,7 +51,11 @@ ifeq ($(NO_LTO),1) CFLAGS := $(filter-out -flto,$(CFLAGS)) endif -LDFLAGS += $(CFLAGS) -Wl,-T,$(TOP)/$(LD_FILE) -Wl,-Map=$@.map -Wl,-cref -Wl,-gc-sections +ifneq ($(LD_FILE),) +LDFLAGS_LD_FILE ?= -Wl,-T,$(TOP)/$(LD_FILE) +endif + +LDFLAGS += $(CFLAGS) $(LDFLAGS_LD_FILE) -Wl,-Map=$@.map -Wl,-cref -Wl,-gc-sections ifneq ($(SKIP_NANOLIB), 1) LDFLAGS += -specs=nosys.specs -specs=nano.specs endif From 7a596b9e559e9c1b3305906eb9eb6ff707643f75 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Sun, 26 Dec 2021 22:32:35 +0100 Subject: [PATCH 085/504] Fix Mynewt build for Microchip PIC32MZ devices. definition of DEBUG breaks Microchip pic32 builds for Mynewt. When MCU is not VALENTYUSB_EPTRI there is no need to have any preprocessor definitions. It may not look like a big deal but for xc32 builds, compiler automatically force-includes some file that have structure with field name DEBUG that result in build error in dcd_eptri.c when this file is not really needed. Moving DEBUG and LOG_USB few lines down should not break eptri builds. --- src/portable/valentyusb/eptri/dcd_eptri.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/portable/valentyusb/eptri/dcd_eptri.c b/src/portable/valentyusb/eptri/dcd_eptri.c index 837d0c0ce..51fb8b401 100644 --- a/src/portable/valentyusb/eptri/dcd_eptri.c +++ b/src/portable/valentyusb/eptri/dcd_eptri.c @@ -24,6 +24,10 @@ * This file is part of the TinyUSB stack. */ +#include "tusb_option.h" + +#if TUSB_OPT_DEVICE_ENABLED && (CFG_TUSB_MCU == OPT_MCU_VALENTYUSB_EPTRI) + #ifndef DEBUG #define DEBUG 0 #endif @@ -32,10 +36,6 @@ #define LOG_USB 0 #endif -#include "tusb_option.h" - -#if TUSB_OPT_DEVICE_ENABLED && (CFG_TUSB_MCU == OPT_MCU_VALENTYUSB_EPTRI) - #include "device/dcd.h" #include "dcd_eptri.h" #include "csr.h" From a76799b085ae157243ed002f8cf11a2d3eb0c6b9 Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Mon, 27 Dec 2021 01:22:57 +0900 Subject: [PATCH 086/504] Add hcd for Renesas RX --- hw/bsp/rx/boards/rx65n_target/rx65n_target.c | 5 + hw/bsp/rx/family.mk | 1 + src/portable/renesas/usba/hcd_usba.c | 869 +++++++++++++++++++ 3 files changed, 875 insertions(+) create mode 100644 src/portable/renesas/usba/hcd_usba.c diff --git a/hw/bsp/rx/boards/rx65n_target/rx65n_target.c b/hw/bsp/rx/boards/rx65n_target/rx65n_target.c index ab86bc419..d658ee5dd 100644 --- a/hw/bsp/rx/boards/rx65n_target/rx65n_target.c +++ b/hw/bsp/rx/boards/rx65n_target/rx65n_target.c @@ -176,7 +176,12 @@ void INT_Excep_SCI5_RXI5(void) //--------------------------------------------------------------------+ void INT_Excep_USB0_USBI0(void) { +#if TUSB_OPT_HOST_ENABLED + tuh_int_handler(0); +#endif +#if TUSB_OPT_DEVICE_ENABLED tud_int_handler(0); +#endif } void board_init(void) diff --git a/hw/bsp/rx/family.mk b/hw/bsp/rx/family.mk index 5a8281718..aba05812d 100644 --- a/hw/bsp/rx/family.mk +++ b/hw/bsp/rx/family.mk @@ -15,6 +15,7 @@ CFLAGS += \ SRC_C += \ src/portable/renesas/usba/dcd_usba.c \ + src/portable/renesas/usba/hcd_usba.c \ $(MCU_DIR)/vects.c INC += \ diff --git a/src/portable/renesas/usba/hcd_usba.c b/src/portable/renesas/usba/hcd_usba.c new file mode 100644 index 000000000..360a8d75f --- /dev/null +++ b/src/portable/renesas/usba/hcd_usba.c @@ -0,0 +1,869 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 Koji Kitayama + * Portions copyrighted (c) 2021 Roland Winistoerfer + * + * 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 TUSB_OPT_HOST_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_RX63X || \ + CFG_TUSB_MCU == OPT_MCU_RX65X || \ + CFG_TUSB_MCU == OPT_MCU_RX72N ) +#include "host/hcd.h" +#include "iodefine.h" + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ +#define SYSTEM_PRCR_PRC1 (1<<1) +#define SYSTEM_PRCR_PRKEY (0xA5u<<8) + +#define USB_DVSTCTR0_LOW (1u) +#define USB_DVSTCTR0_FULL (2u) + +#define USB_FIFOSEL_TX ((uint16_t)(1u<<5)) +#define USB_FIFOSEL_BIGEND ((uint16_t)(1u<<8)) +#define USB_FIFOSEL_MBW_8 ((uint16_t)(0u<<10)) +#define USB_FIFOSEL_MBW_16 ((uint16_t)(1u<<10)) +#define USB_IS0_CTSQ ((uint16_t)(7u)) +#define USB_IS0_DVSQ ((uint16_t)(7u<<4)) +#define USB_IS0_VALID ((uint16_t)(1u<<3)) +#define USB_IS0_BRDY ((uint16_t)(1u<<8)) +#define USB_IS0_NRDY ((uint16_t)(1u<<9)) +#define USB_IS0_BEMP ((uint16_t)(1u<<10)) +#define USB_IS0_CTRT ((uint16_t)(1u<<11)) +#define USB_IS0_DVST ((uint16_t)(1u<<12)) +#define USB_IS0_SOFR ((uint16_t)(1u<<13)) +#define USB_IS0_RESM ((uint16_t)(1u<<14)) +#define USB_IS0_VBINT ((uint16_t)(1u<<15)) +#define USB_IS1_SACK ((uint16_t)(1u<<4)) +#define USB_IS1_SIGN ((uint16_t)(1u<<5)) +#define USB_IS1_EOFERR ((uint16_t)(1u<<6)) +#define USB_IS1_ATTCH ((uint16_t)(1u<<11)) +#define USB_IS1_DTCH ((uint16_t)(1u<<12)) +#define USB_IS1_BCHG ((uint16_t)(1u<<14)) +#define USB_IS1_OVRCR ((uint16_t)(1u<<15)) + +#define USB_IS0_CTSQ_MSK (7u) +#define USB_IS0_CTSQ_SETUP (1u) +#define USB_IS0_DVSQ_DEF (1u<<4) +#define USB_IS0_DVSQ_ADDR (2u<<4) +#define USB_IS0_DVSQ_SUSP0 (4u<<4) +#define USB_IS0_DVSQ_SUSP1 (5u<<4) +#define USB_IS0_DVSQ_SUSP2 (6u<<4) +#define USB_IS0_DVSQ_SUSP3 (7u<<4) + +#define USB_PIPECTR_PID_MSK (3u) +#define USB_PIPECTR_PID_NAK (0u) +#define USB_PIPECTR_PID_BUF (1u) +#define USB_PIPECTR_PID_STALL (2u) +#define USB_PIPECTR_CCPL (1u<<2) +#define USB_PIPECTR_SQMON (1u<<6) +#define USB_PIPECTR_SQCLR (1u<<8) +#define USB_PIPECTR_ACLRM (1u<<9) +#define USB_PIPECTR_INBUFM (1u<<14) +#define USB_PIPECTR_BSTS (1u<<15) + +#define USB_FIFOCTR_DTLN (0x1FF) +#define USB_FIFOCTR_FRDY (1u<<13) +#define USB_FIFOCTR_BCLR (1u<<14) +#define USB_FIFOCTR_BVAL (1u<<15) + +#define USB_PIPECFG_SHTNAK (1u<<7) +#define USB_PIPECFG_DBLB (1u<<9) +#define USB_PIPECFG_BULK (1u<<14) +#define USB_PIPECFG_ISO (3u<<14) +#define USB_PIPECFG_INT (2u<<14) + +#define USB_DEVADD_LOW (1u<<6) +#define USB_DEVADD_FULL (2u<<6) + +#define FIFO_REQ_CLR (1u) +#define FIFO_COMPLETE (1u<<1) + +// Start of definition of packed structs (used by the CCRX toolchain) +TU_ATTR_PACKED_BEGIN +TU_ATTR_BIT_FIELD_ORDER_BEGIN + +typedef struct { + union { + struct { + uint16_t : 8; + uint16_t TRCLR: 1; + uint16_t TRENB: 1; + uint16_t : 0; + }; + uint16_t TRE; + }; + uint16_t TRN; +} reg_pipetre_t; + +typedef union { + struct { + volatile uint16_t u8: 8; + volatile uint16_t : 0; + }; + volatile uint16_t u16; +} hw_fifo_t; + +typedef struct TU_ATTR_PACKED +{ + void *buf; /* the start address of a transfer data buffer */ + uint16_t length; /* the number of bytes in the buffer */ + uint16_t remaining; /* the number of bytes remaining in the buffer */ + struct { + uint32_t ep : 8; /* an assigned endpoint address */ + uint32_t dev : 8; /* an assigned device address */ + uint32_t ff : 1; /* `buf` is TU_FUFO or POD */ + uint32_t : 0; + }; +} pipe_state_t; + +TU_ATTR_PACKED_END // End of definition of packed structs (used by the CCRX toolchain) +TU_ATTR_BIT_FIELD_ORDER_END + +typedef struct +{ + bool need_reset; /* The device has not been reset after connection. */ + pipe_state_t pipe[10]; + uint8_t ep[4][2][15]; /* a lookup table for a pipe index from an endpoint address */ + uint8_t ctl_mps[5]; /* EP0 max packet size for each device */ +} hcd_data_t; + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ +static hcd_data_t _hcd; + +static uint32_t disable_interrupt(void) +{ + uint32_t pswi; +#if defined(__CCRX__) + pswi = get_psw() & 0x010000; + clrpsw_i(); +#else + pswi = __builtin_rx_mvfc(0) & 0x010000; + __builtin_rx_clrpsw('I'); +#endif + return pswi; +} + +static void enable_interrupt(uint32_t pswi) +{ +#if defined(__CCRX__) + set_psw(get_psw() | pswi); +#else + __builtin_rx_mvtc(0, __builtin_rx_mvfc(0) | pswi); +#endif +} + +static unsigned find_pipe(unsigned xfer) +{ + switch (xfer) { + case TUSB_XFER_ISOCHRONOUS: + for (int i = 1; i <= 2; ++i) { + if (0 == _hcd.pipe[i].ep) return i; + } + break; + case TUSB_XFER_BULK: + for (int i = 3; i <= 5; ++i) { + if (0 == _hcd.pipe[i].ep) return i; + } + for (int i = 1; i <= 1; ++i) { + if (0 == _hcd.pipe[i].ep) return i; + } + break; + case TUSB_XFER_INTERRUPT: + for (int i = 6; i <= 9; ++i) { + if (0 == _hcd.pipe[i].ep) return i; + } + break; + default: + /* No support for control transfer */ + break; + } + return 0; +} + +static volatile uint16_t* get_pipectr(unsigned num) +{ + volatile uint16_t *ctr = NULL; + if (num) { + ctr = (volatile uint16_t*)&USB0.PIPE1CTR.WORD; + ctr += num - 1; + } else { + ctr = (volatile uint16_t*)&USB0.DCPCTR.WORD; + } + return ctr; +} + +static volatile reg_pipetre_t* get_pipetre(unsigned num) +{ + volatile reg_pipetre_t* tre = NULL; + if ((1 <= num) && (num <= 5)) { + tre = (volatile reg_pipetre_t*)&USB0.PIPE1TRE.WORD; + tre += num - 1; + } + return tre; +} + +static volatile uint16_t* addr_to_pipectr(uint8_t dev_addr, unsigned ep_addr) +{ + volatile uint16_t *ctr = NULL; + const unsigned epn = tu_edpt_number(ep_addr); + if (epn) { + const unsigned dir_in = tu_edpt_dir(ep_addr); + const unsigned num = _hcd.ep[dev_addr][dir_in][epn - 1]; + if (num) { + ctr = (volatile uint16_t*)&USB0.PIPE1CTR.WORD; + ctr += num - 1; + } + } else { + ctr = (volatile uint16_t*)&USB0.DCPCTR.WORD; + } + return ctr; +} + +static unsigned edpt0_max_packet_size(void) +{ + return USB0.DCPMAXP.BIT.MXPS; +} + +static unsigned edpt_max_packet_size(unsigned num) +{ + USB0.PIPESEL.WORD = num; + return USB0.PIPEMAXP.BIT.MXPS; +} + +static inline void pipe_wait_for_ready(unsigned num) +{ + while (USB0.D0FIFOSEL.BIT.CURPIPE != num) ; + while (!USB0.D0FIFOCTR.BIT.FRDY) ; +} + +static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) +{ + volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; + uintptr_t addr = (uintptr_t)buf; + while (len >= 2) { + reg->u16 = *(const uint16_t *)addr; + addr += 2; + len -= 2; + } + if (len) { + reg->u8 = *(const uint8_t *)addr; + ++addr; + } +} + +static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len) +{ + uint8_t *p = (uint8_t*)buf; + volatile uint8_t *reg = (volatile uint8_t*)fifo; /* byte access is always at base register address */ + while (len--) *p++ = *reg; +} + +static bool pipe0_xfer_in(void) +{ + pipe_state_t *pipe = &_hcd.pipe[0]; + const unsigned rem = pipe->remaining; + + const unsigned mps = edpt0_max_packet_size(); + const unsigned vld = USB0.CFIFOCTR.BIT.DTLN; + const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); + void *buf = pipe->buf; + if (len) { + USB0.DCPCTR.WORD = USB_PIPECTR_PID_NAK; + pipe_read_packet(buf, (volatile void*)&USB0.CFIFO.WORD, len); + pipe->buf = (uint8_t*)buf + len; + } + if (len < mps) USB0.CFIFOCTR.WORD = USB_FIFOCTR_BCLR; + pipe->remaining = rem - len; + if ((len < mps) || (rem == len)) { + pipe->buf = NULL; + return true; + } + USB0.DCPCTR.WORD = USB_PIPECTR_PID_BUF; + return false; +} + +static bool pipe0_xfer_out(void) +{ + pipe_state_t *pipe = &_hcd.pipe[0]; + const unsigned rem = pipe->remaining; + if (!rem) { + pipe->buf = NULL; + return true; + } + const unsigned mps = edpt0_max_packet_size(); + const unsigned len = TU_MIN(mps, rem); + void *buf = pipe->buf; + if (len) { + pipe_write_packet(buf, (volatile void*)&USB0.CFIFO.WORD, len); + pipe->buf = (uint8_t*)buf + len; + } + if (len < mps) USB0.CFIFOCTR.WORD = USB_FIFOCTR_BVAL; + pipe->remaining = rem - len; + return false; +} + +static bool pipe_xfer_in(unsigned num) +{ + pipe_state_t *pipe = &_hcd.pipe[num]; + const unsigned rem = pipe->remaining; + + USB0.D0FIFOSEL.WORD = num | USB_FIFOSEL_MBW_8; + const unsigned mps = edpt_max_packet_size(num); + pipe_wait_for_ready(num); + const unsigned vld = USB0.D0FIFOCTR.BIT.DTLN; + const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); + void *buf = pipe->buf; + if (len) { + pipe_read_packet(buf, (volatile void*)&USB0.D0FIFO.WORD, len); + pipe->buf = (uint8_t*)buf + len; + } + if (len < mps) USB0.D0FIFOCTR.WORD = USB_FIFOCTR_BCLR; + USB0.D0FIFOSEL.WORD = 0; + while (USB0.D0FIFOSEL.BIT.CURPIPE) ; /* if CURPIPE bits changes, check written value */ + pipe->remaining = rem - len; + if ((len < mps) || (rem == len)) { + pipe->buf = NULL; + return NULL != buf; + } + return false; +} + +static bool pipe_xfer_out(unsigned num) +{ + pipe_state_t *pipe = &_hcd.pipe[num]; + const unsigned rem = pipe->remaining; + + if (!rem) { + pipe->buf = NULL; + return true; + } + + USB0.D0FIFOSEL.WORD = num | USB_FIFOSEL_MBW_16 | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? USB_FIFOSEL_BIGEND : 0); + const unsigned mps = edpt_max_packet_size(num); + pipe_wait_for_ready(num); + const unsigned len = TU_MIN(rem, mps); + void *buf = pipe->buf; + if (len) { + pipe_write_packet(buf, (volatile void*)&USB0.D0FIFO.WORD, len); + pipe->buf = (uint8_t*)buf + len; + } + if (len < mps) USB0.D0FIFOCTR.WORD = USB_FIFOCTR_BVAL; + USB0.D0FIFOSEL.WORD = 0; + while (USB0.D0FIFOSEL.BIT.CURPIPE) ; /* if CURPIPE bits changes, check written value */ + pipe->remaining = rem - len; + return false; +} + +static bool process_pipe0_xfer(uint8_t dev_addr, uint8_t ep_addr, void* buffer, uint16_t buflen) +{ + (void)dev_addr; + const unsigned dir_in = tu_edpt_dir(ep_addr); + + /* configure fifo direction and access unit settings */ + if (dir_in) { /* IN, a byte */ + USB0.CFIFOSEL.WORD = USB_FIFOSEL_MBW_8; + while (USB0.CFIFOSEL.WORD & USB_FIFOSEL_TX) ; + } else { /* OUT, 2 bytes */ + USB0.CFIFOSEL.WORD = USB_FIFOSEL_TX | USB_FIFOSEL_MBW_16 | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? USB_FIFOSEL_BIGEND : 0); + while (!(USB0.CFIFOSEL.WORD & USB_FIFOSEL_TX)) ; + } + + pipe_state_t *pipe = &_hcd.pipe[0]; + pipe->ep = ep_addr; + pipe->length = buflen; + pipe->remaining = buflen; + if (buflen) { + pipe->buf = buffer; + if (!dir_in) { /* OUT */ + TU_ASSERT(USB0.DCPCTR.BIT.BSTS && (USB0.USBREQ.WORD & 0x80)); + pipe0_xfer_out(); + } + } else { /* ZLP */ + pipe->buf = NULL; + if (!dir_in) { /* OUT */ + USB0.CFIFOCTR.WORD = USB_FIFOCTR_BVAL; + } + if (dir_in == USB0.DCPCFG.BIT.DIR) { + TU_ASSERT(USB_PIPECTR_PID_NAK == USB0.DCPCTR.BIT.PID); + USB0.DCPCTR.BIT.SQSET = 1; + USB0.DCPCFG.BIT.DIR = dir_in ^ 1; + } + } + USB0.DCPCTR.WORD = USB_PIPECTR_PID_BUF; + return true; +} + +static bool process_pipe_xfer(uint8_t dev_addr, uint8_t ep_addr, void* buffer, uint16_t buflen) +{ + const unsigned epn = tu_edpt_number(ep_addr); + const unsigned dir_in = tu_edpt_dir(ep_addr); + const unsigned num = _hcd.ep[dev_addr - 1][dir_in][epn - 1]; + + TU_ASSERT(num); + + pipe_state_t *pipe = &_hcd.pipe[num]; + pipe->buf = buffer; + pipe->length = buflen; + pipe->remaining = buflen; + if (!dir_in) { /* OUT */ + if (buflen) { + pipe_xfer_out(num); + } else { /* ZLP */ + USB0.D0FIFOSEL.WORD = num; + pipe_wait_for_ready(num); + USB0.D0FIFOCTR.WORD = USB_FIFOCTR_BVAL; + USB0.D0FIFOSEL.WORD = 0; + while (USB0.D0FIFOSEL.BIT.CURPIPE) ; /* if CURPIPE bits changes, check written value */ + } + } else { + volatile uint16_t *ctr = get_pipectr(num); + volatile reg_pipetre_t *pt = get_pipetre(num); + if (pt) { + const unsigned mps = edpt_max_packet_size(num); + if (*ctr & 0x3) *ctr = USB_PIPECTR_PID_NAK; + pt->TRE = TU_BIT(8); + pt->TRN = (buflen + mps - 1) / mps; + pt->TRENB = 1; + } + *ctr = USB_PIPECTR_PID_BUF; + } + return true; +} + +static bool process_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, void* buffer, uint16_t buflen) +{ + const unsigned epn = tu_edpt_number(ep_addr); + if (0 == epn) { + return process_pipe0_xfer(dev_addr, ep_addr, buffer, buflen); + } else { + return process_pipe_xfer(dev_addr, ep_addr, buffer, buflen); + } +} + +static void process_pipe0_bemp(uint8_t rhport) +{ + (void)rhport; + bool completed = pipe0_xfer_out(); + if (completed) { + pipe_state_t *pipe = &_hcd.pipe[0]; + hcd_event_xfer_complete(pipe->dev, + tu_edpt_addr(0, TUSB_DIR_OUT), + pipe->length - pipe->remaining, + XFER_RESULT_SUCCESS, true); + } +} + +static void process_pipe_nrdy(uint8_t rhport, unsigned num) +{ + (void)rhport; + unsigned result; + uint16_t volatile *ctr = get_pipectr(num); + // TU_LOG1("NRDY %d %x\n", num, *ctr); + switch (*ctr & USB_PIPECTR_PID_MSK) { + default: return; + case USB_PIPECTR_PID_STALL: result = XFER_RESULT_STALLED; break; + case USB_PIPECTR_PID_NAK: result = XFER_RESULT_FAILED; break; + } + pipe_state_t *pipe = &_hcd.pipe[num]; + hcd_event_xfer_complete(pipe->dev, pipe->ep, + pipe->length - pipe->remaining, + result, true); +} + +static void process_pipe_brdy(uint8_t rhport, unsigned num) +{ + (void)rhport; + pipe_state_t *pipe = &_hcd.pipe[num]; + const unsigned dir_in = tu_edpt_dir(pipe->ep); + bool completed; + + if (dir_in) { /* IN */ + if (num) { + completed = pipe_xfer_in(num); + } else { + completed = pipe0_xfer_in(); + } + } else { + completed = pipe_xfer_out(num); + } + if (completed) { + hcd_event_xfer_complete(pipe->dev, pipe->ep, + pipe->length - pipe->remaining, + XFER_RESULT_SUCCESS, true); + // TU_LOG1("C %d %d\r\n", num, pipe->length - pipe->remaining); + } +} + + +/*------------------------------------------------------------------*/ +/* Host API + *------------------------------------------------------------------*/ +bool hcd_init(uint8_t rhport) +{ + (void)rhport; + /* Enable USB0 */ + uint32_t pswi = disable_interrupt(); + SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY | SYSTEM_PRCR_PRC1; + MSTP(USB0) = 0; + SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY; + enable_interrupt(pswi); + USB0.SYSCFG.BIT.SCKE = 1; + while (!USB0.SYSCFG.BIT.SCKE) ; + USB0.SYSCFG.BIT.DPRPU = 0; + USB0.SYSCFG.BIT.DRPD = 0; + USB0.SYSCFG.BIT.DCFM = 1; + USB0.SYSCFG.BIT.DRPD = 1; + for (volatile int i = 0; i < 30000; ++i) ; + USB0.SYSCFG.BIT.USBE = 1; + + USB.DPUSR0R.BIT.FIXPHY0 = 0u; /* USB0 Transceiver Output fixed */ +#if ( CFG_TUSB_MCU == OPT_MCU_RX72N ) + USB0.PHYSLEW.LONG = 0x5; + IR(PERIB, INTB185) = 0; +#else + IR(USB0, USBI0) = 0; +#endif + + /* Setup default control pipe */ + USB0.DCPCFG.WORD = USB_PIPECFG_SHTNAK; + USB0.DCPMAXP.WORD = 64; + USB0.INTENB0.WORD = USB_IS0_BRDY | USB_IS0_NRDY | USB_IS0_BEMP; + USB0.INTENB1.WORD = USB_IS1_SACK | USB_IS1_SIGN | + USB_IS1_ATTCH | USB_IS1_DTCH; + USB0.BEMPENB.WORD = 1; + USB0.NRDYENB.WORD = 1; + USB0.BRDYENB.WORD = 1; + return true; +} + +void hcd_int_enable(uint8_t rhport) +{ + (void)rhport; +#if ( CFG_TUSB_MCU == OPT_MCU_RX72N ) + IEN(PERIB, INTB185) = 1; +#else + IEN(USB0, USBI0) = 1; +#endif +} + +void hcd_int_disable(uint8_t rhport) +{ + (void)rhport; +#if ( CFG_TUSB_MCU == OPT_MCU_RX72N ) + IEN(PERIB, INTB185) = 0; +#else + IEN(USB0, USBI0) = 0; +#endif +} + +uint32_t hcd_frame_number(uint8_t rhport) +{ + (void)rhport; + /* The device must be reset at least once after connection + * in order to start the frame counter. */ + if (_hcd.need_reset) hcd_port_reset(rhport); + return USB0.FRMNUM.BIT.FRNM; +} + +/*--------------------------------------------------------------------+ + * Port API + *--------------------------------------------------------------------+*/ +bool hcd_port_connect_status(uint8_t rhport) +{ + (void)rhport; + return USB0.INTSTS1.BIT.ATTCH ? true: false; +} + +void hcd_port_reset(uint8_t rhport) +{ + USB0.DCPCTR.WORD = USB_PIPECTR_PID_NAK; + while (USB0.DCPCTR.BIT.PBUSY) ; + hcd_int_disable(rhport); + USB0.DVSTCTR0.BIT.UACT = 0; + if (USB0.DCPCTR.BIT.SUREQ) + USB0.DCPCTR.BIT.SUREQCLR = 1; + hcd_int_enable(rhport); + /* Reset should be asserted 10-20ms. */ + USB0.DVSTCTR0.BIT.USBRST = 1; + for (volatile int i = 0; i < 2400000; ++i) ; + USB0.DVSTCTR0.BIT.USBRST = 0; + USB0.DVSTCTR0.BIT.UACT = 1; + _hcd.need_reset = false; +} + +tusb_speed_t hcd_port_speed_get(uint8_t rhport) +{ + (void)rhport; + switch (USB0.DVSTCTR0.BIT.RHST) { + default: return TUSB_SPEED_INVALID; + case USB_DVSTCTR0_FULL: return TUSB_SPEED_FULL; + case USB_DVSTCTR0_LOW: return TUSB_SPEED_LOW; + } +} + +void hcd_device_close(uint8_t rhport, uint8_t dev_addr) +{ + (void)rhport; + uint16_t volatile *ctr; + TU_ASSERT(dev_addr < 6,); /* USBa can only handle addresses from 0 to 5. */ + if (!dev_addr) return; + _hcd.ctl_mps[dev_addr] = 0; + uint8_t *ep = &_hcd.ep[dev_addr - 1][0][0]; + for (int i = 0; i < 2 * 15; ++i, ++ep) { + unsigned num = *ep; + if (!num || dev_addr != _hcd.pipe[num].dev) continue; + + ctr = (uint16_t volatile*)&USB0.PIPE1CTR.WORD + num - 1; + *ctr = 0; + USB0.NRDYENB.WORD &= ~TU_BIT(num); + USB0.BRDYENB.WORD &= ~TU_BIT(num); + USB0.PIPESEL.WORD = num; + USB0.PIPECFG.WORD = 0; + USB0.PIPEMAXP.WORD = 0; + + _hcd.pipe[num].ep = 0; + _hcd.pipe[num].dev = 0; + *ep = 0; + } +} + +/*--------------------------------------------------------------------+ + * Endpoints API + *--------------------------------------------------------------------+*/ +bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) +{ + (void)rhport; + // TU_LOG1("S %d %x\n", dev_addr, USB0.DCPCTR.WORD); + + TU_ASSERT(dev_addr < 6); /* USBa can only handle addresses from 0 to 5. */ + TU_ASSERT(0 == USB0.DCPCTR.BIT.SUREQ); + + USB0.DCPCTR.WORD = USB_PIPECTR_PID_NAK; + + _hcd.pipe[0].buf = NULL; + _hcd.pipe[0].length = 8; + _hcd.pipe[0].remaining = 0; + _hcd.pipe[0].dev = dev_addr; + + while (USB0.DCPCTR.BIT.PBUSY) ; + USB0.DCPMAXP.WORD = (dev_addr << 12) | _hcd.ctl_mps[dev_addr]; + + /* Set direction in advance for DATA stage */ + uint8_t const bmRequesttype = setup_packet[0]; + USB0.DCPCFG.BIT.DIR = tu_edpt_dir(bmRequesttype) ? 0: 1; + + uint16_t const* p = (uint16_t const*)(uintptr_t)&setup_packet[0]; + USB0.USBREQ.WORD = tu_htole16(p[0]); + USB0.USBVAL = p[1]; + USB0.USBINDX = p[2]; + USB0.USBLENG = p[3]; + + USB0.DCPCTR.BIT.SUREQ = 1; + return true; +} + +bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) +{ + (void)rhport; + TU_ASSERT(dev_addr < 6); /* USBa can only handle addresses from 0 to 5. */ + + const unsigned ep_addr = ep_desc->bEndpointAddress; + const unsigned epn = tu_edpt_number(ep_addr); + const unsigned mps = tu_edpt_packet_size(ep_desc); + if (0 == epn) { + USB0.DCPCTR.WORD = USB_PIPECTR_PID_NAK; + hcd_devtree_info_t devtree; + hcd_devtree_get_info(dev_addr, &devtree); + uint16_t volatile *devadd = (uint16_t volatile *)(uintptr_t)&USB0.DEVADD0.WORD; + devadd += dev_addr; + while (USB0.DCPCTR.BIT.PBUSY) ; + USB0.DCPMAXP.WORD = (dev_addr << 12) | mps; + *devadd = (TUSB_SPEED_FULL == devtree.speed) ? USB_DEVADD_FULL : USB_DEVADD_LOW; + _hcd.ctl_mps[dev_addr] = mps; + return true; + } + + const unsigned dir_in = tu_edpt_dir(ep_addr); + const unsigned xfer = ep_desc->bmAttributes.xfer; + if (xfer == TUSB_XFER_ISOCHRONOUS && mps > 256) { + /* USBa supports up to 256 bytes */ + return false; + } + const unsigned num = find_pipe(xfer); + if (!num) return false; + _hcd.pipe[num].dev = dev_addr; + _hcd.pipe[num].ep = ep_addr; + _hcd.ep[dev_addr - 1][dir_in][epn - 1] = num; + + /* setup pipe */ + hcd_int_disable(rhport); + USB0.PIPESEL.WORD = num; + USB0.PIPEMAXP.WORD = (dev_addr << 12) | mps; + volatile uint16_t *ctr = get_pipectr(num); + *ctr = USB_PIPECTR_ACLRM | USB_PIPECTR_SQCLR; + *ctr = 0; + unsigned cfg = ((1 ^ dir_in) << 4) | epn; + if (xfer == TUSB_XFER_BULK) { + cfg |= USB_PIPECFG_BULK | USB_PIPECFG_SHTNAK | USB_PIPECFG_DBLB; + } else if (xfer == TUSB_XFER_INTERRUPT) { + cfg |= USB_PIPECFG_INT; + } else { + cfg |= USB_PIPECFG_ISO | USB_PIPECFG_DBLB; + } + USB0.PIPECFG.WORD = cfg; + USB0.BRDYSTS.WORD = 0x1FFu ^ TU_BIT(num); + USB0.NRDYENB.WORD |= TU_BIT(num); + USB0.BRDYENB.WORD |= TU_BIT(num); + if (!dir_in) { + *ctr = USB_PIPECTR_PID_BUF; + } + hcd_int_enable(rhport); + + return true; +} + +bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen) +{ + bool r; + hcd_int_disable(rhport); + // TU_LOG1("X %d %x %u\n", dev_addr, ep_addr, buflen); + r = process_edpt_xfer(dev_addr, ep_addr, buffer, buflen); + hcd_int_enable(rhport); + return r; +} + +bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) +{ + uint16_t volatile *ctr = addr_to_pipectr(dev_addr, ep_addr); + TU_ASSERT(ctr); + *ctr = USB_PIPECTR_SQCLR; + unsigned const epn = tu_edpt_number(ep_addr); + if (!epn) return true; + + if (tu_edpt_dir(ep_addr)) { /* IN */ + const unsigned num = _hcd.ep[dev_addr - 1][1][epn - 1]; + hcd_int_disable(0); + USB0.PIPESEL.WORD = num; + if (USB0.PIPECFG.BIT.TYPE != 1) { + *ctr = USB_PIPECTR_PID_BUF; + } + hcd_int_enable(0); + } else { + *ctr = USB_PIPECTR_PID_BUF; + } + return true; +} + +//--------------------------------------------------------------------+ +// ISR +//--------------------------------------------------------------------+ +void hcd_int_handler(uint8_t rhport) +{ + (void)rhport; +#if defined(__CCRX__) + static const int Mod37BitPosition[] = { + -1, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4, + 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5, + 20, 8, 19, 18}; +#endif + + unsigned is1 = USB0.INTSTS1.WORD; + unsigned is0 = USB0.INTSTS0.WORD; + /* clear active bits except VALID (don't write 0 to already cleared bits according to the HW manual) */ + USB0.INTSTS1.WORD = ~((USB_IS1_SACK | USB_IS1_SIGN | USB_IS1_ATTCH | USB_IS1_DTCH) & is1); + USB0.INTSTS0.WORD = ~((USB_IS0_BRDY | USB_IS0_NRDY | USB_IS0_BEMP) & is0); + // TU_LOG1("IS %04x %04x\n", is0, is1); + is1 &= USB0.INTENB1.WORD; + is0 &= USB0.INTENB0.WORD; + + if (is1 & USB_IS1_SACK) { + /* Set DATA1 in advance for the next transfer. */ + USB0.DCPCTR.BIT.SQSET = 1; + hcd_event_xfer_complete(USB0.DCPMAXP.BIT.DEVSEL, + tu_edpt_addr(0, TUSB_DIR_OUT), + 8, XFER_RESULT_SUCCESS, true); + } + if (is1 & USB_IS1_SIGN) { + hcd_event_xfer_complete(USB0.DCPMAXP.BIT.DEVSEL, + tu_edpt_addr(0, TUSB_DIR_OUT), + 8, XFER_RESULT_FAILED, true); + } + if (is1 & USB_IS1_ATTCH) { + USB0.DVSTCTR0.BIT.UACT = 1; + _hcd.need_reset = true; + USB0.INTENB1.WORD = (USB0.INTENB1.WORD & ~USB_IS1_ATTCH) | USB_IS1_DTCH; + hcd_event_device_attach(rhport, true); + } + if (is1 & USB_IS1_DTCH) { + USB0.DVSTCTR0.BIT.UACT = 0; + if (USB0.DCPCTR.BIT.SUREQ) + USB0.DCPCTR.BIT.SUREQCLR = 1; + USB0.INTENB1.WORD = (USB0.INTENB1.WORD & ~USB_IS1_DTCH) | USB_IS1_ATTCH; + hcd_event_device_remove(rhport, true); + } + + if (is0 & USB_IS0_BEMP) { + const unsigned s = USB0.BEMPSTS.WORD; + USB0.BEMPSTS.WORD = 0; + if (s & 1) { + process_pipe0_bemp(rhport); + } + } + if (is0 & USB_IS0_NRDY) { + const unsigned m = USB0.NRDYENB.WORD; + unsigned s = USB0.NRDYSTS.WORD & m; + USB0.NRDYSTS.WORD = ~s; + while (s) { +#if defined(__CCRX__) + const unsigned num = Mod37BitPosition[(-s & s) % 37]; +#else + const unsigned num = __builtin_ctz(s); +#endif + process_pipe_nrdy(rhport, num); + s &= ~TU_BIT(num); + } + } + if (is0 & USB_IS0_BRDY) { + const unsigned m = USB0.BRDYENB.WORD; + unsigned s = USB0.BRDYSTS.WORD & m; + /* clear active bits (don't write 0 to already cleared bits according to the HW manual) */ + USB0.BRDYSTS.WORD = ~s; + while (s) { +#if defined(__CCRX__) + const unsigned num = Mod37BitPosition[(-s & s) % 37]; +#else + const unsigned num = __builtin_ctz(s); +#endif + process_pipe_brdy(rhport, num); + s &= ~TU_BIT(num); + } + } +} + +#endif From a750c9c90244e54f95f4b801672c15ad7c7019bc Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Mon, 27 Dec 2021 21:28:46 +0900 Subject: [PATCH 087/504] Increase stack size --- hw/bsp/rx/boards/rx65n_target/r5f565ne.ld | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/bsp/rx/boards/rx65n_target/r5f565ne.ld b/hw/bsp/rx/boards/rx65n_target/r5f565ne.ld index 8e5617f23..27914e64f 100644 --- a/hw/bsp/rx/boards/rx65n_target/r5f565ne.ld +++ b/hw/bsp/rx/boards/rx65n_target/r5f565ne.ld @@ -1,5 +1,5 @@ -__USTACK_SIZE = 0x00000400; -__ISTACK_SIZE = 0x00000400; +__USTACK_SIZE = 0x00000800; +__ISTACK_SIZE = 0x00000800; MEMORY { From 2c0fcc2fa7e9eec26211760c9d69dcd564e48f2a Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Mon, 27 Dec 2021 21:36:49 +0900 Subject: [PATCH 088/504] Add statements for control VBUS --- src/portable/renesas/usba/hcd_usba.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/portable/renesas/usba/hcd_usba.c b/src/portable/renesas/usba/hcd_usba.c index 360a8d75f..2dc7f9394 100644 --- a/src/portable/renesas/usba/hcd_usba.c +++ b/src/portable/renesas/usba/hcd_usba.c @@ -538,6 +538,9 @@ bool hcd_init(uint8_t rhport) USB0.SYSCFG.BIT.DPRPU = 0; USB0.SYSCFG.BIT.DRPD = 0; USB0.SYSCFG.BIT.DCFM = 1; + + USB0.DVSTCTR0.BIT.VBUSEN = 1; + USB0.SYSCFG.BIT.DRPD = 1; for (volatile int i = 0; i < 30000; ++i) ; USB0.SYSCFG.BIT.USBE = 1; From 745607357b9fc46aafb496f628c60c6fb18af6f9 Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Mon, 27 Dec 2021 21:51:23 +0900 Subject: [PATCH 089/504] Update Renesas RX status --- docs/reference/supported.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index 1f7f395cb..445643733 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -60,7 +60,7 @@ Supported MCUs +--------------+---------+-------------+--------+------+-----------+-------------------+--------------+ | Raspberry Pi | RP2040 | ✔ | ✔ | ✖ | rp2040 | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ -| Renesas | RX 63N, 65N, 72N | ✔ | ✖ | ✖ | usba | | +| Renesas | RX 63N, 65N, 72N | ✔ | ✔ | ✖ | usba | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ | Silabs | EFM32GG12 | ✔ | | ✖ | dwc2 | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ From 2b8b8a3a97e8e895409104689d16387967648c6d Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Mon, 27 Dec 2021 22:55:28 +0900 Subject: [PATCH 090/504] Fix hcd_edpt_clear_stall --- src/portable/renesas/usba/hcd_usba.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/portable/renesas/usba/hcd_usba.c b/src/portable/renesas/usba/hcd_usba.c index 2dc7f9394..35eb060cd 100644 --- a/src/portable/renesas/usba/hcd_usba.c +++ b/src/portable/renesas/usba/hcd_usba.c @@ -765,19 +765,17 @@ bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) { uint16_t volatile *ctr = addr_to_pipectr(dev_addr, ep_addr); TU_ASSERT(ctr); + + const uint32_t pid = *ctr & 0x3; + if (pid & 2) { + *ctr = pid & 2; + *ctr = 0; + } *ctr = USB_PIPECTR_SQCLR; unsigned const epn = tu_edpt_number(ep_addr); if (!epn) return true; - if (tu_edpt_dir(ep_addr)) { /* IN */ - const unsigned num = _hcd.ep[dev_addr - 1][1][epn - 1]; - hcd_int_disable(0); - USB0.PIPESEL.WORD = num; - if (USB0.PIPECFG.BIT.TYPE != 1) { - *ctr = USB_PIPECTR_PID_BUF; - } - hcd_int_enable(0); - } else { + if (!tu_edpt_dir(ep_addr)) { /* OUT */ *ctr = USB_PIPECTR_PID_BUF; } return true; From 2d13ecde1bdb94575398b2e0e64e6e50a192fd18 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 29 Dec 2021 18:59:47 +0700 Subject: [PATCH 091/504] add allwinnner driver as submodule --- .gitmodules | 3 + hw/mcu/allwinner | 1 + hw/mcu/allwinner/f1c100s/f1c100s.ld | 136 --- hw/mcu/allwinner/f1c100s/include/arm32.h | 150 ---- .../allwinner/f1c100s/include/f1c100s-gpio.h | 66 -- .../allwinner/f1c100s/include/f1c100s-irq.h | 104 --- .../allwinner/f1c100s/include/f1c100s-reset.h | 39 - .../allwinner/f1c100s/include/f1c100s-util.h | 139 --- .../f1c100s/include/f1c100s/reg-ccu.h | 55 -- .../f1c100s/include/f1c100s/reg-dram.h | 39 - hw/mcu/allwinner/f1c100s/include/io.h | 57 -- hw/mcu/allwinner/f1c100s/include/irqflags.h | 104 --- hw/mcu/allwinner/f1c100s/include/malloc.h | 35 - hw/mcu/allwinner/f1c100s/include/printf.h | 99 --- hw/mcu/allwinner/f1c100s/include/sizes.h | 42 - hw/mcu/allwinner/f1c100s/include/types.h | 55 -- hw/mcu/allwinner/f1c100s/lib/malloc.c | 834 ------------------ hw/mcu/allwinner/f1c100s/lib/memcpy.S | 404 --------- hw/mcu/allwinner/f1c100s/lib/memset.S | 79 -- hw/mcu/allwinner/f1c100s/lib/printf.c | 757 ---------------- hw/mcu/allwinner/f1c100s/machine/exception.c | 76 -- .../allwinner/f1c100s/machine/f1c100s-intc.c | 173 ---- hw/mcu/allwinner/f1c100s/machine/start.S | 314 ------- hw/mcu/allwinner/f1c100s/machine/sys-clock.c | 124 --- .../allwinner/f1c100s/machine/sys-copyself.c | 111 --- hw/mcu/allwinner/f1c100s/machine/sys-dram.c | 506 ----------- hw/mcu/allwinner/f1c100s/machine/sys-mmu.c | 57 -- .../allwinner/f1c100s/machine/sys-spi-flash.c | 204 ----- hw/mcu/allwinner/f1c100s/machine/sys-uart.c | 83 -- 29 files changed, 4 insertions(+), 4842 deletions(-) create mode 160000 hw/mcu/allwinner delete mode 100644 hw/mcu/allwinner/f1c100s/f1c100s.ld delete mode 100644 hw/mcu/allwinner/f1c100s/include/arm32.h delete mode 100644 hw/mcu/allwinner/f1c100s/include/f1c100s-gpio.h delete mode 100644 hw/mcu/allwinner/f1c100s/include/f1c100s-irq.h delete mode 100644 hw/mcu/allwinner/f1c100s/include/f1c100s-reset.h delete mode 100644 hw/mcu/allwinner/f1c100s/include/f1c100s-util.h delete mode 100644 hw/mcu/allwinner/f1c100s/include/f1c100s/reg-ccu.h delete mode 100644 hw/mcu/allwinner/f1c100s/include/f1c100s/reg-dram.h delete mode 100644 hw/mcu/allwinner/f1c100s/include/io.h delete mode 100644 hw/mcu/allwinner/f1c100s/include/irqflags.h delete mode 100644 hw/mcu/allwinner/f1c100s/include/malloc.h delete mode 100644 hw/mcu/allwinner/f1c100s/include/printf.h delete mode 100644 hw/mcu/allwinner/f1c100s/include/sizes.h delete mode 100644 hw/mcu/allwinner/f1c100s/include/types.h delete mode 100644 hw/mcu/allwinner/f1c100s/lib/malloc.c delete mode 100644 hw/mcu/allwinner/f1c100s/lib/memcpy.S delete mode 100644 hw/mcu/allwinner/f1c100s/lib/memset.S delete mode 100644 hw/mcu/allwinner/f1c100s/lib/printf.c delete mode 100644 hw/mcu/allwinner/f1c100s/machine/exception.c delete mode 100644 hw/mcu/allwinner/f1c100s/machine/f1c100s-intc.c delete mode 100644 hw/mcu/allwinner/f1c100s/machine/start.S delete mode 100644 hw/mcu/allwinner/f1c100s/machine/sys-clock.c delete mode 100644 hw/mcu/allwinner/f1c100s/machine/sys-copyself.c delete mode 100644 hw/mcu/allwinner/f1c100s/machine/sys-dram.c delete mode 100644 hw/mcu/allwinner/f1c100s/machine/sys-mmu.c delete mode 100644 hw/mcu/allwinner/f1c100s/machine/sys-spi-flash.c delete mode 100644 hw/mcu/allwinner/f1c100s/machine/sys-uart.c diff --git a/.gitmodules b/.gitmodules index 5c79ea910..4ce5d0f0d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -134,3 +134,6 @@ [submodule "hw/mcu/infineon/mtb-xmclib-cat3"] path = hw/mcu/infineon/mtb-xmclib-cat3 url = https://github.com/Infineon/mtb-xmclib-cat3.git +[submodule "hw/mcu/allwinner"] + path = hw/mcu/allwinner + url = https://github.com/hathach/allwinner_driver.git diff --git a/hw/mcu/allwinner b/hw/mcu/allwinner new file mode 160000 index 000000000..c56955e15 --- /dev/null +++ b/hw/mcu/allwinner @@ -0,0 +1 @@ +Subproject commit c56955e156b1050a4a8ccf8589555148f00a1bb6 diff --git a/hw/mcu/allwinner/f1c100s/f1c100s.ld b/hw/mcu/allwinner/f1c100s/f1c100s.ld deleted file mode 100644 index 43c353bbd..000000000 --- a/hw/mcu/allwinner/f1c100s/f1c100s.ld +++ /dev/null @@ -1,136 +0,0 @@ -OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(_start) - -STACK_UND_SIZE = 0x10000; -STACK_ABT_SIZE = 0x10000; -STACK_IRQ_SIZE = 0x10000; -STACK_FIQ_SIZE = 0x10000; -STACK_SRV_SIZE = 0x40000; - -MEMORY -{ - ram : org = 0x80000000, len = 8M - heap : org = 0x81000000, len = 16M -} - -SECTIONS -{ - .bootloader : - { - PROVIDE(__bootloader_start = .); - PROVIDE(__image_start = .); - PROVIDE(__text_start = .); - _build/*/obj/hw/mcu/allwinner/*/machine/start_asm.o (.text) - _build/*/obj/hw/mcu/allwinner/*/lib/memcpy_asm.o (.text) - _build/*/obj/hw/mcu/allwinner/*/lib/memset_asm.o (.text) - _build/*/obj/hw/mcu/allwinner/*/machine/sys-uart.o (.text*) - _build/*/obj/hw/mcu/allwinner/*/machine/sys-clock.o (.text*) - _build/*/obj/hw/mcu/allwinner/*/machine/sys-dram.o (.text*) - _build/*/obj/hw/mcu/allwinner/*/machine/sys-mmu.o (.text*) - _build/*/obj/hw/mcu/allwinner/*/machine/sys-spi-flash.o (.text*) - _build/*/obj/hw/mcu/allwinner/*/machine/sys-copyself.o (.text*) - PROVIDE(__bootloader_end = .); - } > ram - - __bootloader_size = SIZEOF(.bootloader); - - .text : - { - *(.text*) - *(.glue*) - *(.note.gnu.build-id) - PROVIDE(__text_end = .); - } > ram - - .rodata ALIGN(8) : - { - PROVIDE(__rodata_start = .); - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) - PROVIDE(__rodata_end = .); - } > ram - - .data_shadow ALIGN(8) : - { - PROVIDE(__data_shadow_start = .); - PROVIDE(__data_shadow_end = (. + SIZEOF(.data))); - PROVIDE(__image_end = __data_shadow_end); - } > ram - - .data : AT(ADDR(.data_shadow)) - { - PROVIDE(__data_start = .); - *(.data*) - . = ALIGN(8); - PROVIDE(__data_end = .); - } > ram - - .ARM.exidx ALIGN(8) : - { - PROVIDE (__exidx_start = .); - *(.ARM.exidx*) - PROVIDE (__exidx_end = .); - } > ram - - .ARM.extab ALIGN(8) : - { - PROVIDE (__extab_start = .); - *(.ARM.extab*) - PROVIDE (__extab_end = .); - } > ram - - .bss ALIGN(8) (NOLOAD) : - { - PROVIDE(__bss_start = .); - *(.bss*) - *(.sbss*) - *(COMMON) - . = ALIGN(8); - PROVIDE(__bss_end = .); - } > ram - - .stack ALIGN(8) (NOLOAD) : - { - PROVIDE(__stack_start = .); - PROVIDE(__stack_und_start = .); - . += STACK_UND_SIZE; - PROVIDE(__stack_und_end = .); - . = ALIGN(8); - PROVIDE(__stack_abt_start = .); - . += STACK_ABT_SIZE; - PROVIDE(__stack_abt_end = .); - . = ALIGN(8); - PROVIDE(__stack_irq_start = .); - . += STACK_IRQ_SIZE; - PROVIDE(__stack_irq_end = .); - . = ALIGN(8); - PROVIDE(__stack_fiq_start = .); - . += STACK_FIQ_SIZE; - PROVIDE(__stack_fiq_end = .); - . = ALIGN(8); - PROVIDE(__stack_srv_start = .); - . += STACK_SRV_SIZE; - PROVIDE(__stack_srv_end = .); - . = ALIGN(8); - PROVIDE(__stack_end = .); - } > ram - - .heap ALIGN(8) (NOLOAD) : - { - PROVIDE(__heap_start = ORIGIN(heap)); - PROVIDE(__heap_end = ORIGIN(heap) + LENGTH(heap)); - } > heap - - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_info 0 : { *(.debug_info) } - .debug_line 0 : { *(.debug_line) } - .debug_pubnames 0 : { *(.debug_pubnames) } - .debug_aranges 0 : { *(.debug_aranges) } -} diff --git a/hw/mcu/allwinner/f1c100s/include/arm32.h b/hw/mcu/allwinner/f1c100s/include/arm32.h deleted file mode 100644 index a3a254551..000000000 --- a/hw/mcu/allwinner/f1c100s/include/arm32.h +++ /dev/null @@ -1,150 +0,0 @@ -#ifndef __ARM32_H__ -#define __ARM32_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -struct arm_regs_t { - uint32_t r[13]; - uint32_t sp; - uint32_t lr; - uint32_t pc; - uint32_t cpsr; -}; - -static inline uint32_t arm32_read_p15_c1(void) -{ - uint32_t value; - - __asm__ __volatile__( - "mrc p15, 0, %0, c1, c0, 0" - : "=r" (value) - : - : "memory"); - - return value; -} - -static inline void arm32_write_p15_c1(uint32_t value) -{ - __asm__ __volatile__( - "mcr p15, 0, %0, c1, c0, 0" - : - : "r" (value) - : "memory"); - arm32_read_p15_c1(); -} - -static inline void arm32_interrupt_enable(void) -{ - uint32_t tmp; - - __asm__ __volatile__( - "mrs %0, cpsr\n" - "bic %0, %0, #(1<<7)\n" - "msr cpsr_cxsf, %0" - : "=r" (tmp) - : - : "memory"); -} - -static inline void arm32_interrupt_disable(void) -{ - uint32_t tmp; - - __asm__ __volatile__( - "mrs %0, cpsr\n" - "orr %0, %0, #(1<<7)\n" - "msr cpsr_cxsf, %0" - : "=r" (tmp) - : - : "memory"); -} - -static inline void arm32_mmu_enable(void) -{ - uint32_t value = arm32_read_p15_c1(); - arm32_write_p15_c1(value | (1 << 0)); -} - -static inline void arm32_mmu_disable(void) -{ - uint32_t value = arm32_read_p15_c1(); - arm32_write_p15_c1(value & ~(1 << 0)); -} - -static inline void arm32_dcache_enable(void) -{ - uint32_t value = arm32_read_p15_c1(); - arm32_write_p15_c1(value | (1 << 2)); -} - -static inline void arm32_dcache_disable(void) -{ - uint32_t value = arm32_read_p15_c1(); - arm32_write_p15_c1(value & ~(1 << 2)); -} - -static inline void arm32_icache_enable(void) -{ - uint32_t value = arm32_read_p15_c1(); - arm32_write_p15_c1(value | (1 << 12)); -} - -static inline void arm32_icache_disable(void) -{ - uint32_t value = arm32_read_p15_c1(); - arm32_write_p15_c1(value & ~(1 << 12)); -} - -static inline uint32_t arm32_smp_processor_id(void) -{ - uint32_t tmp; - - __asm__ __volatile__( - "mrc p15,0,%0,c0,c0,5\n" - "and %0,%0,#0x3\n" - : "=r" (tmp) - : - : "memory"); - return tmp; -} - -static inline void arm32_ttb_set(uint32_t base) -{ - __asm__ __volatile__( - "mcr p15, 0, %0, c2, c0, 0" - : - : "r" (base) - : "memory"); -} - -static inline void arm32_domain_set(uint32_t domain) -{ - __asm__ __volatile__( - "mcr p15, 0, %0, c3, c0, 0" - : - : "r" (domain) - : "memory"); -} - -static inline void arm32_tlb_invalidate(void) -{ - __asm__ __volatile__( - "mov r0, #0\n" - "mcr p15, 0, r0, c7, c10, 4\n" - "mcr p15, 0, r0, c8, c6, 0\n" - "mcr p15, 0, r0, c8, c5, 0\n" - : - : - : "r0"); -} - -#ifdef __cplusplus -} -#endif - -#endif /* __ARM32_H__ */ diff --git a/hw/mcu/allwinner/f1c100s/include/f1c100s-gpio.h b/hw/mcu/allwinner/f1c100s/include/f1c100s-gpio.h deleted file mode 100644 index 3dbe8bf13..000000000 --- a/hw/mcu/allwinner/f1c100s/include/f1c100s-gpio.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef __F1C100S_GPIO_H__ -#define __F1C100S_GPIO_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#define F1C100S_GPIOA0 (0) -#define F1C100S_GPIOA1 (1) -#define F1C100S_GPIOA2 (2) -#define F1C100S_GPIOA3 (3) - -#define F1C100S_GPIOC0 (64) -#define F1C100S_GPIOC1 (65) -#define F1C100S_GPIOC2 (66) -#define F1C100S_GPIOC3 (67) - -#define F1C100S_GPIOD0 (96) -#define F1C100S_GPIOD1 (97) -#define F1C100S_GPIOD2 (98) -#define F1C100S_GPIOD3 (99) -#define F1C100S_GPIOD4 (100) -#define F1C100S_GPIOD5 (101) -#define F1C100S_GPIOD6 (102) -#define F1C100S_GPIOD7 (103) -#define F1C100S_GPIOD8 (104) -#define F1C100S_GPIOD9 (105) -#define F1C100S_GPIOD10 (106) -#define F1C100S_GPIOD11 (107) -#define F1C100S_GPIOD12 (108) -#define F1C100S_GPIOD13 (109) -#define F1C100S_GPIOD14 (110) -#define F1C100S_GPIOD15 (111) -#define F1C100S_GPIOD16 (112) -#define F1C100S_GPIOD17 (113) -#define F1C100S_GPIOD18 (114) -#define F1C100S_GPIOD19 (115) -#define F1C100S_GPIOD20 (116) -#define F1C100S_GPIOD21 (117) - -#define F1C100S_GPIOE0 (128) -#define F1C100S_GPIOE1 (129) -#define F1C100S_GPIOE2 (130) -#define F1C100S_GPIOE3 (131) -#define F1C100S_GPIOE4 (132) -#define F1C100S_GPIOE5 (133) -#define F1C100S_GPIOE6 (134) -#define F1C100S_GPIOE7 (135) -#define F1C100S_GPIOE8 (136) -#define F1C100S_GPIOE9 (137) -#define F1C100S_GPIOE10 (138) -#define F1C100S_GPIOE11 (139) -#define F1C100S_GPIOE12 (140) - -#define F1C100S_GPIOF0 (160) -#define F1C100S_GPIOF1 (161) -#define F1C100S_GPIOF2 (162) -#define F1C100S_GPIOF3 (163) -#define F1C100S_GPIOF4 (164) -#define F1C100S_GPIOF5 (165) - -#ifdef __cplusplus -} -#endif - -#endif /* __F1C100S_GPIO_H__ */ diff --git a/hw/mcu/allwinner/f1c100s/include/f1c100s-irq.h b/hw/mcu/allwinner/f1c100s/include/f1c100s-irq.h deleted file mode 100644 index 410d1be93..000000000 --- a/hw/mcu/allwinner/f1c100s/include/f1c100s-irq.h +++ /dev/null @@ -1,104 +0,0 @@ -#ifndef __F1C100S_IRQ_H__ -#define __F1C100S_IRQ_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#define F1C100S_IRQ_NMI (0) -#define F1C100S_IRQ_UART0 (1) -#define F1C100S_IRQ_UART1 (2) -#define F1C100S_IRQ_UART2 (3) -#define F1C100S_IRQ_SPDIF (5) -#define F1C100S_IRQ_CIR (6) -#define F1C100S_IRQ_I2C0 (7) -#define F1C100S_IRQ_I2C1 (8) -#define F1C100S_IRQ_I2C2 (9) -#define F1C100S_IRQ_SPI0 (10) -#define F1C100S_IRQ_SPI1 (11) -#define F1C100S_IRQ_TIMER0 (13) -#define F1C100S_IRQ_TIMER1 (14) -#define F1C100S_IRQ_TIMER2 (15) -#define F1C100S_IRQ_WDOG (16) -#define F1C100S_IRQ_RSB (17) -#define F1C100S_IRQ_DMA (18) -#define F1C100S_IRQ_TP (20) -#define F1C100S_IRQ_AUDIO (21) -#define F1C100S_IRQ_LRADC (22) -#define F1C100S_IRQ_MMC0 (23) -#define F1C100S_IRQ_MMC1 (24) -#define F1C100S_IRQ_USBOTG (26) -#define F1C100S_IRQ_TVD (27) -#define F1C100S_IRQ_TVE (28) -#define F1C100S_IRQ_LCD (29) -#define F1C100S_IRQ_DEFE (30) -#define F1C100S_IRQ_DEBE (31) -#define F1C100S_IRQ_CSI (32) -#define F1C100S_IRQ_DEITLA (33) -#define F1C100S_IRQ_VE (34) -#define F1C100S_IRQ_I2S (35) -#define F1C100S_IRQ_GPIOD (38) -#define F1C100S_IRQ_GPIOE (39) -#define F1C100S_IRQ_GPIOF (40) - -#define F1C100S_IRQ_GPIOD0 (64) -#define F1C100S_IRQ_GPIOD1 (65) -#define F1C100S_IRQ_GPIOD2 (66) -#define F1C100S_IRQ_GPIOD3 (67) -#define F1C100S_IRQ_GPIOD4 (68) -#define F1C100S_IRQ_GPIOD5 (69) -#define F1C100S_IRQ_GPIOD6 (70) -#define F1C100S_IRQ_GPIOD7 (71) -#define F1C100S_IRQ_GPIOD8 (72) -#define F1C100S_IRQ_GPIOD9 (73) -#define F1C100S_IRQ_GPIOD10 (74) -#define F1C100S_IRQ_GPIOD11 (75) -#define F1C100S_IRQ_GPIOD12 (76) -#define F1C100S_IRQ_GPIOD13 (77) -#define F1C100S_IRQ_GPIOD14 (78) -#define F1C100S_IRQ_GPIOD15 (79) -#define F1C100S_IRQ_GPIOD17 (80) -#define F1C100S_IRQ_GPIOD18 (81) -#define F1C100S_IRQ_GPIOD19 (82) -#define F1C100S_IRQ_GPIOD20 (83) -#define F1C100S_IRQ_GPIOD21 (84) - -#define F1C100S_IRQ_GPIOE0 (96) -#define F1C100S_IRQ_GPIOE1 (97) -#define F1C100S_IRQ_GPIOE2 (98) -#define F1C100S_IRQ_GPIOE3 (99) -#define F1C100S_IRQ_GPIOE4 (100) -#define F1C100S_IRQ_GPIOE5 (101) -#define F1C100S_IRQ_GPIOE6 (102) -#define F1C100S_IRQ_GPIOE7 (103) -#define F1C100S_IRQ_GPIOE8 (104) -#define F1C100S_IRQ_GPIOE9 (105) -#define F1C100S_IRQ_GPIOE10 (106) -#define F1C100S_IRQ_GPIOE11 (107) -#define F1C100S_IRQ_GPIOE12 (108) - -#define F1C100S_IRQ_GPIOF0 (128) -#define F1C100S_IRQ_GPIOF1 (129) -#define F1C100S_IRQ_GPIOF2 (130) -#define F1C100S_IRQ_GPIOF3 (131) -#define F1C100S_IRQ_GPIOF4 (132) -#define F1C100S_IRQ_GPIOF5 (133) - -typedef void (*IRQHandleTypeDef)(void); - -uint8_t f1c100s_intc_get_nirq(void); -void f1c100s_intc_dispatch(uint8_t nIRQ); -void f1c100s_intc_set_isr(uint8_t nIRQ, IRQHandleTypeDef handle); -void f1c100s_intc_enable_irq(uint8_t nIRQ); -void f1c100s_intc_disable_irq(uint8_t nIRQ); -void f1c100s_intc_unmask_irq(uint8_t nIRQ); -void f1c100s_intc_mask_irq(uint8_t nIRQ); -void f1c100s_intc_force_irq(uint8_t nIRQ); -void f1c100s_intc_clear_pend(uint8_t nIRQ); -void f1c100s_intc_init(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __F1C100S_IRQ_H__ */ diff --git a/hw/mcu/allwinner/f1c100s/include/f1c100s-reset.h b/hw/mcu/allwinner/f1c100s/include/f1c100s-reset.h deleted file mode 100644 index e787a1ac1..000000000 --- a/hw/mcu/allwinner/f1c100s/include/f1c100s-reset.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef __F1C100S_RESET_H__ -#define __F1C100S_RESET_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#define F1C100S_RESET_DMA (6) -#define F1C100S_RESET_SD0 (8) -#define F1C100S_RESET_SD1 (9) -#define F1C100S_RESET_SDRAM (14) -#define F1C100S_RESET_SPI0 (20) -#define F1C100S_RESET_SPI1 (21) -#define F1C100S_RESET_USB_OTG (24) -#define F1C100S_RESET_VE (32) -#define F1C100S_RESET_LCD (36) -#define F1C100S_RESET_DEINTERLACE (37) -#define F1C100S_RESET_CSI (40) -#define F1C100S_RESET_TVD (41) -#define F1C100S_RESET_TVE (42) -#define F1C100S_RESET_DEBE (44) -#define F1C100S_RESET_DEFE (46) -#define F1C100S_RESET_ADDA (64) -#define F1C100S_RESET_SPDIF (65) -#define F1C100S_RESET_CIR (66) -#define F1C100S_RESET_RSB (67) -#define F1C100S_RESET_DAUDIO (76) -#define F1C100S_RESET_I2C0 (80) -#define F1C100S_RESET_I2C1 (81) -#define F1C100S_RESET_I2C2 (82) -#define F1C100S_RESET_UART0 (84) -#define F1C100S_RESET_UART1 (85) -#define F1C100S_RESET_UART2 (86) - -#ifdef __cplusplus -} -#endif - -#endif /* __F1C100S_RESET_H__ */ diff --git a/hw/mcu/allwinner/f1c100s/include/f1c100s-util.h b/hw/mcu/allwinner/f1c100s/include/f1c100s-util.h deleted file mode 100644 index cb3829f82..000000000 --- a/hw/mcu/allwinner/f1c100s/include/f1c100s-util.h +++ /dev/null @@ -1,139 +0,0 @@ -// Designed by Hong Xuyao - -#ifndef __TARGET_H__ -#define __TARGET_H__ -//////////////////////////////////////////////////////////////////////////////// -#include -typedef unsigned long ubase_t; - -#define MEM_PI_SRAM __attribute__((section("SRAM"))) - -#define MEM_PI_SUMMARY __attribute__((section("SUMMARY"))) - -#define MEM_PI_NOINIT __attribute__((section("NOINIT"),zero_init)) - -#define MEM_PI_CPUONLY __attribute__((section("CPUONLY"),zero_init)) - -#define MEM_PI_HARDWARE __attribute__((section("HARDWARE"),zero_init,aligned(32))) - -#define MEM_PI_NCNB __attribute__((section("NCNB"),zero_init,aligned(32))) - -#define MEM_PI_STACK __attribute__((section("STACK"),zero_init,aligned(8))) - -#define CACHE_ALIGNED __attribute__((aligned(32))) - -#ifndef INLINE -#define INLINE __attribute__((always_inline)) -#endif - -#ifndef NOINLINE -#define NOINLINE __attribute__((noinline)) -#endif - -#ifndef NOINLINE_FUNC -#define NOINLINE_FUNC __attribute__((noinline)) -#endif - -#ifndef ALIGN -#define ALIGN(n) __attribute__((aligned(n))) -#endif - -#define CPU_SR_DECL ubase_t cpu_sr - -#ifdef __thumb__ -#define __SWITCH_TO_ARM__ -#pragma arm -#endif - -#if 0 -#define CPU_ENTER_CRITICAL() do{cpu_sr = util_enter_critical();}while(0) -#else -#define CPU_ENTER_CRITICAL() do{cpu_sr = __fast_enter_critical();}while(0) -static inline ubase_t __fast_enter_critical(void) -{ - ubase_t cpu_sr, tmp_sr; - __asm volatile { - MRS cpu_sr, CPSR - ORR tmp_sr, cpu_sr, #0xC0 - MSR CPSR_c, tmp_sr - } - return cpu_sr; -} -#endif - -#if 0 -#define CPU_EXIT_CRITICAL() do{util_exit_critical(cpu_sr);}while(0) -#else -#define CPU_EXIT_CRITICAL() do{__fast_exit_critical(cpu_sr);}while(0) -static inline void __fast_exit_critical(ubase_t cpu_sr) -{ - __asm volatile { - MSR CPSR_c, cpu_sr - } -} -#endif - -static inline unsigned CPU_CLZ16(uint16_t val) -{ - __asm volatile { - CLZ val, val - } - return (val - 16); -} - -static inline uint8_t __swap_byte(uint8_t newval, uint8_t volatile* pmem) -{ - uint8_t oldval; - __asm volatile { - SWPB oldval, newval, [pmem] - }; - return oldval; -} - -static inline uint32_t UTL_REV32(uint32_t val) -{ - uint32_t tmpval; - __asm volatile { - EOR tmpval, val, val, ROR #16 - MOV tmpval, tmpval, LSR #8 - BIC tmpval, tmpval, #0xFF00 - EOR val, tmpval, val, ROR #8 - } - return val; -} - -static inline uint16_t UTL_REV16(uint16_t val) -{ - uint32_t tmpval; - __asm volatile { - LSR tmpval, val, #8 - ORR val, tmpval, val, LSL #8 - BIC val, val, #0xFF0000 - } - return val; -} - -#ifdef __SWITCH_TO_ARM__ -#undef __SWITCH_TO_ARM__ -#pragma thumb -#endif - -#ifndef COUNTOF -#define COUNTOF(ar) (sizeof(ar)/sizeof(ar[0])) -#endif -/* -void util_halt(void); -void util_fastloop(ubase_t n); -ubase_t util_getCPSR(void); -ubase_t util_enter_critical(void); -void util_exit_critical(ubase_t sr); -void util_enable_interrupt(void); -void util_disable_interrupt(void); - -void target_wdt_setup(void); -void target_wdt_feed(void); -void target_reset(void); -*/ -//////////////////////////////////////////////////////////////////////////////// -#endif /* __TARGET_H__ */ - diff --git a/hw/mcu/allwinner/f1c100s/include/f1c100s/reg-ccu.h b/hw/mcu/allwinner/f1c100s/include/f1c100s/reg-ccu.h deleted file mode 100644 index 1770ad7ff..000000000 --- a/hw/mcu/allwinner/f1c100s/include/f1c100s/reg-ccu.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef __F1C100S_REG_CCU_H__ -#define __F1C100S_REG_CCU_H__ - -#define F1C100S_CCU_BASE (0x01c20000) - -#define CCU_PLL_CPU_CTRL (0x000) -#define CCU_PLL_AUDIO_CTRL (0x008) -#define CCU_PLL_VIDEO_CTRL (0x010) -#define CCU_PLL_VE_CTRL (0x018) -#define CCU_PLL_DDR_CTRL (0x020) -#define CCU_PLL_PERIPH_CTRL (0x028) -#define CCU_CPU_CFG (0x050) -#define CCU_AHB_APB_CFG (0x054) - -#define CCU_BUS_CLK_GATE0 (0x060) -#define CCU_BUS_CLK_GATE1 (0x064) -#define CCU_BUS_CLK_GATE2 (0x068) - -#define CCU_SDMMC0_CLK (0x088) -#define CCU_SDMMC1_CLK (0x08c) -#define CCU_DAUDIO_CLK (0x0b0) -#define CCU_SPDIF_CLK (0x0b4) -#define CCU_I2S_CLK (0x0b8) -#define CCU_USBPHY_CFG (0x0cc) -#define CCU_DRAM_CLK_GATE (0x100) -#define CCU_DEBE_CLK (0x104) -#define CCU_DEFE_CLK (0x10c) -#define CCU_LCD_CLK (0x118) -#define CCU_DEINTERLACE_CLK (0x11c) -#define CCU_TVE_CLK (0x120) -#define CCU_TVD_CLK (0x124) -#define CCU_CSI_CLK (0x134) -#define CCU_VE_CLK (0x13c) -#define CCU_ADDA_CLK (0x140) -#define CCU_AVS_CLK (0x144) - -#define CCU_PLL_STABLE_TIME0 (0x200) -#define CCU_PLL_STABLE_TIME1 (0x204) -#define CCU_PLL_CPU_BIAS (0x220) -#define CCU_PLL_AUDIO_BIAS (0x224) -#define CCU_PLL_VIDEO_BIAS (0x228) -#define CCU_PLL_VE_BIAS (0x22c) -#define CCU_PLL_DDR0_BIAS (0x230) -#define CCU_PLL_PERIPH_BIAS (0x234) -#define CCU_PLL_CPU_TUN (0x250) -#define CCU_PLL_DDR_TUN (0x260) -#define CCU_PLL_AUDIO_PAT (0x284) -#define CCU_PLL_VIDEO_PAT (0x288) -#define CCU_PLL_DDR0_PAT (0x290) - -#define CCU_BUS_SOFT_RST0 (0x2c0) -#define CCU_BUS_SOFT_RST1 (0x2c4) -#define CCU_BUS_SOFT_RST3 (0x2d0) - -#endif /* __F1C100S_REG_CCU_H__ */ diff --git a/hw/mcu/allwinner/f1c100s/include/f1c100s/reg-dram.h b/hw/mcu/allwinner/f1c100s/include/f1c100s/reg-dram.h deleted file mode 100644 index 8a0ac3e0e..000000000 --- a/hw/mcu/allwinner/f1c100s/include/f1c100s/reg-dram.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef __F1C100S_REG_DRAM_H__ -#define __F1C100S_REG_DRAM_H__ - -#define F1C100S_DRAM_BASE (0x01c01000) - -#define DRAM_SCONR (0x00) -#define DRAM_STMG0R (0x04) -#define DRAM_STMG1R (0x08) -#define DRAM_SCTLR (0x0c) -#define DRAM_SREFR (0x10) -#define DRAM_SEXTMR (0x14) -#define DRAM_DDLYR (0x24) -#define DRAM_DADRR (0x28) -#define DRAM_DVALR (0x2c) -#define DRAM_DRPTR0 (0x30) -#define DRAM_DRPTR1 (0x34) -#define DRAM_DRPTR2 (0x38) -#define DRAM_DRPTR3 (0x3c) -#define DRAM_SEFR (0x40) -#define DRAM_MAE (0x44) -#define DRAM_ASPR (0x48) -#define DRAM_SDLY0 (0x4C) -#define DRAM_SDLY1 (0x50) -#define DRAM_SDLY2 (0x54) -#define DRAM_MCR0 (0x100) -#define DRAM_MCR1 (0x104) -#define DRAM_MCR2 (0x108) -#define DRAM_MCR3 (0x10c) -#define DRAM_MCR4 (0x110) -#define DRAM_MCR5 (0x114) -#define DRAM_MCR6 (0x118) -#define DRAM_MCR7 (0x11c) -#define DRAM_MCR8 (0x120) -#define DRAM_MCR9 (0x124) -#define DRAM_MCR10 (0x128) -#define DRAM_MCR11 (0x12c) -#define DRAM_BWCR (0x140) - -#endif /* __F1C100S_REG_DRAM_H__ */ diff --git a/hw/mcu/allwinner/f1c100s/include/io.h b/hw/mcu/allwinner/f1c100s/include/io.h deleted file mode 100644 index f0dad1785..000000000 --- a/hw/mcu/allwinner/f1c100s/include/io.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef __IO_H__ -#define __IO_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -static inline u8_t read8(virtual_addr_t addr) -{ - return( *((volatile u8_t *)(addr)) ); -} - -static inline u16_t read16(virtual_addr_t addr) -{ - return( *((volatile u16_t *)(addr)) ); -} - -static inline u32_t read32(virtual_addr_t addr) -{ - return( *((volatile u32_t *)(addr)) ); -} - -static inline u64_t read64(virtual_addr_t addr) -{ - return( *((volatile u64_t *)(addr)) ); -} - -static inline void write8(virtual_addr_t addr, u8_t value) -{ - *((volatile u8_t *)(addr)) = value; -} - -static inline void write16(virtual_addr_t addr, u16_t value) -{ - *((volatile u16_t *)(addr)) = value; -} - -static inline void write32(virtual_addr_t addr, u32_t value) -{ - *((volatile u32_t *)(addr)) = value; -} - -static inline void write64(virtual_addr_t addr, u64_t value) -{ - *((volatile u64_t *)(addr)) = value; -} - -virtual_addr_t phys_to_virt(physical_addr_t phys); -physical_addr_t virt_to_phys(virtual_addr_t virt); - -#ifdef __cplusplus -} -#endif - -#endif /* __IO_H__ */ diff --git a/hw/mcu/allwinner/f1c100s/include/irqflags.h b/hw/mcu/allwinner/f1c100s/include/irqflags.h deleted file mode 100644 index e4ef97cd2..000000000 --- a/hw/mcu/allwinner/f1c100s/include/irqflags.h +++ /dev/null @@ -1,104 +0,0 @@ -#ifndef __ARM32_IRQFLAGS_H__ -#define __ARM32_IRQFLAGS_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#if __ARM32_ARCH__ == 5 - -static inline void arch_local_irq_enable(void) -{ - irq_flags_t temp; - - __asm__ __volatile__( - "mrs %0, cpsr\n" - "bic %0, %0, #(1<<7)\n" - "msr cpsr_c, %0" - : "=r" (temp) - : - : "memory", "cc"); -} - -static inline void arch_local_irq_disable(void) -{ - irq_flags_t temp; - - __asm__ __volatile__( - "mrs %0, cpsr\n" - "orr %0, %0, #(1<<7)\n" - "msr cpsr_c, %0" - : "=r" (temp) - : - : "memory", "cc"); -} - -static inline irq_flags_t arch_local_irq_save(void) -{ - irq_flags_t flags, temp; - - __asm__ __volatile__( - "mrs %0, cpsr\n" - "orr %1, %0, #(1<<7)\n" - "msr cpsr_c, %1" - : "=r" (flags), "=r" (temp) - : - : "memory", "cc"); - - return flags; -} - -static inline void arch_local_irq_restore(irq_flags_t flags) -{ - __asm__ __volatile__( - "msr cpsr_c, %0" - : - : "r" (flags) - : "memory", "cc"); -} -#else -static inline void arch_local_irq_enable(void) -{ - __asm__ __volatile__("cpsie i" ::: "memory", "cc"); -} - -static inline void arch_local_irq_disable(void) -{ - __asm__ __volatile__("cpsid i" ::: "memory", "cc"); -} - -static inline irq_flags_t arch_local_irq_save(void) -{ - irq_flags_t flags; - - __asm__ __volatile__( - "mrs %0, cpsr\n" - "cpsid i" - : "=r" (flags) - : - : "memory", "cc"); - return flags; -} - -static inline void arch_local_irq_restore(irq_flags_t flags) -{ - __asm__ __volatile__( - "msr cpsr_c, %0" - : - : "r" (flags) - : "memory", "cc"); -} -#endif - -#define local_irq_enable() do { arch_local_irq_enable(); } while(0) -#define local_irq_disable() do { arch_local_irq_disable(); } while(0) -#define local_irq_save(flags) do { flags = arch_local_irq_save(); } while(0) -#define local_irq_restore(flags) do { arch_local_irq_restore(flags); } while(0) - -#ifdef __cplusplus -} -#endif - -#endif /* __ARM32_IRQFLAGS_H__ */ diff --git a/hw/mcu/allwinner/f1c100s/include/malloc.h b/hw/mcu/allwinner/f1c100s/include/malloc.h deleted file mode 100644 index 6669fe48c..000000000 --- a/hw/mcu/allwinner/f1c100s/include/malloc.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef __MALLOC_H__ -#define __MALLOC_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include -#include - -void * mm_create(void * mem, size_t bytes); -void mm_destroy(void * mm); -void * mm_get_pool(void * mm); -void * mm_add_pool(void * mm, void * mem, size_t bytes); -void mm_remove_pool(void * mm, void * pool); -void * mm_malloc(void * mm, size_t size); -void * mm_memalign(void * mm, size_t align, size_t size); -void * mm_realloc(void * mm, void * ptr, size_t size); -void mm_free(void * mm, void * ptr); - -void * malloc(size_t size); -void * memalign(size_t align, size_t size); -void * realloc(void * ptr, size_t size); -void * calloc(size_t nmemb, size_t size); -void free(void * ptr); - -void do_init_mem_pool(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __MALLOC_H__ */ diff --git a/hw/mcu/allwinner/f1c100s/include/printf.h b/hw/mcu/allwinner/f1c100s/include/printf.h deleted file mode 100644 index 632bfc20e..000000000 --- a/hw/mcu/allwinner/f1c100s/include/printf.h +++ /dev/null @@ -1,99 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// \author (c) Marco Paland (info@paland.com) -// 2014-2018, PALANDesign Hannover, Germany -// -// \license The MIT License (MIT) -// -// 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. -// -// \brief Tiny printf, sprintf and snprintf implementation, optimized for speed on -// embedded systems with a very limited resources. -// Use this instead of bloated standard/newlib printf. -// These routines are thread safe and reentrant! -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _PRINTF_H_ -#define _PRINTF_H_ - -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif - - -/** - * Output a character to a custom device like UART, used by the printf() function - * This function is declared here only. You have to write your custom implementation somewhere - * \param character Character to output - */ -void _putchar(char character); - - -/** - * Tiny printf implementation - * You have to implement _putchar if you use printf() - * \param format A string that specifies the format of the output - * \return The number of characters that are written into the array, not counting the terminating null character - */ -int printf(const char* format, ...); - - -/** - * Tiny sprintf implementation - * Due to security reasons (buffer overflow) YOU SHOULD CONSIDER USING (V)SNPRINTF INSTEAD! - * \param buffer A pointer to the buffer where to store the formatted string. MUST be big enough to store the output! - * \param format A string that specifies the format of the output - * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character - */ -int sprintf(char* buffer, const char* format, ...); - - -/** - * Tiny snprintf/vsnprintf implementation - * \param buffer A pointer to the buffer where to store the formatted string - * \param count The maximum number of characters to store in the buffer, including a terminating null character - * \param format A string that specifies the format of the output - * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character - * If the formatted string is truncated the buffer size (count) is returned - */ -int snprintf(char* buffer, size_t count, const char* format, ...); -int vsnprintf(char* buffer, size_t count, const char* format, va_list va); - - -/** - * printf with output function - * You may use this as dynamic alternative to printf() with its fixed _putchar() output - * \param out An output function which takes one character and an argument pointer - * \param arg An argument pointer for user data passed to output function - * \param format A string that specifies the format of the output - * \return The number of characters that are sent to the output function, not counting the terminating null character - */ -int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...); - - -#ifdef __cplusplus -} -#endif - - -#endif // _PRINTF_H_ diff --git a/hw/mcu/allwinner/f1c100s/include/sizes.h b/hw/mcu/allwinner/f1c100s/include/sizes.h deleted file mode 100644 index 3edeed503..000000000 --- a/hw/mcu/allwinner/f1c100s/include/sizes.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef __SIZES_H__ -#define __SIZES_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#define SZ_16 (0x00000010) -#define SZ_256 (0x00000100) -#define SZ_512 (0x00000200) - -#define SZ_1K (0x00000400) -#define SZ_4K (0x00001000) -#define SZ_8K (0x00002000) -#define SZ_16K (0x00004000) -#define SZ_32K (0x00008000) -#define SZ_64K (0x00010000) -#define SZ_128K (0x00020000) -#define SZ_256K (0x00040000) -#define SZ_512K (0x00080000) - -#define SZ_1M (0x00100000) -#define SZ_2M (0x00200000) -#define SZ_4M (0x00400000) -#define SZ_8M (0x00800000) -#define SZ_16M (0x01000000) -#define SZ_32M (0x02000000) -#define SZ_64M (0x04000000) -#define SZ_128M (0x08000000) -#define SZ_256M (0x10000000) -#define SZ_512M (0x20000000) - -#define SZ_1G (0x40000000) -#define SZ_2G (0x80000000) - -#define ARRAY_SIZE(array) ( sizeof(array) / sizeof((array)[0]) ) - -#ifdef __cplusplus -} -#endif - -#endif /* __SIZES_H__ */ diff --git a/hw/mcu/allwinner/f1c100s/include/types.h b/hw/mcu/allwinner/f1c100s/include/types.h deleted file mode 100644 index 61b87b6d7..000000000 --- a/hw/mcu/allwinner/f1c100s/include/types.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef __ARM32_TYPES_H__ -#define __ARM32_TYPES_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef signed char s8_t; -typedef unsigned char u8_t; - -typedef signed short s16_t; -typedef unsigned short u16_t; - -typedef signed int s32_t; -typedef unsigned int u32_t; - -typedef signed long long s64_t; -typedef unsigned long long u64_t; - -typedef signed long long intmax_t; -typedef unsigned long long uintmax_t; - -typedef signed int ptrdiff_t; -typedef signed int intptr_t; -typedef unsigned int uintptr_t; - -typedef unsigned int size_t; -typedef signed int ssize_t; - -// typedef signed int off_t; -typedef signed long long loff_t; - -typedef signed int bool_t; - -typedef signed int register_t; -typedef unsigned int irq_flags_t; - -typedef unsigned int virtual_addr_t; -typedef unsigned int virtual_size_t; -typedef unsigned int physical_addr_t; -typedef unsigned int physical_size_t; - -typedef struct { - volatile long counter; -} atomic_t; - -typedef struct { - volatile long lock; -} spinlock_t; - -#ifdef __cplusplus -} -#endif - -#endif /* __ARM32_TYPES_H__ */ diff --git a/hw/mcu/allwinner/f1c100s/lib/malloc.c b/hw/mcu/allwinner/f1c100s/lib/malloc.c deleted file mode 100644 index 763746a47..000000000 --- a/hw/mcu/allwinner/f1c100s/lib/malloc.c +++ /dev/null @@ -1,834 +0,0 @@ -/* - * lib/libc/malloc/malloc.c - */ - -#include - -static void * __heap_pool = NULL; - -/* - * Some macros. - */ -#define tlsf_cast(t, exp) ((t)(exp)) -#define tlsf_min(a, b) ((a) < (b) ? (a) : (b)) -#define tlsf_max(a, b) ((a) > (b) ? (a) : (b)) - -#define tlsf_assert assert -#define tlsf_insist(x) { tlsf_assert(x); if (!(x)) { status--; } } - -#if defined(__ARM64__) || defined(__X64__) -# define TLSF_64BIT -#else -# undef TLSF_64BIT -#endif - -/* - * Public constants - */ -enum tlsf_public -{ - /* - * log2 of number of linear subdivisions of block sizes - */ - SL_INDEX_COUNT_LOG2 = 5, -}; - -/* - * Private constants - */ -enum tlsf_private -{ -#if defined(TLSF_64BIT) - /* - * All allocation sizes and addresses are aligned to 8 bytes - */ - ALIGN_SIZE_LOG2 = 3, -#else - /* - * All allocation sizes and addresses are aligned to 4 bytes - */ - ALIGN_SIZE_LOG2 = 2, -#endif - ALIGN_SIZE = (1 << ALIGN_SIZE_LOG2), - -#if defined(TLSF_64BIT) - FL_INDEX_MAX = 32, -#else - FL_INDEX_MAX = 30, -#endif - SL_INDEX_COUNT = (1 << SL_INDEX_COUNT_LOG2), - FL_INDEX_SHIFT = (SL_INDEX_COUNT_LOG2 + ALIGN_SIZE_LOG2), - FL_INDEX_COUNT = (FL_INDEX_MAX - FL_INDEX_SHIFT + 1), - - SMALL_BLOCK_SIZE = (1 << FL_INDEX_SHIFT), -}; - -/* - * Block header structure - */ -typedef struct block_header_t -{ - /* - * Points to the previous physical block - */ - struct block_header_t * prev_phys_block; - - /* - * The size of this block, excluding the block header - */ - size_t size; - - /* - * Next and previous free blocks - */ - struct block_header_t * next_free; - struct block_header_t * prev_free; -} block_header_t; - -/* - * The TLSF control structure. - */ -typedef struct control_t -{ - /* - * Empty lists point at this block to indicate they are free. - */ - block_header_t block_null; - - /* - * Bitmaps for free lists. - */ - unsigned int fl_bitmap; - unsigned int sl_bitmap[FL_INDEX_COUNT]; - - /* - * Head of free lists. - */ - block_header_t * blocks[FL_INDEX_COUNT][SL_INDEX_COUNT]; -} control_t; - -/* - * A type used for casting when doing pointer arithmetic. - */ -typedef ptrdiff_t tlsfptr_t; - -/* - * Associated constants - */ -static const size_t block_header_free_bit = 1 << 0; -static const size_t block_header_prev_free_bit = 1 << 1; -static const size_t block_header_overhead = sizeof(size_t); -static const size_t block_start_offset = offsetof(block_header_t, size) + sizeof(size_t); -static const size_t block_size_min = sizeof(block_header_t) - sizeof(block_header_t *); -static const size_t block_size_max = tlsf_cast(size_t, 1) << FL_INDEX_MAX; - -#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) && defined(__GNUC_PATCHLEVEL__) -static int tlsf_ffs(unsigned int word) -{ - return __builtin_ffs(word) - 1; -} - -static int tlsf_fls(unsigned int word) -{ - const int bit = word ? 32 - __builtin_clz(word) : 0; - return bit - 1; -} -#else -static int tlsf_fls_generic(unsigned int word) -{ - int bit = 32; - - if (!word) bit -= 1; - if (!(word & 0xffff0000)) { word <<= 16; bit -= 16; } - if (!(word & 0xff000000)) { word <<= 8; bit -= 8; } - if (!(word & 0xf0000000)) { word <<= 4; bit -= 4; } - if (!(word & 0xc0000000)) { word <<= 2; bit -= 2; } - if (!(word & 0x80000000)) { word <<= 1; bit -= 1; } - - return bit; -} - -static int tlsf_ffs(unsigned int word) -{ - return tlsf_fls_generic(word & (~word + 1)) - 1; -} - -static int tlsf_fls(unsigned int word) -{ - return tlsf_fls_generic(word) - 1; -} -#endif - -#if defined(TLSF_64BIT) -static int tlsf_fls_sizet(size_t size) -{ - int high = (int)(size >> 32); - int bits = 0; - if(high) - { - bits = 32 + tlsf_fls(high); - } - else - { - bits = tlsf_fls((int)size & 0xffffffff); - - } - return bits; -} -#else -#define tlsf_fls_sizet tlsf_fls -#endif - -static size_t block_get_size(const block_header_t * block) -{ - return block->size & ~(block_header_free_bit | block_header_prev_free_bit); -} - -static void block_set_size(block_header_t * block, size_t size) -{ - const size_t oldsize = block->size; - block->size = size | (oldsize & (block_header_free_bit | block_header_prev_free_bit)); -} - -static int block_is_last(const block_header_t * block) -{ - return (0 == block_get_size(block)); -} - -static int block_is_free(const block_header_t * block) -{ - return tlsf_cast(int, block->size & block_header_free_bit); -} - -static void block_set_free(block_header_t * block) -{ - block->size |= block_header_free_bit; -} - -static void block_set_used(block_header_t * block) -{ - block->size &= ~block_header_free_bit; -} - -static int block_is_prev_free(const block_header_t * block) -{ - return tlsf_cast(int, block->size & block_header_prev_free_bit); -} - -static void block_set_prev_free(block_header_t * block) -{ - block->size |= block_header_prev_free_bit; -} - -static void block_set_prev_used(block_header_t * block) -{ - block->size &= ~block_header_prev_free_bit; -} - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wcast-align" -static block_header_t * block_from_ptr(void * ptr) -{ - return tlsf_cast(block_header_t *, tlsf_cast(unsigned char*, ptr) - block_start_offset); -} -#pragma GCC diagnostic pop - -static void * block_to_ptr(block_header_t * block) -{ - return tlsf_cast(void *, tlsf_cast(unsigned char*, block) + block_start_offset); -} - -static block_header_t * offset_to_block(void * ptr, size_t size) -{ - return tlsf_cast(block_header_t *, tlsf_cast(tlsfptr_t, ptr) + size); -} - -static block_header_t * block_prev(block_header_t * block) -{ - return block->prev_phys_block; -} - -static block_header_t * block_next(block_header_t * block) -{ - block_header_t * next = offset_to_block(block_to_ptr(block), block_get_size(block) - block_header_overhead); - tlsf_assert(!block_is_last(block)); - return next; -} - -static block_header_t * block_link_next(block_header_t * block) -{ - block_header_t * next = block_next(block); - next->prev_phys_block = block; - return next; -} - -static void block_mark_as_free(block_header_t * block) -{ - block_header_t * next = block_link_next(block); - block_set_prev_free(next); - block_set_free(block); -} - -static void block_mark_as_used(block_header_t * block) -{ - block_header_t * next = block_next(block); - block_set_prev_used(next); - block_set_used(block); -} - -static size_t align_up(size_t x, size_t align) -{ - tlsf_assert(0 == (align & (align - 1)) && "must align to a power of two"); - return (x + (align - 1)) & ~(align - 1); -} - -static size_t align_down(size_t x, size_t align) -{ - tlsf_assert(0 == (align & (align - 1)) && "must align to a power of two"); - return x - (x & (align - 1)); -} - -static void * align_ptr(const void * ptr, size_t align) -{ - const tlsfptr_t aligned = (tlsf_cast(tlsfptr_t, ptr) + (align - 1)) & ~(align - 1); - tlsf_assert(0 == (align & (align - 1)) && "must align to a power of two"); - return tlsf_cast(void*, aligned); -} - -static size_t adjust_request_size(size_t size, size_t align) -{ - size_t adjust = 0; - if (size && size < block_size_max) - { - const size_t aligned = align_up(size, align); - adjust = tlsf_max(aligned, block_size_min); - } - return adjust; -} - -static void mapping_insert(size_t size, int * fli, int * sli) -{ - int fl, sl; - if (size < SMALL_BLOCK_SIZE) - { - fl = 0; - sl = tlsf_cast(int, size) / (SMALL_BLOCK_SIZE / SL_INDEX_COUNT); - } - else - { - fl = tlsf_fls_sizet(size); - sl = tlsf_cast(int, size >> (fl - SL_INDEX_COUNT_LOG2)) ^ (1 << SL_INDEX_COUNT_LOG2); - fl -= (FL_INDEX_SHIFT - 1); - } - *fli = fl; - *sli = sl; -} - -static void mapping_search(size_t size, int * fli, int * sli) -{ - if (size >= (1 << SL_INDEX_COUNT_LOG2)) - { - const size_t round = (1 << (tlsf_fls_sizet(size) - SL_INDEX_COUNT_LOG2)) - 1; - size += round; - } - mapping_insert(size, fli, sli); -} - -static block_header_t * search_suitable_block(control_t * control, int * fli, int * sli) -{ - int fl = *fli; - int sl = *sli; - - unsigned int sl_map = control->sl_bitmap[fl] & (~0U << sl); - if (!sl_map) - { - const unsigned int fl_map = control->fl_bitmap & (~0U << (fl + 1)); - if (!fl_map) - { - return 0; - } - - fl = tlsf_ffs(fl_map); - *fli = fl; - sl_map = control->sl_bitmap[fl]; - } - tlsf_assert(sl_map && "internal error - second level bitmap is null"); - sl = tlsf_ffs(sl_map); - *sli = sl; - - return control->blocks[fl][sl]; -} - -static void remove_free_block(control_t * control, block_header_t * block, int fl, int sl) -{ - block_header_t * prev = block->prev_free; - block_header_t * next = block->next_free; - tlsf_assert(prev && "prev_free field can not be null"); - tlsf_assert(next && "next_free field can not be null"); - next->prev_free = prev; - prev->next_free = next; - - if (control->blocks[fl][sl] == block) - { - control->blocks[fl][sl] = next; - - if (next == &control->block_null) - { - control->sl_bitmap[fl] &= ~(1 << sl); - - if (!control->sl_bitmap[fl]) - { - control->fl_bitmap &= ~(1 << fl); - } - } - } -} - -static void insert_free_block(control_t * control, block_header_t * block, int fl, int sl) -{ - block_header_t * current = control->blocks[fl][sl]; - tlsf_assert(current && "free list cannot have a null entry"); - tlsf_assert(block && "cannot insert a null entry into the free list"); - block->next_free = current; - block->prev_free = &control->block_null; - current->prev_free = block; - - tlsf_assert(block_to_ptr(block) == align_ptr(block_to_ptr(block), ALIGN_SIZE) && "block not aligned properly"); - - control->blocks[fl][sl] = block; - control->fl_bitmap |= (1 << fl); - control->sl_bitmap[fl] |= (1 << sl); -} - -static void block_remove(control_t * control, block_header_t * block) -{ - int fl, sl; - mapping_insert(block_get_size(block), &fl, &sl); - remove_free_block(control, block, fl, sl); -} - -static void block_insert(control_t * control, block_header_t * block) -{ - int fl, sl; - mapping_insert(block_get_size(block), &fl, &sl); - insert_free_block(control, block, fl, sl); -} - -static int block_can_split(block_header_t * block, size_t size) -{ - return block_get_size(block) >= sizeof(block_header_t) + size; -} - -static block_header_t * block_split(block_header_t * block, size_t size) -{ - block_header_t* remaining = offset_to_block(block_to_ptr(block), size - block_header_overhead); - const size_t remain_size = block_get_size(block) - (size + block_header_overhead); - - tlsf_assert(block_to_ptr(remaining) == align_ptr(block_to_ptr(remaining), ALIGN_SIZE) && "remaining block not aligned properly"); - - tlsf_assert(block_get_size(block) == remain_size + size + block_header_overhead); - block_set_size(remaining, remain_size); - tlsf_assert(block_get_size(remaining) >= block_size_min && "block split with invalid size"); - - block_set_size(block, size); - block_mark_as_free(remaining); - - return remaining; -} - -static block_header_t * block_absorb(block_header_t * prev, block_header_t * block) -{ - tlsf_assert(!block_is_last(prev) && "previous block can't be last!"); - prev->size += block_get_size(block) + block_header_overhead; - block_link_next(prev); - return prev; -} - -static block_header_t * block_merge_prev(control_t * control, block_header_t * block) -{ - if (block_is_prev_free(block)) - { - block_header_t* prev = block_prev(block); - tlsf_assert(prev && "prev physical block can't be null"); - tlsf_assert(block_is_free(prev) && "prev block is not free though marked as such"); - block_remove(control, prev); - block = block_absorb(prev, block); - } - - return block; -} - -static block_header_t * block_merge_next(control_t * control, block_header_t * block) -{ - block_header_t* next = block_next(block); - tlsf_assert(next && "next physical block can't be null"); - - if (block_is_free(next)) - { - tlsf_assert(!block_is_last(block) && "previous block can't be last!"); - block_remove(control, next); - block = block_absorb(block, next); - } - - return block; -} - -static void block_trim_free(control_t * control, block_header_t * block, size_t size) -{ - tlsf_assert(block_is_free(block) && "block must be free"); - if (block_can_split(block, size)) - { - block_header_t* remaining_block = block_split(block, size); - block_link_next(block); - block_set_prev_free(remaining_block); - block_insert(control, remaining_block); - } -} - -static void block_trim_used(control_t * control, block_header_t * block, size_t size) -{ - tlsf_assert(!block_is_free(block) && "block must be used"); - if (block_can_split(block, size)) - { - block_header_t* remaining_block = block_split(block, size); - block_set_prev_used(remaining_block); - - remaining_block = block_merge_next(control, remaining_block); - block_insert(control, remaining_block); - } -} - -static block_header_t * block_trim_free_leading(control_t * control, block_header_t * block, size_t size) -{ - block_header_t * remaining_block = block; - if (block_can_split(block, size)) - { - remaining_block = block_split(block, size - block_header_overhead); - block_set_prev_free(remaining_block); - - block_link_next(block); - block_insert(control, block); - } - - return remaining_block; -} - -static block_header_t * block_locate_free(control_t * control, size_t size) -{ - int fl = 0, sl = 0; - block_header_t * block = 0; - - if (size) - { - mapping_search(size, &fl, &sl); - block = search_suitable_block(control, &fl, &sl); - } - - if (block) - { - tlsf_assert(block_get_size(block) >= size); - remove_free_block(control, block, fl, sl); - } - - return block; -} - -static void * block_prepare_used(control_t * control, block_header_t * block, size_t size) -{ - void* p = 0; - if (block) - { - block_trim_free(control, block, size); - block_mark_as_used(block); - p = block_to_ptr(block); - } - return p; -} - -static void control_construct(control_t * control) -{ - int i, j; - - control->block_null.next_free = &control->block_null; - control->block_null.prev_free = &control->block_null; - - control->fl_bitmap = 0; - for (i = 0; i < FL_INDEX_COUNT; ++i) - { - control->sl_bitmap[i] = 0; - for (j = 0; j < SL_INDEX_COUNT; ++j) - { - control->blocks[i][j] = &control->block_null; - } - } -} - -static inline void * tlsf_add_pool(void * tlsf, void * mem, size_t bytes) -{ - block_header_t * block; - block_header_t * next; - const size_t pool_overhead = 2 * block_header_overhead; - const size_t pool_bytes = align_down(bytes - pool_overhead, ALIGN_SIZE); - - if (((ptrdiff_t)mem % ALIGN_SIZE) != 0) - return 0; - - if (pool_bytes < block_size_min || pool_bytes > block_size_max) - return 0; - - block = offset_to_block(mem, -(tlsfptr_t)block_header_overhead); - block_set_size(block, pool_bytes); - block_set_free(block); - block_set_prev_used(block); - block_insert(tlsf_cast(control_t*, tlsf), block); - - next = block_link_next(block); - block_set_size(next, 0); - block_set_used(next); - block_set_prev_free(next); - - return mem; -} - -static inline void tlsf_remove_pool(void * tlsf, void * pool) -{ - control_t * control = tlsf_cast(control_t *, tlsf); - block_header_t * block = offset_to_block(pool, -(int)block_header_overhead); - int fl = 0, sl = 0; - - tlsf_assert(block_is_free(block) && "block should be free"); - tlsf_assert(!block_is_free(block_next(block)) && "next block should not be free"); - tlsf_assert(block_get_size(block_next(block)) == 0 && "next block size should be zero"); - - mapping_insert(block_get_size(block), &fl, &sl); - remove_free_block(control, block, fl, sl); -} - -static inline void * tlsf_create(void * mem) -{ - if (((tlsfptr_t)mem % ALIGN_SIZE) != 0) - return 0; - - control_construct(tlsf_cast(control_t *, mem)); - return tlsf_cast(void *, mem); -} - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Warray-bounds" -static inline void * tlsf_create_with_pool(void * mem, size_t bytes) -{ - void * tlsf = tlsf_create(mem); - tlsf_add_pool(tlsf, (char *)mem + sizeof(control_t), bytes - sizeof(control_t)); - return tlsf; -} -#pragma GCC diagnostic pop - - -static inline void tlsf_destroy(void * tlsf) -{ - (void)tlsf; -} - -static inline void * tlsf_get_pool(void * tlsf) -{ - return tlsf_cast(void *, (char *)tlsf + sizeof(control_t)); -} - -static inline void * tlsf_malloc(void * tlsf, size_t size) -{ - control_t * control = tlsf_cast(control_t *, tlsf); - const size_t adjust = adjust_request_size(size, ALIGN_SIZE); - block_header_t * block = block_locate_free(control, adjust); - return block_prepare_used(control, block, adjust); -} - -static inline void * tlsf_memalign(void * tlsf, size_t align, size_t size) -{ - control_t * control = tlsf_cast(control_t *, tlsf); - const size_t adjust = adjust_request_size(size, ALIGN_SIZE); - - const size_t gap_minimum = sizeof(block_header_t); - const size_t size_with_gap = adjust_request_size(adjust + align + gap_minimum, align); - - const size_t aligned_size = (align <= ALIGN_SIZE) ? adjust : size_with_gap; - - block_header_t* block = block_locate_free(control, aligned_size); - - tlsf_assert(sizeof(block_header_t) == block_size_min + block_header_overhead); - - if (block) - { - void * ptr = block_to_ptr(block); - void * aligned = align_ptr(ptr, align); - size_t gap = tlsf_cast(size_t, tlsf_cast(tlsfptr_t, aligned) - tlsf_cast(tlsfptr_t, ptr)); - - if (gap && gap < gap_minimum) - { - const size_t gap_remain = gap_minimum - gap; - const size_t offset = tlsf_max(gap_remain, align); - const void * next_aligned = tlsf_cast(void *, tlsf_cast(tlsfptr_t, aligned) + offset); - - aligned = align_ptr(next_aligned, align); - gap = tlsf_cast(size_t, tlsf_cast(tlsfptr_t, aligned) - tlsf_cast(tlsfptr_t, ptr)); - } - - if (gap) - { - tlsf_assert(gap >= gap_minimum && "gap size too small"); - block = block_trim_free_leading(control, block, gap); - } - } - - return block_prepare_used(control, block, adjust); -} - -static inline void tlsf_free(void * tlsf, void * ptr) -{ - if (ptr) - { - control_t * control = tlsf_cast(control_t *, tlsf); - block_header_t * block = block_from_ptr(ptr); - tlsf_assert(!block_is_free(block) && "block already marked as free"); - block_mark_as_free(block); - block = block_merge_prev(control, block); - block = block_merge_next(control, block); - block_insert(control, block); - } -} - -static inline void * tlsf_realloc(void * tlsf, void * ptr, size_t size) -{ - control_t * control = tlsf_cast(control_t *, tlsf); - void * p = 0; - - if (ptr && size == 0) - { - tlsf_free(tlsf, ptr); - } - else if (!ptr) - { - p = tlsf_malloc(tlsf, size); - } - else - { - block_header_t * block = block_from_ptr(ptr); - block_header_t * next = block_next(block); - - const size_t cursize = block_get_size(block); - const size_t combined = cursize + block_get_size(next) + block_header_overhead; - const size_t adjust = adjust_request_size(size, ALIGN_SIZE); - - tlsf_assert(!block_is_free(block) && "block already marked as free"); - - if (adjust > cursize && (!block_is_free(next) || adjust > combined)) - { - p = tlsf_malloc(tlsf, size); - if (p) - { - const size_t minsize = tlsf_min(cursize, size); - memcpy(p, ptr, minsize); - tlsf_free(tlsf, ptr); - } - } - else - { - if (adjust > cursize) - { - block_merge_next(control, block); - block_mark_as_used(block); - } - - block_trim_used(control, block, adjust); - p = ptr; - } - } - - return p; -} - -void * mm_create(void * mem, size_t bytes) -{ - return tlsf_create_with_pool(mem, bytes); -} - -void mm_destroy(void * mm) -{ - tlsf_destroy(mm); -} - -void * mm_get_pool(void * mm) -{ - return tlsf_get_pool(mm); -} - -void * mm_add_pool(void * mm, void * mem, size_t bytes) -{ - return tlsf_add_pool(mm, mem, bytes); -} - -void mm_remove_pool(void * mm, void * pool) -{ - tlsf_remove_pool(mm, pool); -} - -void * mm_malloc(void * mm, size_t size) -{ - return tlsf_malloc(mm, size); -} - -void * mm_memalign(void * mm, size_t align, size_t size) -{ - return tlsf_memalign(mm, align, size); -} - -void * mm_realloc(void * mm, void * ptr, size_t size) -{ - return tlsf_realloc(mm, ptr, size); -} - -void mm_free(void * mm, void * ptr) -{ - tlsf_free(mm, ptr); -} - -void * malloc(size_t size) -{ - return tlsf_malloc(__heap_pool, size); -} - -void * memalign(size_t align, size_t size) -{ - return tlsf_memalign(__heap_pool, align, size); -} - -void * realloc(void * ptr, size_t size) -{ - return tlsf_realloc(__heap_pool, ptr, size); -} - -void * calloc(size_t nmemb, size_t size) -{ - void * ptr; - - if((ptr = malloc(nmemb * size))) - memset(ptr, 0, nmemb * size); - - return ptr; -} - -void free(void * ptr) -{ - tlsf_free(__heap_pool, ptr); -} - -void do_init_mem_pool(void) -{ -#ifndef __SANDBOX__ - extern unsigned char __heap_start; - extern unsigned char __heap_end; - __heap_pool = tlsf_create_with_pool((void *)&__heap_start, (size_t)(&__heap_end - &__heap_start)); -#else - static char __heap_buf[SZ_16M]; - __heap_pool = tlsf_create_with_pool((void *)__heap_buf, (size_t)(sizeof(__heap_buf))); -#endif -} diff --git a/hw/mcu/allwinner/f1c100s/lib/memcpy.S b/hw/mcu/allwinner/f1c100s/lib/memcpy.S deleted file mode 100644 index f7ed3130c..000000000 --- a/hw/mcu/allwinner/f1c100s/lib/memcpy.S +++ /dev/null @@ -1,404 +0,0 @@ -/* - * memcpy.S - */ - .text - - .global memcpy - .type memcpy, %function - .align 4 - -memcpy: - /* determine copy direction */ - cmp r1, r0 - bcc .Lmemcpy_backwards - - moveq r0, #0 /* quick abort for len=0 */ - moveq pc, lr - - stmdb sp!, {r0, lr} /* memcpy() returns dest addr */ - subs r2, r2, #4 - blt .Lmemcpy_fl4 /* less than 4 bytes */ - ands r12, r0, #3 - bne .Lmemcpy_fdestul /* oh unaligned destination addr */ - ands r12, r1, #3 - bne .Lmemcpy_fsrcul /* oh unaligned source addr */ - -.Lmemcpy_ft8: - /* we have aligned source and destination */ - subs r2, r2, #8 - blt .Lmemcpy_fl12 /* less than 12 bytes (4 from above) */ - subs r2, r2, #0x14 - blt .Lmemcpy_fl32 /* less than 32 bytes (12 from above) */ - stmdb sp!, {r4} /* borrow r4 */ - - /* blat 32 bytes at a time */ -.Lmemcpy_floop32: - ldmia r1!, {r3, r4, r12, lr} - stmia r0!, {r3, r4, r12, lr} - ldmia r1!, {r3, r4, r12, lr} - stmia r0!, {r3, r4, r12, lr} - subs r2, r2, #0x20 - bge .Lmemcpy_floop32 - - cmn r2, #0x10 - ldmgeia r1!, {r3, r4, r12, lr} /* blat a remaining 16 bytes */ - stmgeia r0!, {r3, r4, r12, lr} - subge r2, r2, #0x10 - ldmia sp!, {r4} /* return r4 */ - -.Lmemcpy_fl32: - adds r2, r2, #0x14 - - /* blat 12 bytes at a time */ -.Lmemcpy_floop12: - ldmgeia r1!, {r3, r12, lr} - stmgeia r0!, {r3, r12, lr} - subges r2, r2, #0x0c - bge .Lmemcpy_floop12 - -.Lmemcpy_fl12: - adds r2, r2, #8 - blt .Lmemcpy_fl4 - - subs r2, r2, #4 - ldrlt r3, [r1], #4 - strlt r3, [r0], #4 - ldmgeia r1!, {r3, r12} - stmgeia r0!, {r3, r12} - subge r2, r2, #4 - -.Lmemcpy_fl4: - /* less than 4 bytes to go */ - adds r2, r2, #4 - ldmeqia sp!, {r0, pc} /* done */ - - /* copy the crud byte at a time */ - cmp r2, #2 - ldrb r3, [r1], #1 - strb r3, [r0], #1 - ldrgeb r3, [r1], #1 - strgeb r3, [r0], #1 - ldrgtb r3, [r1], #1 - strgtb r3, [r0], #1 - ldmia sp!, {r0, pc} - - /* erg - unaligned destination */ -.Lmemcpy_fdestul: - rsb r12, r12, #4 - cmp r12, #2 - - /* align destination with byte copies */ - ldrb r3, [r1], #1 - strb r3, [r0], #1 - ldrgeb r3, [r1], #1 - strgeb r3, [r0], #1 - ldrgtb r3, [r1], #1 - strgtb r3, [r0], #1 - subs r2, r2, r12 - blt .Lmemcpy_fl4 /* less the 4 bytes */ - - ands r12, r1, #3 - beq .Lmemcpy_ft8 /* we have an aligned source */ - - /* erg - unaligned source */ - /* This is where it gets nasty ... */ -.Lmemcpy_fsrcul: - bic r1, r1, #3 - ldr lr, [r1], #4 - cmp r12, #2 - bgt .Lmemcpy_fsrcul3 - beq .Lmemcpy_fsrcul2 - cmp r2, #0x0c - blt .Lmemcpy_fsrcul1loop4 - sub r2, r2, #0x0c - stmdb sp!, {r4, r5} - -.Lmemcpy_fsrcul1loop16: - mov r3, lr, lsr #8 - ldmia r1!, {r4, r5, r12, lr} - orr r3, r3, r4, lsl #24 - mov r4, r4, lsr #8 - orr r4, r4, r5, lsl #24 - mov r5, r5, lsr #8 - orr r5, r5, r12, lsl #24 - mov r12, r12, lsr #8 - orr r12, r12, lr, lsl #24 - stmia r0!, {r3-r5, r12} - subs r2, r2, #0x10 - bge .Lmemcpy_fsrcul1loop16 - ldmia sp!, {r4, r5} - adds r2, r2, #0x0c - blt .Lmemcpy_fsrcul1l4 - -.Lmemcpy_fsrcul1loop4: - mov r12, lr, lsr #8 - ldr lr, [r1], #4 - orr r12, r12, lr, lsl #24 - str r12, [r0], #4 - subs r2, r2, #4 - bge .Lmemcpy_fsrcul1loop4 - -.Lmemcpy_fsrcul1l4: - sub r1, r1, #3 - b .Lmemcpy_fl4 - -.Lmemcpy_fsrcul2: - cmp r2, #0x0c - blt .Lmemcpy_fsrcul2loop4 - sub r2, r2, #0x0c - stmdb sp!, {r4, r5} - -.Lmemcpy_fsrcul2loop16: - mov r3, lr, lsr #16 - ldmia r1!, {r4, r5, r12, lr} - orr r3, r3, r4, lsl #16 - mov r4, r4, lsr #16 - orr r4, r4, r5, lsl #16 - mov r5, r5, lsr #16 - orr r5, r5, r12, lsl #16 - mov r12, r12, lsr #16 - orr r12, r12, lr, lsl #16 - stmia r0!, {r3-r5, r12} - subs r2, r2, #0x10 - bge .Lmemcpy_fsrcul2loop16 - ldmia sp!, {r4, r5} - adds r2, r2, #0x0c - blt .Lmemcpy_fsrcul2l4 - -.Lmemcpy_fsrcul2loop4: - mov r12, lr, lsr #16 - ldr lr, [r1], #4 - orr r12, r12, lr, lsl #16 - str r12, [r0], #4 - subs r2, r2, #4 - bge .Lmemcpy_fsrcul2loop4 - -.Lmemcpy_fsrcul2l4: - sub r1, r1, #2 - b .Lmemcpy_fl4 - -.Lmemcpy_fsrcul3: - cmp r2, #0x0c - blt .Lmemcpy_fsrcul3loop4 - sub r2, r2, #0x0c - stmdb sp!, {r4, r5} - -.Lmemcpy_fsrcul3loop16: - mov r3, lr, lsr #24 - ldmia r1!, {r4, r5, r12, lr} - orr r3, r3, r4, lsl #8 - mov r4, r4, lsr #24 - orr r4, r4, r5, lsl #8 - mov r5, r5, lsr #24 - orr r5, r5, r12, lsl #8 - mov r12, r12, lsr #24 - orr r12, r12, lr, lsl #8 - stmia r0!, {r3-r5, r12} - subs r2, r2, #0x10 - bge .Lmemcpy_fsrcul3loop16 - ldmia sp!, {r4, r5} - adds r2, r2, #0x0c - blt .Lmemcpy_fsrcul3l4 - -.Lmemcpy_fsrcul3loop4: - mov r12, lr, lsr #24 - ldr lr, [r1], #4 - orr r12, r12, lr, lsl #8 - str r12, [r0], #4 - subs r2, r2, #4 - bge .Lmemcpy_fsrcul3loop4 - -.Lmemcpy_fsrcul3l4: - sub r1, r1, #1 - b .Lmemcpy_fl4 - -.Lmemcpy_backwards: - add r1, r1, r2 - add r0, r0, r2 - subs r2, r2, #4 - blt .Lmemcpy_bl4 /* less than 4 bytes */ - ands r12, r0, #3 - bne .Lmemcpy_bdestul /* oh unaligned destination addr */ - ands r12, r1, #3 - bne .Lmemcpy_bsrcul /* oh unaligned source addr */ - -.Lmemcpy_bt8: - /* we have aligned source and destination */ - subs r2, r2, #8 - blt .Lmemcpy_bl12 /* less than 12 bytes (4 from above) */ - stmdb sp!, {r4, lr} - subs r2, r2, #0x14 /* less than 32 bytes (12 from above) */ - blt .Lmemcpy_bl32 - - /* blat 32 bytes at a time */ -.Lmemcpy_bloop32: - ldmdb r1!, {r3, r4, r12, lr} - stmdb r0!, {r3, r4, r12, lr} - ldmdb r1!, {r3, r4, r12, lr} - stmdb r0!, {r3, r4, r12, lr} - subs r2, r2, #0x20 - bge .Lmemcpy_bloop32 - -.Lmemcpy_bl32: - cmn r2, #0x10 - ldmgedb r1!, {r3, r4, r12, lr} /* blat a remaining 16 bytes */ - stmgedb r0!, {r3, r4, r12, lr} - subge r2, r2, #0x10 - adds r2, r2, #0x14 - ldmgedb r1!, {r3, r12, lr} /* blat a remaining 12 bytes */ - stmgedb r0!, {r3, r12, lr} - subge r2, r2, #0x0c - ldmia sp!, {r4, lr} - -.Lmemcpy_bl12: - adds r2, r2, #8 - blt .Lmemcpy_bl4 - subs r2, r2, #4 - ldrlt r3, [r1, #-4]! - strlt r3, [r0, #-4]! - ldmgedb r1!, {r3, r12} - stmgedb r0!, {r3, r12} - subge r2, r2, #4 - -.Lmemcpy_bl4: - /* less than 4 bytes to go */ - adds r2, r2, #4 - moveq pc, lr - - /* copy the crud byte at a time */ - cmp r2, #2 - ldrb r3, [r1, #-1]! - strb r3, [r0, #-1]! - ldrgeb r3, [r1, #-1]! - strgeb r3, [r0, #-1]! - ldrgtb r3, [r1, #-1]! - strgtb r3, [r0, #-1]! - mov pc, lr - - /* erg - unaligned destination */ -.Lmemcpy_bdestul: - cmp r12, #2 - - /* align destination with byte copies */ - ldrb r3, [r1, #-1]! - strb r3, [r0, #-1]! - ldrgeb r3, [r1, #-1]! - strgeb r3, [r0, #-1]! - ldrgtb r3, [r1, #-1]! - strgtb r3, [r0, #-1]! - subs r2, r2, r12 - blt .Lmemcpy_bl4 /* less than 4 bytes to go */ - ands r12, r1, #3 - beq .Lmemcpy_bt8 /* we have an aligned source */ - - /* erg - unaligned source */ - /* This is where it gets nasty ... */ -.Lmemcpy_bsrcul: - bic r1, r1, #3 - ldr r3, [r1, #0] - cmp r12, #2 - blt .Lmemcpy_bsrcul1 - beq .Lmemcpy_bsrcul2 - cmp r2, #0x0c - blt .Lmemcpy_bsrcul3loop4 - sub r2, r2, #0x0c - stmdb sp!, {r4, r5, lr} - -.Lmemcpy_bsrcul3loop16: - mov lr, r3, lsl #8 - ldmdb r1!, {r3-r5, r12} - orr lr, lr, r12, lsr #24 - mov r12, r12, lsl #8 - orr r12, r12, r5, lsr #24 - mov r5, r5, lsl #8 - orr r5, r5, r4, lsr #24 - mov r4, r4, lsl #8 - orr r4, r4, r3, lsr #24 - stmdb r0!, {r4, r5, r12, lr} - subs r2, r2, #0x10 - bge .Lmemcpy_bsrcul3loop16 - ldmia sp!, {r4, r5, lr} - adds r2, r2, #0x0c - blt .Lmemcpy_bsrcul3l4 - -.Lmemcpy_bsrcul3loop4: - mov r12, r3, lsl #8 - ldr r3, [r1, #-4]! - orr r12, r12, r3, lsr #24 - str r12, [r0, #-4]! - subs r2, r2, #4 - bge .Lmemcpy_bsrcul3loop4 - -.Lmemcpy_bsrcul3l4: - add r1, r1, #3 - b .Lmemcpy_bl4 - -.Lmemcpy_bsrcul2: - cmp r2, #0x0c - blt .Lmemcpy_bsrcul2loop4 - sub r2, r2, #0x0c - stmdb sp!, {r4, r5, lr} - -.Lmemcpy_bsrcul2loop16: - mov lr, r3, lsl #16 - ldmdb r1!, {r3-r5, r12} - orr lr, lr, r12, lsr #16 - mov r12, r12, lsl #16 - orr r12, r12, r5, lsr #16 - mov r5, r5, lsl #16 - orr r5, r5, r4, lsr #16 - mov r4, r4, lsl #16 - orr r4, r4, r3, lsr #16 - stmdb r0!, {r4, r5, r12, lr} - subs r2, r2, #0x10 - bge .Lmemcpy_bsrcul2loop16 - ldmia sp!, {r4, r5, lr} - adds r2, r2, #0x0c - blt .Lmemcpy_bsrcul2l4 - -.Lmemcpy_bsrcul2loop4: - mov r12, r3, lsl #16 - ldr r3, [r1, #-4]! - orr r12, r12, r3, lsr #16 - str r12, [r0, #-4]! - subs r2, r2, #4 - bge .Lmemcpy_bsrcul2loop4 - -.Lmemcpy_bsrcul2l4: - add r1, r1, #2 - b .Lmemcpy_bl4 - -.Lmemcpy_bsrcul1: - cmp r2, #0x0c - blt .Lmemcpy_bsrcul1loop4 - sub r2, r2, #0x0c - stmdb sp!, {r4, r5, lr} - -.Lmemcpy_bsrcul1loop32: - mov lr, r3, lsl #24 - ldmdb r1!, {r3-r5, r12} - orr lr, lr, r12, lsr #8 - mov r12, r12, lsl #24 - orr r12, r12, r5, lsr #8 - mov r5, r5, lsl #24 - orr r5, r5, r4, lsr #8 - mov r4, r4, lsl #24 - orr r4, r4, r3, lsr #8 - stmdb r0!, {r4, r5, r12, lr} - subs r2, r2, #0x10 - bge .Lmemcpy_bsrcul1loop32 - ldmia sp!, {r4, r5, lr} - adds r2, r2, #0x0c - blt .Lmemcpy_bsrcul1l4 - -.Lmemcpy_bsrcul1loop4: - mov r12, r3, lsl #24 - ldr r3, [r1, #-4]! - orr r12, r12, r3, lsr #8 - str r12, [r0, #-4]! - subs r2, r2, #4 - bge .Lmemcpy_bsrcul1loop4 - -.Lmemcpy_bsrcul1l4: - add r1, r1, #1 - b .Lmemcpy_bl4 diff --git a/hw/mcu/allwinner/f1c100s/lib/memset.S b/hw/mcu/allwinner/f1c100s/lib/memset.S deleted file mode 100644 index 3eea2db1e..000000000 --- a/hw/mcu/allwinner/f1c100s/lib/memset.S +++ /dev/null @@ -1,79 +0,0 @@ -/* - * memcpy.S - */ - .text - - .global memset - .type memset, %function - .align 4 - -memset: - stmfd sp!, {r0} /* remember address for return value */ - and r1, r1, #0x000000ff /* we write bytes */ - - cmp r2, #0x00000004 /* do we have less than 4 bytes */ - blt .Lmemset_lessthanfour - - /* first we will word align the address */ - ands r3, r0, #0x00000003 /* get the bottom two bits */ - beq .Lmemset_addraligned /* the address is word aligned */ - - rsb r3, r3, #0x00000004 - sub r2, r2, r3 - cmp r3, #0x00000002 - strb r1, [r0], #0x0001 /* set 1 byte */ - strgeb r1, [r0], #0x0001 /* set another byte */ - strgtb r1, [r0], #0x0001 /* and a third */ - - cmp r2, #0x00000004 - blt .Lmemset_lessthanfour - - /* now we must be word aligned */ -.Lmemset_addraligned: - orr r3, r1, r1, lsl #8 /* repeat the byte into a word */ - orr r3, r3, r3, lsl #16 - - /* we know we have at least 4 bytes ... */ - cmp r2, #0x00000020 /* if less than 32 then use words */ - blt .Lmemset_lessthan32 - - /* we have at least 32 so lets use quad words */ - stmfd sp!, {r4-r6} /* store registers */ - mov r4, r3 /* duplicate data */ - mov r5, r3 - mov r6, r3 - -.Lmemset_loop16: - stmia r0!, {r3-r6} /* store 16 bytes */ - sub r2, r2, #0x00000010 /* adjust count */ - cmp r2, #0x00000010 /* still got at least 16 bytes ? */ - bgt .Lmemset_loop16 - - ldmfd sp!, {r4-r6} /* restore registers */ - - /* do we need to set some words as well ? */ - cmp r2, #0x00000004 - blt .Lmemset_lessthanfour - - /* have either less than 16 or less than 32 depending on route taken */ -.Lmemset_lessthan32: - - /* we have at least 4 bytes so copy as words */ -.Lmemset_loop4: - str r3, [r0], #0x0004 - sub r2, r2, #0x0004 - cmp r2, #0x00000004 - bge .Lmemset_loop4 - -.Lmemset_lessthanfour: - cmp r2, #0x00000000 - ldmeqfd sp!, {r0} - moveq pc, lr /* zero length so exit */ - - cmp r2, #0x00000002 - strb r1, [r0], #0x0001 /* set 1 byte */ - strgeb r1, [r0], #0x0001 /* set another byte */ - strgtb r1, [r0], #0x0001 /* and a third */ - - ldmfd sp!, {r0} - mov pc, lr /* exit */ diff --git a/hw/mcu/allwinner/f1c100s/lib/printf.c b/hw/mcu/allwinner/f1c100s/lib/printf.c deleted file mode 100644 index 366bb9c0b..000000000 --- a/hw/mcu/allwinner/f1c100s/lib/printf.c +++ /dev/null @@ -1,757 +0,0 @@ - -/////////////////////////////////////////////////////////////////////////////// -// \author (c) Marco Paland (info@paland.com) -// 2014-2018, PALANDesign Hannover, Germany -// -// \license The MIT License (MIT) -// -// 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. -// -// \brief Tiny printf, sprintf and (v)snprintf implementation, optimized for speed on -// embedded systems with a very limited resources. These routines are thread -// safe and reentrant! -// Use this instead of the bloated standard/newlib printf cause these use -// malloc for printf (and may not be thread safe). -// -/////////////////////////////////////////////////////////////////////////////// - -#include -#include "printf.h" - - -// ntoa conversion buffer size, this must be big enough to hold -// one converted numeric number including padded zeros (dynamically created on stack) -// 32 byte is a good default -#define PRINTF_NTOA_BUFFER_SIZE 32U - -// ftoa conversion buffer size, this must be big enough to hold -// one converted float number including padded zeros (dynamically created on stack) -// 32 byte is a good default -#define PRINTF_FTOA_BUFFER_SIZE 32U - -// define this to support floating point (%f) -#define PRINTF_SUPPORT_FLOAT - -// define this to support long long types (%llu or %p) -#define PRINTF_SUPPORT_LONG_LONG - -// define this to support the ptrdiff_t type (%t) -// ptrdiff_t is normally defined in as long or long long type -#define PRINTF_SUPPORT_PTRDIFF_T - - -/////////////////////////////////////////////////////////////////////////////// - -// internal flag definitions -#define FLAGS_ZEROPAD (1U << 0U) -#define FLAGS_LEFT (1U << 1U) -#define FLAGS_PLUS (1U << 2U) -#define FLAGS_SPACE (1U << 3U) -#define FLAGS_HASH (1U << 4U) -#define FLAGS_UPPERCASE (1U << 5U) -#define FLAGS_CHAR (1U << 6U) -#define FLAGS_SHORT (1U << 7U) -#define FLAGS_LONG (1U << 8U) -#define FLAGS_LONG_LONG (1U << 9U) -#define FLAGS_PRECISION (1U << 10U) - -typedef unsigned char bool; -#ifndef false -#define false 0 -#endif -#ifndef true -#define true (!false) -#endif -extern void sys_uart_putc(char c); -static char last_ch; -void _putchar(char character) -{ - if(character == 0x0a && last_ch != 0x0d) - { - sys_uart_putc(0x0d); - } - sys_uart_putc(character); - -} - -// output function type -typedef void (*out_fct_type)(char character, void* buffer, size_t idx, size_t maxlen); - - -// wrapper (used as buffer) for output function type -typedef struct { - void (*fct)(char character, void* arg); - void* arg; -} out_fct_wrap_type; - - -// internal buffer output -static inline void _out_buffer(char character, void* buffer, size_t idx, size_t maxlen) -{ - if (idx < maxlen) { - ((char*)buffer)[idx] = character; - } -} - - -// internal null output -static inline void _out_null(char character, void* buffer, size_t idx, size_t maxlen) -{ - (void)character; (void)buffer; (void)idx; (void)maxlen; -} - - -// internal _putchar wrapper -static inline void _out_char(char character, void* buffer, size_t idx, size_t maxlen) -{ - (void)buffer; (void)idx; (void)maxlen; - if (character) { - _putchar(character); - } -} - - -// internal output function wrapper -static inline void _out_fct(char character, void* buffer, size_t idx, size_t maxlen) -{ - (void)idx; (void)maxlen; - // buffer is the output fct pointer - ((out_fct_wrap_type*)buffer)->fct(character, ((out_fct_wrap_type*)buffer)->arg); -} - - -// internal strlen -// \return The length of the string (excluding the terminating 0) -static inline unsigned int _strlen(const char* str) -{ - const char* s; - for (s = str; *s; ++s); - return (unsigned int)(s - str); -} - - -// internal test if char is a digit (0-9) -// \return true if char is a digit -static inline bool _is_digit(char ch) -{ - return (ch >= '0') && (ch <= '9'); -} - - -// internal ASCII string to unsigned int conversion -static unsigned int _atoi(const char** str) -{ - unsigned int i = 0U; - while (_is_digit(**str)) { - i = i * 10U + (unsigned int)(*((*str)++) - '0'); - } - return i; -} - - -// internal itoa format -static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t maxlen, char* buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags) -{ - const size_t start_idx = idx; - - // pad leading zeros - while (!(flags & FLAGS_LEFT) && (len < prec) && (len < PRINTF_NTOA_BUFFER_SIZE)) { - buf[len++] = '0'; - } - while (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_NTOA_BUFFER_SIZE)) { - buf[len++] = '0'; - } - - // handle hash - if (flags & FLAGS_HASH) { - if (!(flags & FLAGS_PRECISION) && len && ((len == prec) || (len == width))) { - len--; - if (len && (base == 16U)) { - len--; - } - } - if ((base == 16U) && !(flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) { - buf[len++] = 'x'; - } - else if ((base == 16U) && (flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) { - buf[len++] = 'X'; - } - else if ((base == 2U) && (len < PRINTF_NTOA_BUFFER_SIZE)) { - buf[len++] = 'b'; - } - if (len < PRINTF_NTOA_BUFFER_SIZE) { - buf[len++] = '0'; - } - } - - // handle sign - if (len && (len == width) && (negative || (flags & FLAGS_PLUS) || (flags & FLAGS_SPACE))) { - len--; - } - if (len < PRINTF_NTOA_BUFFER_SIZE) { - if (negative) { - buf[len++] = '-'; - } - else if (flags & FLAGS_PLUS) { - buf[len++] = '+'; // ignore the space if the '+' exists - } - else if (flags & FLAGS_SPACE) { - buf[len++] = ' '; - } - } - - // pad spaces up to given width - if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) { - for (size_t i = len; i < width; i++) { - out(' ', buffer, idx++, maxlen); - } - } - - // reverse string - for (size_t i = 0U; i < len; i++) { - out(buf[len - i - 1U], buffer, idx++, maxlen); - } - - // append pad spaces up to given width - if (flags & FLAGS_LEFT) { - while (idx - start_idx < width) { - out(' ', buffer, idx++, maxlen); - } - } - - return idx; -} - - -// internal itoa for 'long' type -static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags) -{ - char buf[PRINTF_NTOA_BUFFER_SIZE]; - size_t len = 0U; - - // no hash for 0 values - if (!value) { - flags &= ~FLAGS_HASH; - } - - // write if precision != 0 and value is != 0 - if (!(flags & FLAGS_PRECISION) || value) { - do { - const char digit = (char)(value % base); - buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; - value /= base; - } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); - } - - return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); -} - - -// internal itoa for 'long long' type -#if defined(PRINTF_SUPPORT_LONG_LONG) -static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long long value, bool negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags) -{ - char buf[PRINTF_NTOA_BUFFER_SIZE]; - size_t len = 0U; - - // no hash for 0 values - if (!value) { - flags &= ~FLAGS_HASH; - } - - // write if precision != 0 and value is != 0 - if (!(flags & FLAGS_PRECISION) || value) { - do { - const char digit = (char)(value % base); - buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; - value /= base; - } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); - } - - return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); -} -#endif // PRINTF_SUPPORT_LONG_LONG - - -#if defined(PRINTF_SUPPORT_FLOAT) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wfloat-equal" - -static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) -{ - const size_t start_idx = idx; - - char buf[PRINTF_FTOA_BUFFER_SIZE]; - size_t len = 0U; - double diff = 0.0; - - // if input is larger than thres_max, revert to exponential - const double thres_max = (double)0x7FFFFFFF; - - // powers of 10 - static const double pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; - - // test for negative - bool negative = false; - if (value < 0) { - negative = true; - value = 0 - value; - } - - // set default precision to 6, if not set explicitly - if (!(flags & FLAGS_PRECISION)) { - prec = 6U; - } - // limit precision to 9, cause a prec >= 10 can lead to overflow errors - while ((len < PRINTF_FTOA_BUFFER_SIZE) && (prec > 9U)) { - buf[len++] = '0'; - prec--; - } - - int whole = (int)value; - double tmp = (value - whole) * pow10[prec]; - unsigned long frac = (unsigned long)tmp; - diff = tmp - frac; - - if (diff > 0.5l) { - ++frac; - // handle rollover, e.g. case 0.99 with prec 1 is 1.0 - if (frac >= pow10[prec]) { - frac = 0; - ++whole; - } - } - else if ((diff == 0.5l) && ((frac == 0U) || (frac & 1U))) { - // if halfway, round up if odd, OR if last digit is 0 - ++frac; - } - - // TBD: for very large numbers switch back to native sprintf for exponentials. Anyone want to write code to replace this? - // Normal printf behavior is to print EVERY whole number digit which can be 100s of characters overflowing your buffers == bad - if (value > thres_max) { - return 0U; - } - - if (prec == 0U) { - diff = value - (double)whole; - if (diff > 0.5l) { - // greater than 0.5, round up, e.g. 1.6 -> 2 - ++whole; - } - else if ((diff == 0.5l) && (whole & 1)) { - // exactly 0.5 and ODD, then round up - // 1.5 -> 2, but 2.5 -> 2 - ++whole; - } - } - else { - unsigned int count = prec; - // now do fractional part, as an unsigned number - while (len < PRINTF_FTOA_BUFFER_SIZE) { - --count; - buf[len++] = (char)(48U + (frac % 10U)); - if (!(frac /= 10U)) { - break; - } - } - // add extra 0s - while ((len < PRINTF_FTOA_BUFFER_SIZE) && (count-- > 0U)) { - buf[len++] = '0'; - } - if (len < PRINTF_FTOA_BUFFER_SIZE) { - // add decimal - buf[len++] = '.'; - } - } - - // do whole part, number is reversed - while (len < PRINTF_FTOA_BUFFER_SIZE) { - buf[len++] = (char)(48 + (whole % 10)); - if (!(whole /= 10)) { - break; - } - } - - // pad leading zeros - while (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_FTOA_BUFFER_SIZE)) { - buf[len++] = '0'; - } - - // handle sign - if ((len == width) && (negative || (flags & FLAGS_PLUS) || (flags & FLAGS_SPACE))) { - len--; - } - if (len < PRINTF_FTOA_BUFFER_SIZE) { - if (negative) { - buf[len++] = '-'; - } - else if (flags & FLAGS_PLUS) { - buf[len++] = '+'; // ignore the space if the '+' exists - } - else if (flags & FLAGS_SPACE) { - buf[len++] = ' '; - } - } - - // pad spaces up to given width - if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) { - for (size_t i = len; i < width; i++) { - out(' ', buffer, idx++, maxlen); - } - } - - // reverse string - for (size_t i = 0U; i < len; i++) { - out(buf[len - i - 1U], buffer, idx++, maxlen); - } - - // append pad spaces up to given width - if (flags & FLAGS_LEFT) { - while (idx - start_idx < width) { - out(' ', buffer, idx++, maxlen); - } - } - - return idx; -} -#pragma GCC diagnostic pop -#endif // PRINTF_SUPPORT_FLOAT - - -// internal vsnprintf -static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const char* format, va_list va) -{ - unsigned int flags, width, precision, n; - size_t idx = 0U; - - if (!buffer) { - // use null output function - out = _out_null; - } - - while (*format) - { - // format specifier? %[flags][width][.precision][length] - if (*format != '%') { - // no - out(*format, buffer, idx++, maxlen); - format++; - continue; - } - else { - // yes, evaluate it - format++; - } - - // evaluate flags - flags = 0U; - do { - switch (*format) { - case '0': flags |= FLAGS_ZEROPAD; format++; n = 1U; break; - case '-': flags |= FLAGS_LEFT; format++; n = 1U; break; - case '+': flags |= FLAGS_PLUS; format++; n = 1U; break; - case ' ': flags |= FLAGS_SPACE; format++; n = 1U; break; - case '#': flags |= FLAGS_HASH; format++; n = 1U; break; - default : n = 0U; break; - } - } while (n); - - // evaluate width field - width = 0U; - if (_is_digit(*format)) { - width = _atoi(&format); - } - else if (*format == '*') { - const int w = va_arg(va, int); - if (w < 0) { - flags |= FLAGS_LEFT; // reverse padding - width = (unsigned int)-w; - } - else { - width = (unsigned int)w; - } - format++; - } - - // evaluate precision field - precision = 0U; - if (*format == '.') { - flags |= FLAGS_PRECISION; - format++; - if (_is_digit(*format)) { - precision = _atoi(&format); - } - else if (*format == '*') { - const int prec = (int)va_arg(va, int); - precision = prec > 0 ? (unsigned int)prec : 0U; - format++; - } - } - - // evaluate length field - switch (*format) { - case 'l' : - flags |= FLAGS_LONG; - format++; - if (*format == 'l') { - flags |= FLAGS_LONG_LONG; - format++; - } - break; - case 'h' : - flags |= FLAGS_SHORT; - format++; - if (*format == 'h') { - flags |= FLAGS_CHAR; - format++; - } - break; -#if defined(PRINTF_SUPPORT_PTRDIFF_T) - case 't' : - flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); - format++; - break; -#endif - case 'j' : - flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); - format++; - break; - case 'z' : - flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); - format++; - break; - default : - break; - } - - // evaluate specifier - switch (*format) { - case 'd' : - case 'i' : - case 'u' : - case 'x' : - case 'X' : - case 'o' : - case 'b' : { - // set the base - unsigned int base; - if (*format == 'x' || *format == 'X') { - base = 16U; - } - else if (*format == 'o') { - base = 8U; - } - else if (*format == 'b') { - base = 2U; - } - else { - base = 10U; - flags &= ~FLAGS_HASH; // no hash for dec format - } - // uppercase - if (*format == 'X') { - flags |= FLAGS_UPPERCASE; - } - - // no plus or space flag for u, x, X, o, b - if ((*format != 'i') && (*format != 'd')) { - flags &= ~(FLAGS_PLUS | FLAGS_SPACE); - } - - // ignore '0' flag when precision is given - if (flags & FLAGS_PRECISION) { - flags &= ~FLAGS_ZEROPAD; - } - - // convert the integer - if ((*format == 'i') || (*format == 'd')) { - // signed - if (flags & FLAGS_LONG_LONG) { -#if defined(PRINTF_SUPPORT_LONG_LONG) - const long long value = va_arg(va, long long); - idx = _ntoa_long_long(out, buffer, idx, maxlen, (unsigned long long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); -#endif - } - else if (flags & FLAGS_LONG) { - const long value = va_arg(va, long); - idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); - } - else { - const int value = (flags & FLAGS_CHAR) ? (char)va_arg(va, int) : (flags & FLAGS_SHORT) ? (short int)va_arg(va, int) : va_arg(va, int); - idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); - } - } - else { - // unsigned - if (flags & FLAGS_LONG_LONG) { -#if defined(PRINTF_SUPPORT_LONG_LONG) - idx = _ntoa_long_long(out, buffer, idx, maxlen, va_arg(va, unsigned long long), false, base, precision, width, flags); -#endif - } - else if (flags & FLAGS_LONG) { - idx = _ntoa_long(out, buffer, idx, maxlen, va_arg(va, unsigned long), false, base, precision, width, flags); - } - else { - const unsigned int value = (flags & FLAGS_CHAR) ? (unsigned char)va_arg(va, unsigned int) : (flags & FLAGS_SHORT) ? (unsigned short int)va_arg(va, unsigned int) : va_arg(va, unsigned int); - idx = _ntoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags); - } - } - format++; - break; - } -#if defined(PRINTF_SUPPORT_FLOAT) - case 'f' : - case 'F' : - idx = _ftoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); - format++; - break; -#endif // PRINTF_SUPPORT_FLOAT - case 'c' : { - unsigned int l = 1U; - // pre padding - if (!(flags & FLAGS_LEFT)) { - while (l++ < width) { - out(' ', buffer, idx++, maxlen); - } - } - // char output - out((char)va_arg(va, int), buffer, idx++, maxlen); - // post padding - if (flags & FLAGS_LEFT) { - while (l++ < width) { - out(' ', buffer, idx++, maxlen); - } - } - format++; - break; - } - - case 's' : { - char* p = va_arg(va, char*); - unsigned int l = _strlen(p); - // pre padding - if (flags & FLAGS_PRECISION) { - l = (l < precision ? l : precision); - } - if (!(flags & FLAGS_LEFT)) { - while (l++ < width) { - out(' ', buffer, idx++, maxlen); - } - } - // string output - while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision--)) { - out(*(p++), buffer, idx++, maxlen); - } - // post padding - if (flags & FLAGS_LEFT) { - while (l++ < width) { - out(' ', buffer, idx++, maxlen); - } - } - format++; - break; - } - - case 'p' : { - width = sizeof(void*) * 2U; - flags |= FLAGS_ZEROPAD | FLAGS_UPPERCASE; -#if defined(PRINTF_SUPPORT_LONG_LONG) - const bool is_ll = sizeof(uintptr_t) == sizeof(long long); - if (is_ll) { - idx = _ntoa_long_long(out, buffer, idx, maxlen, (uintptr_t)va_arg(va, void*), false, 16U, precision, width, flags); - } - else { -#endif - idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)((uintptr_t)va_arg(va, void*)), false, 16U, precision, width, flags); -#if defined(PRINTF_SUPPORT_LONG_LONG) - } -#endif - format++; - break; - } - - case '%' : - out('%', buffer, idx++, maxlen); - format++; - break; - - default : - out(*format, buffer, idx++, maxlen); - format++; - break; - } - } - - // termination - out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen); - - // return written chars without terminating \0 - return (int)idx; -} - - -/////////////////////////////////////////////////////////////////////////////// - - -int printf(const char* format, ...) -{ - va_list va; - va_start(va, format); - char buffer[1]; - const int ret = _vsnprintf(_out_char, buffer, (size_t)-1, format, va); - va_end(va); - return ret; -} - - -int sprintf(char* buffer, const char* format, ...) -{ - va_list va; - va_start(va, format); - const int ret = _vsnprintf(_out_buffer, buffer, (size_t)-1, format, va); - va_end(va); - return ret; -} - - -int snprintf(char* buffer, size_t count, const char* format, ...) -{ - va_list va; - va_start(va, format); - const int ret = _vsnprintf(_out_buffer, buffer, count, format, va); - va_end(va); - return ret; -} - - -int vsnprintf(char* buffer, size_t count, const char* format, va_list va) -{ - return _vsnprintf(_out_buffer, buffer, count, format, va); -} - - -int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...) -{ - va_list va; - va_start(va, format); - out_fct_wrap_type out_fct_wrap = { out, arg }; - const int ret = _vsnprintf(_out_fct, (char*)&out_fct_wrap, (size_t)-1, format, va); - va_end(va); - return ret; -} diff --git a/hw/mcu/allwinner/f1c100s/machine/exception.c b/hw/mcu/allwinner/f1c100s/machine/exception.c deleted file mode 100644 index ffc61bf47..000000000 --- a/hw/mcu/allwinner/f1c100s/machine/exception.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * exception.c - * - * Copyright(c) 2007-2018 Jianjun Jiang <8192542@qq.com> - * Official site: http://xboot.org - * Mobile phone: +86-18665388956 - * QQ: 8192542 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#include -#include -#include - -static void show_regs(struct arm_regs_t * regs) -{ - int i; - - printf("pc : [<%08lx>] lr : [<%08lx>] cpsr: %08lx\r\n", regs->pc, regs->lr, regs->cpsr); - printf("sp : %08lx\r\n", regs->sp); - for(i = 12; i >= 0; i--) - { - printf("r%-2d: %08lx ", i, regs->r[i]); - if(i % 2 == 0) - printf("\r\n"); - } - printf("\r\n"); -} - -void arm32_do_undefined_instruction(struct arm_regs_t * regs) -{ - //gdbserver_handle_exception(regs); -} - -void arm32_do_software_interrupt(struct arm_regs_t * regs) -{ - show_regs(regs); - regs->pc += 4; -} - -void arm32_do_prefetch_abort(struct arm_regs_t * regs) -{ - show_regs(regs); - regs->pc += 4; -} - -void arm32_do_data_abort(struct arm_regs_t * regs) -{ - show_regs(regs); - regs->pc += 4; -} - -_Noreturn void __fatal_error(const char *msg) { - printf("%s\n", msg); - while (1); -} - -#ifndef NDEBUG -_Noreturn void __assert_func(const char *file, int line, const char *func, const char *expr) { - //printf("Assertion '%s' failed, at file %s:%d\n", expr, file, line); - __fatal_error("Assertion failed"); -} -#endif \ No newline at end of file diff --git a/hw/mcu/allwinner/f1c100s/machine/f1c100s-intc.c b/hw/mcu/allwinner/f1c100s/machine/f1c100s-intc.c deleted file mode 100644 index 2993f0b60..000000000 --- a/hw/mcu/allwinner/f1c100s/machine/f1c100s-intc.c +++ /dev/null @@ -1,173 +0,0 @@ -// Originally designed by Hong Xuyao - -#include -#include -#include -#include - -#define __irq __attribute__ ((interrupt ("IRQ"))) - -#ifndef __IO -#define __IO volatile -#endif - -typedef struct { - __IO uint32_t INTC_VECTOR_REG; // 0x00 - __IO uint32_t INTC_BASE_ADDR_REG; // 0x04 - uint32_t resv1[1]; // 0x08 - __IO uint32_t NMI_INT_CTRL_REG; // 0x0c - __IO uint32_t INTC_PEND_REG[2]; // 0x10 - uint32_t resv2[2]; // 0x18 - __IO uint32_t INTC_EN_REG[2]; // 0x20 - uint32_t resv3[2]; // 0x28 - __IO uint32_t INTC_MASK_REG[2]; // 0x30 - uint32_t resv4[2]; // 0x38 - __IO uint32_t INTC_RESP_REG[2]; // 0x40 - uint32_t resv5[2]; // 0x48 - __IO uint32_t INTC_FF_REG[2]; // 0x50 - uint32_t resv6[2]; // 0x58 - __IO uint32_t INTC_PRIO_REG[4]; // 0x60 -} INTC_TypeDef; - -#ifndef COUNTOF -#define COUNTOF(ar) (sizeof(ar)/sizeof(ar[0])) -#endif - -#define INTC ((INTC_TypeDef*)0x01C20400) - -static IRQHandleTypeDef irq_table[64] __attribute__((used, aligned(32))); - -void arm32_do_irq(struct arm_regs_t * regs) -{ - uint8_t nIRQ = f1c100s_intc_get_nirq(); - - // ForceIRQ flag must be cleared by ISR - // Otherwise ISR will be entered repeatedly - INTC->INTC_FF_REG[nIRQ / 32] &= ~(1 << nIRQ); - // Call the drivers ISR - f1c100s_intc_dispatch(nIRQ); - // Clear pending at the end of ISR - f1c100s_intc_clear_pend(nIRQ); -} - -void arm32_do_fiq(struct arm_regs_t * regs) -{ - // Call the drivers ISR - f1c100s_intc_dispatch(0); - // Clear pending at the end of ISR. - f1c100s_intc_clear_pend(0); -} - -/* -* Read active IRQ number -* @return: none -*/ -uint8_t f1c100s_intc_get_nirq(void) -{ - return ((INTC->INTC_VECTOR_REG >> 2) & 0x3F); -} - -/* -* Execute ISR corresponding to IRQ number -* @nIRQ: IRQ number -* @return: none -*/ -void f1c100s_intc_dispatch(uint8_t nIRQ) -{ - IRQHandleTypeDef handle = irq_table[nIRQ]; - if (handle) - handle(); -} - -/* -* Set handler function for specified IRQ -* @nIRQ: IRQ number -* @handle: Handle function -* @return: none -*/ -void f1c100s_intc_set_isr(uint8_t nIRQ, IRQHandleTypeDef handle) -{ - if (nIRQ < COUNTOF(irq_table)) { - irq_table[nIRQ] = handle; - } -} - -/* -* Enable IRQ -* @nIRQ: IRQ number -* @return: none -*/ -void f1c100s_intc_enable_irq(uint8_t nIRQ) -{ - INTC->INTC_EN_REG[nIRQ / 32] |= (1 << (nIRQ % 32)); -} - -/* -* Disable IRQ -* @nIRQ: IRQ number -* @return: none -*/ -void f1c100s_intc_disable_irq(uint8_t nIRQ) -{ - INTC->INTC_EN_REG[nIRQ / 32] &= ~(1 << (nIRQ % 32)); -} - -/* -* Mask IRQ -* @nIRQ: IRQ number -* @return: none -*/ -void f1c100s_intc_mask_irq(uint8_t nIRQ) -{ - INTC->INTC_MASK_REG[nIRQ / 32] |= (1 << (nIRQ % 32)); -} - -/* -* Unmask IRQ -* @nIRQ: IRQ number -* @return: none -*/ -void f1c100s_intc_unmask_irq(uint8_t nIRQ) -{ - INTC->INTC_MASK_REG[nIRQ / 32] &= ~(1 << (nIRQ % 32)); -} - -/* -* Immediately trigger IRQ -* @nIRQ: IRQ number -* @return: none -*/ -void f1c100s_intc_force_irq(uint8_t nIRQ) -{ - // This bit is to be cleared in IRQ handler - INTC->INTC_FF_REG[nIRQ / 32] = (1 << (nIRQ % 32)); -} - -/* -* Clear pending flag -* @nIRQ: IRQ number -* @return: none -*/ -void f1c100s_intc_clear_pend(uint8_t nIRQ) -{ - INTC->INTC_PEND_REG[nIRQ / 32] = (1 << (nIRQ % 32)); -} - - -/* -* Initialize IRQ module -* @return: none -*/ -void f1c100s_intc_init(void) -{ - INTC->INTC_EN_REG[0] = INTC->INTC_EN_REG[1] = 0; - INTC->INTC_MASK_REG[0] = INTC->INTC_MASK_REG[1] = 0; - INTC->INTC_FF_REG[0] = INTC->INTC_FF_REG[1] = 0; - INTC->INTC_RESP_REG[0] = INTC->INTC_RESP_REG[1] = 0; - INTC->INTC_PEND_REG[0] = INTC->INTC_PEND_REG[1] = ~0UL; - INTC->INTC_BASE_ADDR_REG = 0; - INTC->NMI_INT_CTRL_REG = 0; - for (unsigned int i = 0; i < COUNTOF(irq_table); i++) { - irq_table[i] = 0; - } -} diff --git a/hw/mcu/allwinner/f1c100s/machine/start.S b/hw/mcu/allwinner/f1c100s/machine/start.S deleted file mode 100644 index befb22148..000000000 --- a/hw/mcu/allwinner/f1c100s/machine/start.S +++ /dev/null @@ -1,314 +0,0 @@ -/* - * start.S - * - * Copyright(c) 2007-2018 Jianjun Jiang <8192542@qq.com> - * Official site: http://xboot.org - * Mobile phone: +86-18665388956 - * QQ: 8192542 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -/* - * Exception vector table - */ -.text - .arm - - .global _start -_start: - /* Boot head information for BROM */ - .long 0xea000016 - .byte 'e', 'G', 'O', 'N', '.', 'B', 'T', '0' - .long 0, __bootloader_size - .byte 'S', 'P', 'L', 2 - .long 0, 0 - .long 0, 0, 0, 0, 0, 0, 0, 0 - .long 0, 0, 0, 0, 0, 0, 0, 0 /* 0x40 - boot params, 0x58 - fel boot type, 0x5c - dram size */ - -_vector: - b reset - ldr pc, _undefined_instruction - ldr pc, _software_interrupt - ldr pc, _prefetch_abort - ldr pc, _data_abort - ldr pc, _not_used - ldr pc, _irq - ldr pc, _fiq - -_undefined_instruction: - .word undefined_instruction -_software_interrupt: - .word software_interrupt -_prefetch_abort: - .word prefetch_abort -_data_abort: - .word data_abort -_not_used: - .word not_used -_irq: - .word irq -_fiq: - .word fiq - -/* - * The actual reset code - */ -reset: - /* Save boot params to 0x00000040 */ - ldr r0, =0x00000040 - str sp, [r0, #0] - str lr, [r0, #4] - mrs lr, cpsr - str lr, [r0, #8] - mrc p15, 0, lr, c1, c0, 0 - str lr, [r0, #12] - mrc p15, 0, lr, c1, c0, 0 - str lr, [r0, #16] - - /* Check boot type just for fel */ - mov r0, #0x0 - ldr r1, [r0, #8] - ldr r2, =0x4c45462e - cmp r1, r2 - bne 1f - ldr r1, =0x1 - str r1, [r0, #0x58] -1: nop - - /* Enter svc mode and mask interrupts */ - mrs r0, cpsr - bic r0, r0, #0x1f - orr r0, r0, #0xd3 - msr cpsr, r0 - - /* Set vector to the low address */ - mrc p15, 0, r0, c1, c0, 0 - bic r0, #(1<<13) - mcr p15, 0, r0, c1, c0, 0 - - /* Copy vector to the correct address */ - adr r0, _vector - mrc p15, 0, r2, c1, c0, 0 - ands r2, r2, #(1 << 13) - ldreq r1, =0x00000000 - ldrne r1, =0xffff0000 - ldmia r0!, {r2-r8, r10} - stmia r1!, {r2-r8, r10} - ldmia r0!, {r2-r8, r10} - stmia r1!, {r2-r8, r10} - - /* Initial system clock, ddr and uart */ - bl sys_clock_init - bl sys_uart_init - - /* Check if we are already running from dram */ - adr r0, _start - ldr r1, =_start - cmp r0, r1 - beq _init_mmu - - /* Init dram if not running from dram */ - bl sys_dram_init - - /* Copy bootloader to faster dram (sram is slower) */ - ldr r0, =0x81f80000 - adr r1, _start - mov r2, #0x4000 - bl memcpy - ldr r0, =_copy_self - ldr r1, =_start - sub r0, r0, r1 - ldr r1, =0x81f80000 - add r0, r0, r1 - mov pc, r0 -_init_mmu: - bl sys_mmu_init - b 1f -_copy_self: - /* Copyself to link address */ - bl sys_copyself - -1: nop - /* Initialize stacks */ - mrs r0, cpsr - bic r0, r0, #0x1f - orr r1, r0, #0x1b - msr cpsr_cxsf, r1 - ldr sp, _stack_und_end - - bic r0, r0, #0x1f - orr r1, r0, #0x17 - msr cpsr_cxsf, r1 - ldr sp, _stack_abt_end - - bic r0, r0, #0x1f - orr r1, r0, #0x12 - msr cpsr_cxsf, r1 - ldr sp, _stack_irq_end - - bic r0, r0, #0x1f - orr r1, r0, #0x11 - msr cpsr_cxsf, r1 - ldr sp, _stack_fiq_end - - bic r0, r0, #0x1f - orr r1, r0, #0x13 - msr cpsr_cxsf, r1 - ldr sp, _stack_srv_end - - /* Copy data section */ - ldr r0, _data_start - ldr r1, _data_shadow_start - ldr r2, _data_shadow_end - sub r2, r2, r1 - bl memcpy - - /* Clear bss section */ - ldr r0, _bss_start - ldr r2, _bss_end - sub r2, r2, r0 - mov r1, #0 - bl memset - - /* Call _main */ - ldr r1, =_main - mov pc, r1 -_main: - bl main - b _main - - .global return_to_fel -return_to_fel: - mov r0, #0x4 - mov r1, #'e' - strb r1, [r0, #0] - mov r1, #'G' - strb r1, [r0, #1] - mov r1, #'O' - strb r1, [r0, #2] - mov r1, #'N' - strb r1, [r0, #3] - mov r1, #'.' - strb r1, [r0, #4] - mov r1, #'F' - strb r1, [r0, #5] - mov r1, #'E' - strb r1, [r0, #6] - mov r1, #'L' - strb r1, [r0, #7] - ldr r0, =0x00000040 - ldr sp, [r0, #0] - ldr lr, [r0, #4] - ldr r1, [r0, #16] - mcr p15, 0, r1, c1, c0, 0 - ldr r1, [r0, #12] - mcr p15, 0, r1, c1, c0, 0 - ldr r1, [r0, #8] - msr cpsr, r1 - bx lr - -/* - * Exception handlers - */ - .align 5 -undefined_instruction: - b . - - .align 5 -software_interrupt: - b . - - .align 5 -prefetch_abort: - b . - - .align 5 -data_abort: - b . - - .align 5 -not_used: - b . - - .align 5 -irq: - ldr sp, _stack_irq_end - sub sp, sp, #72 - stmia sp, {r0 - r12} - add r8, sp, #60 - stmdb r8, {sp, lr}^ - str lr, [r8, #0] - mrs r6, spsr - str r6, [r8, #4] - str r0, [r8, #8] - mov r0, sp - bl arm32_do_irq - ldmia sp, {r0 - lr}^ - mov r0, r0 - ldr lr, [sp, #60] - add sp, sp, #72 - subs pc, lr, #4 - - .align 5 -fiq: - ldr sp, _stack_irq_end - sub sp, sp, #72 - stmia sp, {r0 - r12} - add r8, sp, #60 - stmdb r8, {sp, lr}^ - str lr, [r8, #0] - mrs r6, spsr - str r6, [r8, #4] - str r0, [r8, #8] - mov r0, sp - bl arm32_do_fiq - ldmia sp, {r0 - lr}^ - mov r0, r0 - ldr lr, [sp, #60] - add sp, sp, #72 - subs pc, lr, #4 - -/* - * The location of section - */ - .align 4 -_image_start: - .long __image_start -_image_end: - .long __image_end -_data_shadow_start: - .long __data_shadow_start -_data_shadow_end: - .long __data_shadow_end -_data_start: - .long __data_start -_data_end: - .long __data_end -_bss_start: - .long __bss_start -_bss_end: - .long __bss_end -_stack_und_end: - .long __stack_und_end -_stack_abt_end: - .long __stack_abt_end -_stack_irq_end: - .long __stack_irq_end -_stack_fiq_end: - .long __stack_fiq_end -_stack_srv_end: - .long __stack_srv_end diff --git a/hw/mcu/allwinner/f1c100s/machine/sys-clock.c b/hw/mcu/allwinner/f1c100s/machine/sys-clock.c deleted file mode 100644 index d151dd0c1..000000000 --- a/hw/mcu/allwinner/f1c100s/machine/sys-clock.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * sys-clock.c - * - * Copyright(c) 2007-2018 Jianjun Jiang <8192542@qq.com> - * Official site: http://xboot.org - * Mobile phone: +86-18665388956 - * QQ: 8192542 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -//#include -#include -#include -#include - -static inline void sdelay(int loops) -{ - __asm__ __volatile__ ("1:\n" "subs %0, %1, #1\n" - "bne 1b":"=r" (loops):"0"(loops)); -} - -static void wait_pll_stable(uint32_t base) -{ - uint32_t rval = 0; - uint32_t time = 0xfff; - - do { - rval = read32(base); - time--; - } while(time && !(rval & (1 << 28))); -} - -static void clock_set_pll_cpu(uint32_t clk) -{ - uint32_t n, k, m, p; - uint32_t rval = 0; - uint32_t div = 0; - - if(clk > 720000000) - clk = 720000000; - - if((clk % 24000000) == 0) - { - div = clk / 24000000; - n = div - 1; - k = 0; - m = 0; - p = 0; - } - else if((clk % 12000000) == 0) - { - m = 1; - div = clk / 12000000; - if((div % 3) == 0) - k = 2; - else if((div % 4) == 0) - k = 3; - else - k = 1; - n = (div / (k + 1)) - 1; - p = 0; - } - else - { - div = clk / 24000000; - n = div - 1; - k = 0; - m = 0; - p = 0; - } - - rval = read32(F1C100S_CCU_BASE + CCU_PLL_CPU_CTRL); - rval &= ~((0x3 << 16) | (0x1f << 8) | (0x3 << 4) | (0x3 << 0)); - rval |= (1U << 31) | (p << 16) | (n << 8) | (k << 4) | m; - write32(F1C100S_CCU_BASE + CCU_PLL_CPU_CTRL, rval); - wait_pll_stable(F1C100S_CCU_BASE + CCU_PLL_CPU_CTRL); -} - -void sys_clock_init(void) -{ - uint32_t val; - - write32(F1C100S_CCU_BASE + CCU_PLL_STABLE_TIME0, 0x1ff); - write32(F1C100S_CCU_BASE + CCU_PLL_STABLE_TIME1, 0x1ff); - - val = read32(F1C100S_CCU_BASE + CCU_CPU_CFG); - val &= ~(0x3 << 16); - val |= (0x1 << 16); - write32(F1C100S_CCU_BASE + CCU_CPU_CFG, val); - sdelay(100); - - write32(F1C100S_CCU_BASE + CCU_PLL_VIDEO_CTRL, 0x81004107); - sdelay(100); - write32(F1C100S_CCU_BASE + CCU_PLL_PERIPH_CTRL, 0x80041800); - sdelay(100); - write32(F1C100S_CCU_BASE + CCU_AHB_APB_CFG, 0x00003180); - sdelay(100); - - val = read32(F1C100S_CCU_BASE + CCU_DRAM_CLK_GATE); - val |= (0x1 << 26) | (0x1 << 24); - write32(F1C100S_CCU_BASE + CCU_DRAM_CLK_GATE, val); - sdelay(100); - - clock_set_pll_cpu(408000000); - val = read32(F1C100S_CCU_BASE + CCU_CPU_CFG); - val &= ~(0x3 << 16); - val |= (0x2 << 16); - write32(F1C100S_CCU_BASE + CCU_CPU_CFG, val); - sdelay(100); -} diff --git a/hw/mcu/allwinner/f1c100s/machine/sys-copyself.c b/hw/mcu/allwinner/f1c100s/machine/sys-copyself.c deleted file mode 100644 index 4116e1265..000000000 --- a/hw/mcu/allwinner/f1c100s/machine/sys-copyself.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * sys-copyself.c - * - * Copyright(c) 2007-2018 Jianjun Jiang <8192542@qq.com> - * Official site: http://xboot.org - * Mobile phone: +86-18665388956 - * QQ: 8192542 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#include - -extern unsigned char __image_start; -extern unsigned char __image_end; -extern void return_to_fel(void); -extern void sys_mmu_init(void); -extern void sys_uart_putc(char c); -extern void sys_spi_flash_init(void); -extern void sys_spi_flash_exit(void); -extern void sys_spi_flash_read(int addr, void * buf, int count); - -enum { - BOOT_DEVICE_FEL = 0, - BOOT_DEVICE_SPI = 1, - BOOT_DEVICE_MMC = 2, -}; - -static int get_boot_device(void) -{ - uint32_t * t = (void *)0x00000058; - - if(t[0] == 0x1) - return BOOT_DEVICE_FEL; - return BOOT_DEVICE_SPI; -} - -void sys_copyself(void) -{ - int d = get_boot_device(); - void * mem; - uint32_t size; - - if(d == BOOT_DEVICE_FEL) - { - sys_uart_putc('B'); - sys_uart_putc('o'); - sys_uart_putc('o'); - sys_uart_putc('t'); - sys_uart_putc(' '); - sys_uart_putc('t'); - sys_uart_putc('o'); - sys_uart_putc(' '); - sys_uart_putc('F'); - sys_uart_putc('E'); - sys_uart_putc('L'); - sys_uart_putc(' '); - sys_uart_putc('m'); - sys_uart_putc('o'); - sys_uart_putc('d'); - sys_uart_putc('e'); - sys_uart_putc('\r'); - sys_uart_putc('\n'); - return_to_fel(); - } - else if(d == BOOT_DEVICE_SPI) - { - sys_uart_putc('B'); - sys_uart_putc('o'); - sys_uart_putc('o'); - sys_uart_putc('t'); - sys_uart_putc(' '); - sys_uart_putc('t'); - sys_uart_putc('o'); - sys_uart_putc(' '); - sys_uart_putc('S'); - sys_uart_putc('P'); - sys_uart_putc('I'); - sys_uart_putc(' '); - sys_uart_putc('m'); - sys_uart_putc('o'); - sys_uart_putc('d'); - sys_uart_putc('e'); - sys_uart_putc('\r'); - sys_uart_putc('\n'); - mem = (void *)&__image_start; - size = &__image_end - &__image_start; - sys_mmu_init(); - - sys_spi_flash_init(); - sys_spi_flash_read(0, mem, size); - sys_spi_flash_exit(); - } - else if(d == BOOT_DEVICE_MMC) - { - mem = (void *)&__image_start; - size = (&__image_end - &__image_start + 512) >> 9; - } -} diff --git a/hw/mcu/allwinner/f1c100s/machine/sys-dram.c b/hw/mcu/allwinner/f1c100s/machine/sys-dram.c deleted file mode 100644 index a819520a5..000000000 --- a/hw/mcu/allwinner/f1c100s/machine/sys-dram.c +++ /dev/null @@ -1,506 +0,0 @@ -/* - * sys-dram.c - * - * Copyright(c) 2007-2018 Jianjun Jiang <8192542@qq.com> - * Official site: http://xboot.org - * Mobile phone: +86-18665388956 - * QQ: 8192542 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#include -#include -#include -#include - -#define PLL_DDR_CLK (156000000) -#define SDR_T_CAS (0x2) -#define SDR_T_RAS (0x8) -#define SDR_T_RCD (0x3) -#define SDR_T_RP (0x3) -#define SDR_T_WR (0x3) -#define SDR_T_RFC (0xd) -#define SDR_T_XSR (0xf9) -#define SDR_T_RC (0xb) -#define SDR_T_INIT (0x8) -#define SDR_T_INIT_REF (0x7) -#define SDR_T_WTR (0x2) -#define SDR_T_RRD (0x2) -#define SDR_T_XP (0x0) - -enum dram_type_t -{ - DRAM_TYPE_SDR = 0, - DRAM_TYPE_DDR = 1, - DRAM_TYPE_MDDR = 2, -}; - -struct dram_para_t -{ - uint32_t base; /* dram base address */ - uint32_t size; /* dram size (unit: MByte) */ - uint32_t clk; /* dram work clock (unit: MHz) */ - uint32_t access_mode; /* 0: interleave mode 1: sequence mode */ - uint32_t cs_num; /* dram chip count 1: one chip 2: two chip */ - uint32_t ddr8_remap; /* for 8bits data width DDR 0: normal 1: 8bits */ - enum dram_type_t sdr_ddr; - uint32_t bwidth; /* dram bus width */ - uint32_t col_width; /* column address width */ - uint32_t row_width; /* row address width */ - uint32_t bank_size; /* dram bank count */ - uint32_t cas; /* dram cas */ -}; - -static inline void sdelay(int loops) -{ - __asm__ __volatile__ ("1:\n" "subs %0, %1, #1\n" - "bne 1b":"=r" (loops):"0"(loops)); -} - -static void dram_delay(int ms) -{ - sdelay(ms * 2 * 1000); -} - -static int dram_initial(void) -{ - unsigned int time = 0xffffff; - - write32(F1C100S_DRAM_BASE + DRAM_SCTLR, read32(F1C100S_DRAM_BASE + DRAM_SCTLR) | 0x1); - while((read32(F1C100S_DRAM_BASE + DRAM_SCTLR) & 0x1) && time--) - { - if(time == 0) - return 0; - } - return 1; -} - -static int dram_delay_scan(void) -{ - unsigned int time = 0xffffff; - - write32(F1C100S_DRAM_BASE + DRAM_DDLYR, read32(F1C100S_DRAM_BASE + DRAM_DDLYR) | 0x1); - while((read32(F1C100S_DRAM_BASE + DRAM_DDLYR) & 0x1) && time--) - { - if(time == 0) - return 0; - } - return 1; -} - -static void dram_set_autofresh_cycle(uint32_t clk) -{ - uint32_t val = 0; - uint32_t row = 0; - uint32_t temp = 0; - - row = read32(F1C100S_DRAM_BASE + DRAM_SCONR); - row &= 0x1e0; - row >>= 0x5; - - if(row == 0xc) - { - if(clk >= 1000000) - { - temp = clk + (clk >> 3) + (clk >> 4) + (clk >> 5); - while(temp >= (10000000 >> 6)) - { - temp -= (10000000 >> 6); - val++; - } - } - else - { - val = (clk * 499) >> 6; - } - } - else if(row == 0xb) - { - if(clk >= 1000000) - { - temp = clk + (clk >> 3) + (clk >> 4) + (clk >> 5); - while(temp >= (10000000 >> 7)) - { - temp -= (10000000 >> 7); - val++; - } - } - else - { - val = (clk * 499) >> 5; - } - } - write32(F1C100S_DRAM_BASE + DRAM_SREFR, val); -} - -static int dram_para_setup(struct dram_para_t * para) -{ - uint32_t val = 0; - - val = (para->ddr8_remap) | - (0x1 << 1) | - ((para->bank_size >> 2) << 3) | - ((para->cs_num >> 1) << 4) | - ((para->row_width - 1) << 5) | - ((para->col_width - 1) << 9) | - ((para->sdr_ddr ? (para->bwidth >> 4) : (para->bwidth >> 5)) << 13) | - (para->access_mode << 15) | - (para->sdr_ddr << 16); - - write32(F1C100S_DRAM_BASE + DRAM_SCONR, val); - write32(F1C100S_DRAM_BASE + DRAM_SCTLR, read32(F1C100S_DRAM_BASE + DRAM_SCTLR) | (0x1 << 19)); - return dram_initial(); -} - -static uint32_t dram_check_delay(uint32_t bwidth) -{ - uint32_t dsize; - uint32_t i,j; - uint32_t num = 0; - uint32_t dflag = 0; - - dsize = ((bwidth == 16) ? 4 : 2); - for(i = 0; i < dsize; i++) - { - if(i == 0) - dflag = read32(F1C100S_DRAM_BASE + DRAM_DRPTR0); - else if(i == 1) - dflag = read32(F1C100S_DRAM_BASE + DRAM_DRPTR1); - else if(i == 2) - dflag = read32(F1C100S_DRAM_BASE + DRAM_DRPTR2); - else if(i == 3) - dflag = read32(F1C100S_DRAM_BASE + DRAM_DRPTR3); - - for(j = 0; j < 32; j++) - { - if(dflag & 0x1) - num++; - dflag >>= 1; - } - } - return num; -} - -static int sdr_readpipe_scan(void) -{ - uint32_t k = 0; - - for(k = 0; k < 32; k++) - { - write32(0x80000000 + 4 * k, k); - } - for(k = 0; k < 32; k++) - { - if(read32(0x80000000 + 4 * k) != k) - return 0; - } - return 1; -} - -static uint32_t sdr_readpipe_select(void) -{ - uint32_t value = 0; - uint32_t i = 0; - for(i = 0; i < 8; i++) - { - write32(F1C100S_DRAM_BASE + DRAM_SCTLR, (read32(F1C100S_DRAM_BASE + DRAM_SCTLR) & (~(0x7 << 6))) | (i << 6)); - if(sdr_readpipe_scan()) - { - value = i; - return value; - } - } - return value; -} - -static uint32_t dram_check_type(struct dram_para_t * para) -{ - uint32_t val = 0; - uint32_t times = 0; - uint32_t i; - - for(i = 0; i < 8; i++) - { - val = read32(F1C100S_DRAM_BASE + DRAM_SCTLR); - val &= ~(0x7 << 6); - val |= (i << 6); - write32(F1C100S_DRAM_BASE + DRAM_SCTLR, val); - - dram_delay_scan(); - if(read32(F1C100S_DRAM_BASE + DRAM_DDLYR) & 0x30) - times++; - } - - if(times == 8) - { - para->sdr_ddr = DRAM_TYPE_SDR; - return 0; - } - else - { - para->sdr_ddr = DRAM_TYPE_DDR; - return 1; - } -} - -static uint32_t dram_scan_readpipe(struct dram_para_t * para) -{ - uint32_t i, rp_best = 0, rp_val = 0; - uint32_t val = 0; - uint32_t readpipe[8]; - - if(para->sdr_ddr == DRAM_TYPE_DDR) - { - for(i = 0; i < 8; i++) - { - val = read32(F1C100S_DRAM_BASE + DRAM_SCTLR); - val &= ~(0x7 << 6); - val |= (i << 6); - write32(F1C100S_DRAM_BASE + DRAM_SCTLR, val); - dram_delay_scan(); - readpipe[i] = 0; - if((((read32(F1C100S_DRAM_BASE + DRAM_DDLYR) >> 4) & 0x3) == 0x0) && - (((read32(F1C100S_DRAM_BASE + DRAM_DDLYR) >> 4) & 0x1) == 0x0)) - { - readpipe[i] = dram_check_delay(para->bwidth); - } - if(rp_val < readpipe[i]) - { - rp_val = readpipe[i]; - rp_best = i; - } - } - val = read32(F1C100S_DRAM_BASE + DRAM_SCTLR); - val &= ~(0x7 << 6); - val |= (rp_best << 6); - write32(F1C100S_DRAM_BASE + DRAM_SCTLR, val); - dram_delay_scan(); - } - else - { - val = read32(F1C100S_DRAM_BASE + DRAM_SCONR); - val &= (~(0x1 << 16)); - val &= (~(0x3 << 13)); - write32(F1C100S_DRAM_BASE + DRAM_SCONR, val); - rp_best = sdr_readpipe_select(); - val = read32(F1C100S_DRAM_BASE + DRAM_SCTLR); - val &= ~(0x7 << 6); - val |= (rp_best << 6); - write32(F1C100S_DRAM_BASE + DRAM_SCTLR, val); - } - return 0; -} - -static uint32_t dram_get_dram_size(struct dram_para_t * para) -{ - uint32_t colflag = 10, rowflag = 13; - uint32_t i = 0; - uint32_t val1 = 0; - uint32_t count = 0; - uint32_t addr1, addr2; - - para->col_width = colflag; - para->row_width = rowflag; - dram_para_setup(para); - dram_scan_readpipe(para); - for(i = 0; i < 32; i++) - { - *((uint32_t *)(0x80000200 + i)) = 0x11111111; - *((uint32_t *)(0x80000600 + i)) = 0x22222222; - } - for(i = 0; i < 32; i++) - { - val1 = *((uint32_t *)(0x80000200 + i)); - if(val1 == 0x22222222) - count++; - } - if(count == 32) - { - colflag = 9; - } - else - { - colflag = 10; - } - count = 0; - para->col_width = colflag; - para->row_width = rowflag; - dram_para_setup(para); - if(colflag == 10) - { - addr1 = 0x80400000; - addr2 = 0x80c00000; - } - else - { - addr1 = 0x80200000; - addr2 = 0x80600000; - } - for(i = 0; i < 32; i++) - { - *((uint32_t *)(addr1 + i)) = 0x33333333; - *((uint32_t *)(addr2 + i)) = 0x44444444; - } - for(i = 0; i < 32; i++) - { - val1 = *((uint32_t *)(addr1 + i)); - if(val1 == 0x44444444) - { - count++; - } - } - if(count == 32) - { - rowflag = 12; - } - else - { - rowflag = 13; - } - para->col_width = colflag; - para->row_width = rowflag; - if(para->row_width != 13) - { - para->size = 16; - } - else if(para->col_width == 10) - { - para->size = 64; - } - else - { - para->size = 32; - } - dram_set_autofresh_cycle(para->clk); - para->access_mode = 0; - dram_para_setup(para); - - return 0; -} - -static int dram_init(struct dram_para_t * para) -{ - uint32_t val = 0; - uint32_t i; - - write32(0x01c20800 + 0x24, read32(0x01c20800 + 0x24) | (0x7 << 12)); - dram_delay(5); - if(((para->cas) >> 3) & 0x1) - { - write32(0x01c20800 + 0x2c4, read32(0x01c20800 + 0x2c4) | (0x1 << 23) | (0x20 << 17)); - } - if((para->clk >= 144) && (para->clk <= 180)) - { - write32(0x01c20800 + 0x2c0, 0xaaa); - } - if(para->clk >= 180) - { - write32(0x01c20800 + 0x2c0, 0xfff); - } - if((para->clk) <= 96) - { - val = (0x1 << 0) | (0x0 << 4) | (((para->clk * 2) / 12 - 1) << 8) | (0x1u << 31); - } - else - { - val = (0x0 << 0) | (0x0 << 4) | (((para->clk * 2) / 24 - 1) << 8) | (0x1u << 31); - } - - if(para->cas & (0x1 << 4)) - { - write32(F1C100S_CCU_BASE + CCU_PLL_DDR0_PAT, 0xd1303333); - } - else if(para->cas & (0x1 << 5)) - { - write32(F1C100S_CCU_BASE + CCU_PLL_DDR0_PAT, 0xcce06666); - } - else if(para->cas & (0x1 << 6)) - { - write32(F1C100S_CCU_BASE + CCU_PLL_DDR0_PAT, 0xc8909999); - } - else if(para->cas & (0x1 << 7)) - { - write32(F1C100S_CCU_BASE + CCU_PLL_DDR0_PAT, 0xc440cccc); - } - if(para->cas & (0xf << 4)) - { - val |= 0x1 << 24; - } - write32(F1C100S_CCU_BASE + CCU_PLL_DDR_CTRL, val); - write32(F1C100S_CCU_BASE + CCU_PLL_DDR_CTRL, read32(F1C100S_CCU_BASE + CCU_PLL_DDR_CTRL) | (0x1 << 20)); - while((read32(F1C100S_CCU_BASE + CCU_PLL_DDR_CTRL) & (1 << 28)) == 0); - dram_delay(5); - write32(F1C100S_CCU_BASE + CCU_BUS_CLK_GATE0, read32(F1C100S_CCU_BASE + CCU_BUS_CLK_GATE0) | (0x1 << 14)); - write32(F1C100S_CCU_BASE + CCU_BUS_SOFT_RST0, read32(F1C100S_CCU_BASE + CCU_BUS_SOFT_RST0) & ~(0x1 << 14)); - for(i = 0; i < 10; i++) - continue; - write32(F1C100S_CCU_BASE + CCU_BUS_SOFT_RST0, read32(F1C100S_CCU_BASE + CCU_BUS_SOFT_RST0) | (0x1 << 14)); - - val = read32(0x01c20800 + 0x2c4); - (para->sdr_ddr == DRAM_TYPE_DDR) ? (val |= (0x1 << 16)) : (val &= ~(0x1 << 16)); - write32(0x01c20800 + 0x2c4, val); - - val = (SDR_T_CAS << 0) | (SDR_T_RAS << 3) | (SDR_T_RCD << 7) | (SDR_T_RP << 10) | (SDR_T_WR << 13) | (SDR_T_RFC << 15) | (SDR_T_XSR << 19) | (SDR_T_RC << 28); - write32(F1C100S_DRAM_BASE + DRAM_STMG0R, val); - val = (SDR_T_INIT << 0) | (SDR_T_INIT_REF << 16) | (SDR_T_WTR << 20) | (SDR_T_RRD << 22) | (SDR_T_XP << 25); - write32(F1C100S_DRAM_BASE + DRAM_STMG1R, val); - dram_para_setup(para); - dram_check_type(para); - - val = read32(0x01c20800 + 0x2c4); - (para->sdr_ddr == DRAM_TYPE_DDR) ? (val |= (0x1 << 16)) : (val &= ~(0x1 << 16)); - write32(0x01c20800 + 0x2c4, val); - - dram_set_autofresh_cycle(para->clk); - dram_scan_readpipe(para); - dram_get_dram_size(para); - - for(i = 0; i < 128; i++) - { - *((volatile uint32_t *)(para->base + 4 * i)) = para->base + 4 * i; - } - - for(i = 0; i < 128; i++) - { - if(*((volatile uint32_t *)(para->base + 4 * i)) != (para->base + 4 * i)) - return 0; - } - return 1; -} - -void sys_dram_init(void) -{ - struct dram_para_t para; - uint32_t * dsz = (void *)0x0000005c; - - para.base = 0x80000000; - para.size = 32; - para.clk = PLL_DDR_CLK / 1000000; - para.access_mode = 1; - para.cs_num = 1; - para.ddr8_remap = 0; - para.sdr_ddr = DRAM_TYPE_DDR; - para.bwidth = 16; - para.col_width = 10; - para.row_width = 13; - para.bank_size = 4; - para.cas = 0x3; - - if((dsz[0] >> 24) == 'X') - return; - if(dram_init(¶)) - dsz[0] = (((uint32_t)'X') << 24) | (para.size << 0); -} diff --git a/hw/mcu/allwinner/f1c100s/machine/sys-mmu.c b/hw/mcu/allwinner/f1c100s/machine/sys-mmu.c deleted file mode 100644 index 3c89c7255..000000000 --- a/hw/mcu/allwinner/f1c100s/machine/sys-mmu.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * sys-mmu.c - * - * Copyright(c) 2007-2018 Jianjun Jiang <8192542@qq.com> - * Official site: http://xboot.org - * Mobile phone: +86-18665388956 - * QQ: 8192542 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include - -static void map_l1_section(uint32_t * ttb, virtual_addr_t virt, physical_addr_t phys, physical_size_t size, int type) -{ - physical_size_t i; - - virt >>= 20; - phys >>= 20; - size >>= 20; - type &= 0x3; - - for(i = size; i > 0; i--, virt++, phys++) - ttb[virt] = (phys << 20) | (0x3 << 10) | (0x0 << 5) | (type << 2) | (0x2 << 0); -} - -void sys_mmu_init(void) -{ - uint32_t * ttb = (uint32_t *)(0x80000000 + SZ_1M * 31); - - map_l1_section(ttb, 0x00000000, 0x00000000, SZ_2G, 0); - map_l1_section(ttb, 0x80000000, 0x80000000, SZ_2G, 0); - map_l1_section(ttb, 0x80000000, 0x80000000, SZ_1M * 32, 3); - - arm32_ttb_set((uint32_t)(ttb)); - arm32_tlb_invalidate(); - arm32_domain_set(0x3); - arm32_mmu_enable(); - arm32_icache_enable(); - arm32_dcache_enable(); -} \ No newline at end of file diff --git a/hw/mcu/allwinner/f1c100s/machine/sys-spi-flash.c b/hw/mcu/allwinner/f1c100s/machine/sys-spi-flash.c deleted file mode 100644 index 5c3b0f0aa..000000000 --- a/hw/mcu/allwinner/f1c100s/machine/sys-spi-flash.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * sys-spi-flash.c - * - * Copyright(c) 2007-2018 Jianjun Jiang <8192542@qq.com> - * Official site: http://xboot.org - * Mobile phone: +86-18665388956 - * QQ: 8192542 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include - -enum { - SPI_GCR = 0x04, - SPI_TCR = 0x08, - SPI_IER = 0x10, - SPI_ISR = 0x14, - SPI_FCR = 0x18, - SPI_FSR = 0x1c, - SPI_WCR = 0x20, - SPI_CCR = 0x24, - SPI_MBC = 0x30, - SPI_MTC = 0x34, - SPI_BCC = 0x38, - SPI_TXD = 0x200, - SPI_RXD = 0x300, -}; - -void sys_spi_flash_init(void) -{ - virtual_addr_t addr; - uint32_t val; - - /* Config GPIOC0, GPIOC1, GPIOC2 and GPIOC3 */ - addr = 0x01c20848 + 0x00; - val = read32(addr); - val &= ~(0xf << ((0 & 0x7) << 2)); - val |= ((0x2 & 0x7) << ((0 & 0x7) << 2)); - write32(addr, val); - - val = read32(addr); - val &= ~(0xf << ((1 & 0x7) << 2)); - val |= ((0x2 & 0x7) << ((1 & 0x7) << 2)); - write32(addr, val); - - val = read32(addr); - val &= ~(0xf << ((2 & 0x7) << 2)); - val |= ((0x2 & 0x7) << ((2 & 0x7) << 2)); - write32(addr, val); - - val = read32(addr); - val &= ~(0xf << ((3 & 0x7) << 2)); - val |= ((0x2 & 0x7) << ((3 & 0x7) << 2)); - write32(addr, val); - - /* Deassert spi0 reset */ - addr = 0x01c202c0; - val = read32(addr); - val |= (1 << 20); - write32(addr, val); - - /* Open the spi0 bus gate */ - addr = 0x01c20000 + 0x60; - val = read32(addr); - val |= (1 << 20); - write32(addr, val); - - /* Set spi clock rate control register, divided by 4 */ - addr = 0x01c05000; - write32(addr + SPI_CCR, 0x00001001); - - /* Enable spi0 and do a soft reset */ - addr = 0x01c05000; - val = read32(addr + SPI_GCR); - val |= (1 << 31) | (1 << 7) | (1 << 1) | (1 << 0); - write32(addr + SPI_GCR, val); - while(read32(addr + SPI_GCR) & (1 << 31)); - - val = read32(addr + SPI_TCR); - val &= ~(0x3 << 0); - val |= (1 << 6) | (1 << 2); - write32(addr + SPI_TCR, val); - - val = read32(addr + SPI_FCR); - val |= (1 << 31) | (1 << 15); - write32(addr + SPI_FCR, val); -} - -void sys_spi_flash_exit(void) -{ - virtual_addr_t addr = 0x01c05000; - uint32_t val; - - /* Disable the spi0 controller */ - val = read32(addr + SPI_GCR); - val &= ~((1 << 1) | (1 << 0)); - write32(addr + SPI_GCR, val); -} - -static void sys_spi_select(void) -{ - virtual_addr_t addr = 0x01c05000; - uint32_t val; - - val = read32(addr + SPI_TCR); - val &= ~((0x3 << 4) | (0x1 << 7)); - val |= ((0 & 0x3) << 4) | (0x0 << 7); - write32(addr + SPI_TCR, val); -} - -static void sys_spi_deselect(void) -{ - virtual_addr_t addr = 0x01c05000; - uint32_t val; - - val = read32(addr + SPI_TCR); - val &= ~((0x3 << 4) | (0x1 << 7)); - val |= ((0 & 0x3) << 4) | (0x1 << 7); - write32(addr + SPI_TCR, val); -} - -static void sys_spi_write_txbuf(uint8_t * buf, int len) -{ - virtual_addr_t addr = 0x01c05000; - int i; - - if(!buf) - len = 0; - - write32(addr + SPI_MTC, len & 0xffffff); - write32(addr + SPI_BCC, len & 0xffffff); - for(i = 0; i < len; ++i) - write8(addr + SPI_TXD, *buf++); -} - -static int sys_spi_transfer(void * txbuf, void * rxbuf, int len) -{ - virtual_addr_t addr = 0x01c05000; - int count = len; - uint8_t * tx = txbuf; - uint8_t * rx = rxbuf; - uint8_t val; - unsigned int n, i; - - while(count > 0) - { - n = (count <= 64) ? count : 64; - write32(addr + SPI_MBC, n); - sys_spi_write_txbuf(tx, n); - write32(addr + SPI_TCR, read32(addr + SPI_TCR) | (1 << 31)); - - while((read32(addr + SPI_FSR) & 0xff) < n); - for(i = 0; i < n; i++) - { - val = read8(addr + SPI_RXD); - if(rx) - *rx++ = val; - } - - if(tx) - tx += n; - count -= n; - } - return len; -} - -static int sys_spi_write_then_read(void * txbuf, int txlen, void * rxbuf, int rxlen) -{ - if(sys_spi_transfer(txbuf, NULL, txlen) != txlen) - return -1; - if(sys_spi_transfer(NULL, rxbuf, rxlen) != rxlen) - return -1; - return 0; -} - -void sys_spi_flash_read(int addr, void * buf, int count) -{ - uint8_t tx[4]; - - tx[0] = 0x03; - tx[1] = (uint8_t)(addr >> 16); - tx[2] = (uint8_t)(addr >> 8); - tx[3] = (uint8_t)(addr >> 0); - sys_spi_select(); - sys_spi_write_then_read(tx, 4, buf, count); - sys_spi_deselect(); -} diff --git a/hw/mcu/allwinner/f1c100s/machine/sys-uart.c b/hw/mcu/allwinner/f1c100s/machine/sys-uart.c deleted file mode 100644 index 0e61627b7..000000000 --- a/hw/mcu/allwinner/f1c100s/machine/sys-uart.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * sys-uart.c - * - * Copyright(c) 2007-2018 Jianjun Jiang <8192542@qq.com> - * Official site: http://xboot.org - * Mobile phone: +86-18665388956 - * QQ: 8192542 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include - -void sys_uart_init(void) -{ - virtual_addr_t addr; - uint32_t val; - - /* Config GPIOE1 and GPIOE0 to txd0 and rxd0 */ - addr = 0x01c20890 + 0x00; - val = read32(addr); - val &= ~(0xf << ((1 & 0x7) << 2)); - val |= ((0x5 & 0x7) << ((1 & 0x7) << 2)); - write32(addr, val); - - val = read32(addr); - val &= ~(0xf << ((0 & 0x7) << 2)); - val |= ((0x5 & 0x7) << ((0 & 0x7) << 2)); - write32(addr, val); - - /* Open the clock gate for uart0 */ - addr = 0x01c20068; - val = read32(addr); - val |= 1 << 20; - write32(addr, val); - - /* Deassert uart0 reset */ - addr = 0x01c202d0; - val = read32(addr); - val |= 1 << 20; - write32(addr, val); - - /* Config uart0 to 115200-8-1-0 */ - addr = 0x01c25000; - write32(addr + 0x04, 0x0); - write32(addr + 0x08, 0xf7); - write32(addr + 0x10, 0x0); - val = read32(addr + 0x0c); - val |= (1 << 7); - write32(addr + 0x0c, val); - write32(addr + 0x00, 0x36 & 0xff); - write32(addr + 0x04, (0x36 >> 8) & 0xff); - val = read32(addr + 0x0c); - val &= ~(1 << 7); - write32(addr + 0x0c, val); - val = read32(addr + 0x0c); - val &= ~0x1f; - val |= (0x3 << 0) | (0 << 2) | (0x0 << 3); - write32(addr + 0x0c, val); -} - -void sys_uart_putc(char c) -{ - virtual_addr_t addr = 0x01c25000; - - while((read32(addr + 0x7c) & (0x1 << 1)) == 0); - write32(addr + 0x00, c); -} From b943a53b1066e8a736eb7a32e42af6324a208718 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 29 Dec 2021 19:04:08 +0700 Subject: [PATCH 092/504] update allwinner submodule --- hw/mcu/allwinner | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/mcu/allwinner b/hw/mcu/allwinner index c56955e15..8e5e89e8e 160000 --- a/hw/mcu/allwinner +++ b/hw/mcu/allwinner @@ -1 +1 @@ -Subproject commit c56955e156b1050a4a8ccf8589555148f00a1bb6 +Subproject commit 8e5e89e8e132c0fd90e72d5422e5d3d68232b756 From 84e2f6e0e144614b306f68416958f8f662c8cb46 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 29 Dec 2021 19:12:41 +0700 Subject: [PATCH 093/504] skip freertos example for f1c100s --- examples/device/cdc_msc_freertos/.skip.MCU_F1C100S | 0 examples/device/hid_composite_freertos/.skip.MCU_F1C100S | 0 hw/bsp/f1c100s/f1c100s.c | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 examples/device/cdc_msc_freertos/.skip.MCU_F1C100S create mode 100644 examples/device/hid_composite_freertos/.skip.MCU_F1C100S diff --git a/examples/device/cdc_msc_freertos/.skip.MCU_F1C100S b/examples/device/cdc_msc_freertos/.skip.MCU_F1C100S new file mode 100644 index 000000000..e69de29bb diff --git a/examples/device/hid_composite_freertos/.skip.MCU_F1C100S b/examples/device/hid_composite_freertos/.skip.MCU_F1C100S new file mode 100644 index 000000000..e69de29bb diff --git a/hw/bsp/f1c100s/f1c100s.c b/hw/bsp/f1c100s/f1c100s.c index 6cf18597c..d45072ecb 100644 --- a/hw/bsp/f1c100s/f1c100s.c +++ b/hw/bsp/f1c100s/f1c100s.c @@ -49,7 +49,7 @@ void board_init(void) arch_local_irq_enable(); } -// No LED, no button, sorry +// No LED, no button void board_led_write(bool state) { From 5f280b30290e540f24d55fdd3e0dd46efa251547 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 29 Dec 2021 19:22:39 +0700 Subject: [PATCH 094/504] add license to dcd file, slightly update readme --- hw/bsp/f1c100s/README.md | 6 ++++-- hw/bsp/f1c100s/board.mk | 4 +++- src/osal/osal_rtx4.h | 1 + src/portable/sunxi/dcd_sunxi_musb.c | 27 +++++++++++++++++++++++++++ src/portable/sunxi/musb_def.h | 27 +++++++++++++++++++++++++++ 5 files changed, 62 insertions(+), 3 deletions(-) diff --git a/hw/bsp/f1c100s/README.md b/hw/bsp/f1c100s/README.md index cc33ca1f4..325044716 100644 --- a/hw/bsp/f1c100s/README.md +++ b/hw/bsp/f1c100s/README.md @@ -4,9 +4,11 @@ This folder contains necessary file and scripts to run TinyUSB examples on F1Cx0 Currently tested on: -* Lichee Pi Nano (F1C100s) +- Lichee Pi Nano (F1C100s) +- [Widora Tiny200 v2 (also called MangoPi-R3c)](https://mangopi.org/tiny200) ## Flashing + There are two options to put your code into the MCU: `flash` and `exec`. Both modes require you to install [xfel](https://github.com/xboot/xfel) tool to your PATH. You must enter FEL mode before any operation can be done. To enter FEL mode, press BOOT button, then press RESET once, and release BOOT button. You will find VID/PID=1f3a:efe8 on your PC. Exec: `make BOARD=f1c100s exec` will just upload the image to the DDR ram and execute it. It will not touch anything in the SPI flash. @@ -14,5 +16,5 @@ Exec: `make BOARD=f1c100s exec` will just upload the image to the DDR ram and ex Flash: `make BOARD=f1c100s flash` will write the image to SPI flash, and then reset the chip to execute it. ## TODO -* Test on Tiny200 v2 (F1C200s) + * Add F1C100s to `#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX` high speed MCU check in examples (maybe we should extract the logic?) \ No newline at end of file diff --git a/hw/bsp/f1c100s/board.mk b/hw/bsp/f1c100s/board.mk index 9bd9380a7..5fe26a9ea 100644 --- a/hw/bsp/f1c100s/board.mk +++ b/hw/bsp/f1c100s/board.mk @@ -1,3 +1,5 @@ +DEPS_SUBMODULES += hw/mcu/allwinner + DEFINES += -D__ARM32_ARCH__=5 -D__ARM926EJS__ CFLAGS += \ @@ -33,7 +35,7 @@ SRC_C += \ $(MCU_DIR)/lib/printf.c SRC_S += \ - $(MCU_DIR)/machine/start.S \ + $(MCU_DIR)/machine/start.S \ $(MCU_DIR)/lib/memcpy.S \ $(MCU_DIR)/lib/memset.S diff --git a/src/osal/osal_rtx4.h b/src/osal/osal_rtx4.h index 93d1a7a28..32d7782d9 100644 --- a/src/osal/osal_rtx4.h +++ b/src/osal/osal_rtx4.h @@ -1,6 +1,7 @@ /* * The MIT License (MIT) * + * Copyright (c) 2021 Tian Yunhao (t123yh) * Copyright (c) 2019 Ha Thach (tinyusb.org) * * Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/src/portable/sunxi/dcd_sunxi_musb.c b/src/portable/sunxi/dcd_sunxi_musb.c index be1847b21..3d39248c1 100644 --- a/src/portable/sunxi/dcd_sunxi_musb.c +++ b/src/portable/sunxi/dcd_sunxi_musb.c @@ -1,3 +1,30 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 Tian Yunhao (t123yh) + * 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. + */ + #include #include "tusb_option.h" #include "osal/osal.h" diff --git a/src/portable/sunxi/musb_def.h b/src/portable/sunxi/musb_def.h index f55ddab3b..e0c8a5e20 100644 --- a/src/portable/sunxi/musb_def.h +++ b/src/portable/sunxi/musb_def.h @@ -1,3 +1,30 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 Tian Yunhao (t123yh) + * 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. + */ + #ifndef _TUSB_MUSB_DEF #define _TUSB_MUSB_DEF From adb848f75489ea6a9fa27be8c7c53cfa0679af91 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 29 Dec 2021 19:40:55 +0700 Subject: [PATCH 095/504] update docs --- CONTRIBUTORS.rst | 6 ++++++ README.rst | 1 + src/portable/sunxi/dcd_sunxi_musb.c | 1 + src/portable/sunxi/musb_def.h | 1 + 4 files changed, 9 insertions(+) diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst index e3186f086..05d088ee7 100644 --- a/CONTRIBUTORS.rst +++ b/CONTRIBUTORS.rst @@ -153,6 +153,12 @@ Notable contributors - Add new class driver for DFU Runtime +`Tian Yunhao `__ +------------------------------------------- + +- Add new DCD port for Allwinner F1C100S/F1C200S +- Add support for osal_rtx4 + `Timon Skerutsch `__ ---------------------------------------------- diff --git a/README.rst b/README.rst index 03219db3f..7f1eff8b4 100644 --- a/README.rst +++ b/README.rst @@ -32,6 +32,7 @@ Supported MCUs The stack supports the following MCUs: +- **Allwinner:** F1C100s/F1C200s - **Broadcom:** BCM2837, BCM2711 - **Dialog:** DA1469x - **Espressif:** ESP32-S2, ESP32-S3 diff --git a/src/portable/sunxi/dcd_sunxi_musb.c b/src/portable/sunxi/dcd_sunxi_musb.c index 3d39248c1..89464c5b2 100644 --- a/src/portable/sunxi/dcd_sunxi_musb.c +++ b/src/portable/sunxi/dcd_sunxi_musb.c @@ -1,6 +1,7 @@ /* * The MIT License (MIT) * + * Copyright (c) 2021 Koji KITAYAMA * Copyright (c) 2021 Tian Yunhao (t123yh) * Copyright (c) 2021 Ha Thach (tinyusb.org) * diff --git a/src/portable/sunxi/musb_def.h b/src/portable/sunxi/musb_def.h index e0c8a5e20..602b4f113 100644 --- a/src/portable/sunxi/musb_def.h +++ b/src/portable/sunxi/musb_def.h @@ -1,6 +1,7 @@ /* * The MIT License (MIT) * + * Copyright (c) 2021 Koji KITAYAMA * Copyright (c) 2021 Tian Yunhao (t123yh) * Copyright (c) 2021 Ha Thach (tinyusb.org) * From c5d2c82cbbabf02cef16c2da565867f63900f69b Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 30 Dec 2021 20:59:53 +0700 Subject: [PATCH 096/504] fix unreachable warnings with keil --- src/device/usbd.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 0e31f47c7..448114303 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -44,11 +44,6 @@ #define CFG_TUD_TASK_QUEUE_SZ 16 #endif -#ifdef __ARMCC_VERSION -// Supress "statement is unreachable" warning -#pragma diag_suppress 111 -#endif - //--------------------------------------------------------------------+ // Device Data //--------------------------------------------------------------------+ @@ -1013,7 +1008,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const return tud_control_xfer(rhport, p_request, desc_device, sizeof(tusb_desc_device_t)); } } - break; + // break; // unreachable case TUSB_DESC_BOS: { @@ -1030,7 +1025,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const return tud_control_xfer(rhport, p_request, (void*) desc_bos, total_len); } - break; + // break; // unreachable case TUSB_DESC_CONFIGURATION: case TUSB_DESC_OTHER_SPEED_CONFIG: @@ -1056,7 +1051,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const return tud_control_xfer(rhport, p_request, (void*) desc_config, total_len); } - break; + // break; // unreachable case TUSB_DESC_STRING: { @@ -1069,7 +1064,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const // first byte of descriptor is its size return tud_control_xfer(rhport, p_request, (void*) (uintptr_t) desc_str, tu_desc_len(desc_str)); } - break; + // break; // unreachable case TUSB_DESC_DEVICE_QUALIFIER: { @@ -1083,7 +1078,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const // first byte of descriptor is its size return tud_control_xfer(rhport, p_request, (void*) (uintptr_t) desc_qualifier, tu_desc_len(desc_qualifier)); } - break; + // break; // unreachable default: return false; } From 2f69649bb6a2dcd583b52005dc946e08580323fd Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Sun, 26 Dec 2021 21:50:48 +0100 Subject: [PATCH 097/504] Add register file for Microchip PIC32MZ --- .../microchip/pic32mz/usbhs_registers.h | 931 ++++++++++++++++++ 1 file changed, 931 insertions(+) create mode 100644 src/portable/microchip/pic32mz/usbhs_registers.h diff --git a/src/portable/microchip/pic32mz/usbhs_registers.h b/src/portable/microchip/pic32mz/usbhs_registers.h new file mode 100644 index 000000000..757e3f083 --- /dev/null +++ b/src/portable/microchip/pic32mz/usbhs_registers.h @@ -0,0 +1,931 @@ +/******************************************************************************* +* Copyright (C) 2019 Microchip Technology Inc. and its subsidiaries. +* +* Subject to your compliance with these terms, you may use Microchip software +* and any derivatives exclusively with Microchip products. It is your +* responsibility to comply with third party license terms applicable to your +* use of third party software (including open source software) that may +* accompany Microchip software. +* +* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER +* EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED +* WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A +* PARTICULAR PURPOSE. +* +* IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, +* INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND +* WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS +* BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE +* FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN +* ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, +* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. +*******************************************************************************/ +/******************************************************************************* + USBHS Peripheral Library Register Defintions + + File Name: + usbhs_registers.h + + Summary: + USBHS PLIB Register Defintions + + Description: + This file contains the constants and defintions which are required by the + the USBHS library. +*******************************************************************************/ + +#ifndef __USBHS_REGISTERS_H__ +#define __USBHS_REGISTERS_H__ + +#include +#include + +/***************************************** + * Module Register Offsets. + *****************************************/ + +#define USBHS_REG_FADDR 0x000 +#define USBHS_REG_POWER 0x001 +#define USBHS_REG_INTRTX 0x002 +#define USBHS_REG_INTRRX 0x004 +#define USBHS_REG_INTRTXE 0x006 +#define USBHS_REG_INTRRXE 0x008 +#define USBHS_REG_INTRUSB 0x00A +#define USBHS_REG_INTRUSBE 0x00B +#define USBHS_REG_FRAME 0x00C +#define USBHS_REG_INDEX 0x00E +#define USBHS_REG_TESTMODE 0x00F + +/******************************************************* + * Endpoint Control Status Registers (CSR). These values + * should be added to either the 0x10 to access the + * register through Indexed CSR. To access the actual + * CSR, see ahead in this header file. + ******************************************************/ + +#define USBHS_REG_EP_TXMAXP 0x000 +#define USBHS_REG_EP_CSR0L 0x002 +#define USBHS_REG_EP_CSR0H 0x003 +#define USBHS_REG_EP_TXCSRL 0x002 +#define USBHS_REG_EP_TXCSRH 0x003 +#define USBHS_REG_EP_RXMAXP 0x004 +#define USBHS_REG_EP_RXCSRL 0x006 +#define USBHS_REG_EP_RXCSRH 0x007 +#define USBHS_REG_EP_COUNT0 0x008 +#define USBHS_REG_EP_RXCOUNT 0x008 +#define USBHS_REG_EP_TYPE0 0x01A +#define USBHS_REG_EP_TXTYPE 0x01A +#define USBHS_REG_EP_NAKLIMIT0 0x01B +#define USBHS_REG_EP_TXINTERVAL 0x01B +#define USBHS_REG_EP_RXTYPE 0x01C +#define USBHS_REG_EP_RXINTERVAL 0x01D +#define USBHS_REG_EP_CONFIGDATA 0x01F +#define USBHS_REG_EP_FIFOSIZE 0x01F + +#define USBHS_HOST_EP0_SETUPKT_SET 0x8 +#define USBHS_HOST_EP0_TXPKTRDY_SET 0x2 +#define USBHS_SOFT_RST_NRST_SET 0x1 +#define USBHS_SOFT_RST_NRSTX_SET 0x2 +#define USBHS_EP0_DEVICE_SERVICED_RXPKTRDY 0x40 +#define USBHS_EP0_DEVICE_DATAEND 0x08 +#define USBHS_EP0_DEVICE_TXPKTRDY 0x02 +#define USBHS_EP0_HOST_STATUS_STAGE_START 0x40 +#define USBHS_EP0_HOST_REQPKT 0x20 +#define USBHS_EP0_HOST_TXPKTRDY 0x02 +#define USBHS_EP0_HOST_RXPKTRDY 0x01 +#define USBHS_EP_DEVICE_TX_SENT_STALL 0x20 +#define USBHS_EP_DEVICE_TX_SEND_STALL 0x10 +#define USBHS_EP_DEVICE_RX_SENT_STALL 0x40 +#define USBHS_EP_DEVICE_RX_SEND_STALL 0x20 + +/* FADDR - Device Function Address */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned FUNC:7; + unsigned :1; + }; + + uint8_t w; + +} __USBHS_FADDR_t; + +/* POWER - Control Resume and Suspend signalling */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned SUSPEN:1; + unsigned SUSPMODE:1; + unsigned RESUME:1; + unsigned RESET:1; + unsigned HSMODE:1; + unsigned HSEN:1; + unsigned SOFTCONN:1; + unsigned ISOUPD:1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_POWER_t; + +/* INTRTXE - Transmit endpoint interrupt enable */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned EP0IE:1; + unsigned EP1TXIE:1; + unsigned EP2TXIE:1; + unsigned EP3TXIE:1; + unsigned EP4TXIE:1; + unsigned EP5TXIE:1; + unsigned EP6TXIE:1; + unsigned EP7TXIE:1; + unsigned :8; + }; + struct + { + uint16_t w; + }; + +} __USBHS_INTRTXE_t; + +/* INTRRXE - Receive endpoint interrupt enable */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned :1; + unsigned EP1RXIE:1; + unsigned EP2RXIE:1; + unsigned EP3RXIE:1; + unsigned EP4RXIE:1; + unsigned EP5RXIE:1; + unsigned EP6RXIE:1; + unsigned EP7RXIE:1; + unsigned :8; + }; + struct + { + uint16_t w; + }; + +} __USBHS_INTRRXE_t; + +/* INTRUSBE - General USB Interrupt enable */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned SUSPIE:1; + unsigned RESUMEIE:1; + unsigned RESETIE:1; + unsigned SOFIE:1; + unsigned CONNIE:1; + unsigned DISCONIE:1; + unsigned SESSRQIE:1; + unsigned VBUSERRIE:1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_INTRUSBE_t; + +/* FRAME - Frame number */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned RFRMNUM:11; + unsigned :5; + }; + struct + { + uint16_t w; + }; + +} __USBHS_FRAME_t; + +/* INDEX - Endpoint index */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned ENDPOINT:4; + unsigned :4; + }; + struct + { + uint8_t w; + }; + +} __USBHS_INDEX_t; + +/* TESTMODE - Test mode register */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned NAK:1; + unsigned TESTJ:1; + unsigned TESTK:1; + unsigned PACKET:1; + unsigned FORCEHS:1; + unsigned FORCEFS:1; + unsigned FIFOACC:1; + unsigned FORCEHST:1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_TESTMODE_t; + +/* COUNT0 - Indicates the amount of data received in endpoint 0 */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned RXCNT:7; + unsigned :1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_COUNT0_t; + +/* TYPE0 - Operating speed of target device */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned :6; + unsigned SPEED:2; + }; + struct + { + uint8_t w; + }; + +} __USBHS_TYPE0_t; + +/* DEVCTL - Module control register */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned SESSION:1; + unsigned HOSTREQ:1; + unsigned HOSTMODE:1; + unsigned VBUS:2; + unsigned LSDEV:1; + unsigned FSDEV:1; + unsigned BDEV:1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_DEVCTL_t; + +/* CSR0L Device - Endpoint Device Mode Control Status Register */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned RXPKTRDY:1; + unsigned TXPKTRDY:1; + unsigned SENTSTALL:1; + unsigned DATAEND:1; + unsigned SETUPEND:1; + unsigned SENDSTALL:1; + unsigned SVCRPR:1; + unsigned SVSSETEND:1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_CSR0L_DEVICE_t; + +/* CSR0L Host - Endpoint Host Mode Control Status Register */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned RXPKTRDY:1; + unsigned TXPKTRDY:1; + unsigned RXSTALL:1; + unsigned SETUPPKT:1; + unsigned ERROR:1; + unsigned REQPKT:1; + unsigned STATPKT:1; + unsigned NAKTMOUT:1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_CSR0L_HOST_t; + +/* TXCSRL Device - Endpoint Transmit Control Status Register Low */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned TXPKTRDY:1; + unsigned FIFOONE:1; + unsigned UNDERRUN:1; + unsigned FLUSH:1; + unsigned SENDSTALL:1; + unsigned SENTSTALL:1; + unsigned CLRDT:1; + unsigned INCOMPTX:1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_TXCSRL_DEVICE_t; + +/* TXCSRL Host - Endpoint Transmit Control Status Register Low */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned TXPKTRDY:1; + unsigned FIFONE:1; + unsigned ERROR:1; + unsigned FLUSH:1; + unsigned SETUPPKT:1; + unsigned RXSTALL:1; + unsigned CLRDT:1; + unsigned INCOMPTX:1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_TXCSRL_HOST_t; + +/* TXCSRH Device - Endpoint Transmit Control Status Register High */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned :2; + unsigned DMAREQMD:1; + unsigned FRCDATTG:1; + unsigned DMAREQENL:1; + unsigned MODE:1; + unsigned ISO:1; + unsigned AUTOSET:1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_TXCSRH_DEVICE_t; + +/* TXCSRH Host - Endpoint Transmit Control Status Register High */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned DATATGGL:1; + unsigned DTWREN:1; + unsigned DMAREQMD:1; + unsigned FRCDATTG:1; + unsigned DMAREQEN:1; + unsigned MODE:1; + unsigned :1; + unsigned AUOTSET:1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_TXCSRH_HOST_t; + +/* CSR0H Device - Endpoint 0 Control Status Register High */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned FLSHFIFO:1; + unsigned :7; + }; + struct + { + uint8_t w; + }; + +} __USBHS_CSR0H_DEVICE_t; + +/* CSR0H Host - Endpoint 0 Control Status Register High */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned FLSHFIFO:1; + unsigned DATATGGL:1; + unsigned DTWREN:1; + unsigned DISPING:1; + unsigned :4; + }; + struct + { + uint8_t w; + }; + +} __USBHS_CSR0H_HOST_t; + +/* RXMAXP - Receive Endpoint Max packet size. */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned RXMAXP:11; + unsigned MULT:5; + }; + struct + { + uint16_t w; + }; + +} __USBHS_RXMAXP_t; + +/* RXCSRL Device - Receive endpoint Control Status Register */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned RXPKTRDY:1; + unsigned FIFOFULL:1; + unsigned OVERRUN:1; + unsigned DATAERR:1; + unsigned FLUSH:1; + unsigned SENDSTALL:1; + unsigned SENTSTALL:1; + unsigned CLRDT:1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_RXCSRL_DEVICE_t; + +/* RXCSRL Host - Receive endpoint Control Status Register */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned RXPKTRDY:1; + unsigned FIFOFULL:1; + unsigned ERROR:1; + unsigned DERRNAKT:1; + unsigned FLUSH:1; + unsigned REQPKT:1; + unsigned RXSTALL:1; + unsigned CLRDT:1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_RXCSRL_HOST_t; + +/* RXCSRH Device - Receive endpoint Control Status Register */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned INCOMPRX:1; + unsigned :2; + unsigned DMAREQMODE:1; + unsigned DISNYET:1; + unsigned DMAREQEN:1; + unsigned ISO:1; + unsigned AUTOCLR:1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_RXCSRH_DEVICE_t; + +/* RXCSRH Host - Receive endpoint Control Status Register */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned INCOMPRX:1; + unsigned DATATGGL:1; + unsigned DATATWEN:1; + unsigned DMAREQMD:1; + unsigned PIDERR:1; + unsigned DMAREQEN:1; + unsigned AUTORQ:1; + unsigned AUOTCLR:1; + }; + struct + { + uint8_t w; + }; + +} __USBHS_RXCSRH_HOST_t; + +/* RXCOUNT - Amount of data pending in RX FIFO */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned RXCNT:14; + unsigned :2; + }; + struct + { + uint16_t w; + }; + +} __USBHS_RXCOUNT_t; + +/* TXTYPE - Specifies the target transmit endpoint */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned TEP:4; + unsigned PROTOCOL:2; + unsigned SPEED:2; + }; + struct + { + uint8_t w; + }; + +} __USBHS_TXTYPE_t; + +/* RXTYPE - Specifies the target receive endpoint */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned TEP:4; + unsigned PROTOCOL:2; + unsigned SPEED:2; + }; + struct + { + uint8_t w; + }; + +} __USBHS_RXTYPE_t; + +/* TXINTERVAL - Defines the polling interval */ +typedef struct +{ + uint8_t TXINTERV; + +} __USBHS_TXINTERVAL_t; + +/* RXINTERVAL - Defines the polling interval */ +typedef struct +{ + uint8_t RXINTERV; + +} __USBHS_RXINTERVAL_t; + +/* TXMAXP - Maximum amount of data that can be transferred through a TX endpoint + * */ + +typedef union +{ + struct __attribute__((packed)) + { + unsigned TXMAXP:11; + unsigned MULT:5; + }; + uint16_t w; + +} __USBHS_TXMAXP_t; + +/* TXFIFOSZ - Size of the transmit endpoint FIFO */ +typedef struct __attribute__((packed)) +{ + unsigned TXFIFOSZ:4; + unsigned TXDPB:1; + unsigned :3; + +} __USBHS_TXFIFOSZ_t; + +/* RXFIFOSZ - Size of the receive endpoint FIFO */ +typedef struct __attribute__((packed)) +{ + unsigned RXFIFOSZ:4; + unsigned RXDPB:1; + unsigned :3; + +} __USBHS_RXFIFOSZ_t; + +/* TXFIFOADD - Start address of the transmit endpoint FIFO */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned TXFIFOAD:13; + unsigned :3; + }; + uint16_t w; + +} __USBHS_TXFIFOADD_t; + +/* RXFIFOADD - Start address of the receive endpoint FIFO */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned RXFIFOAD:13; + unsigned :3; + }; + uint16_t w; + +} __USBHS_RXFIFOADD_t; + +/* SOFTRST - Asserts NRSTO and NRSTOX */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned NRST:1; + unsigned NRSTX:1; + unsigned :6; + }; + uint8_t w; + +} __USBHS_SOFTRST_t; + +/* TXFUNCADDR - Target address of transmit endpoint */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned TXFADDR:7; + unsigned :1; + }; + uint8_t w; + +} __USBHS_TXFUNCADDR_t; + +/* RXFUNCADDR - Target address of receive endpoint */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned RXFADDR:7; + unsigned :1; + }; + uint8_t w; + +} __USBHS_RXFUNCADDR_t; + +/* TXHUBADDR - Address of the hub to which the target transmit device endpoint + * is connected */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned TXHUBADDR:7; + unsigned MULTTRAN:1; + }; + uint8_t w; + +} __USBHS_TXHUBADDR_t; + +/* RXHUBADDR - Address of the hub to which the target receive device endpoint is + * connected */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned RXHUBADDR:7; + unsigned MULTTRAN:1; + }; + uint8_t w; + +} __USBHS_RXHUBADDR_t; + +/* TXHUBPORT - Address of the hub to which the target transmit device endpoint + * is connected. */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned TXHUBPRT:7; + unsigned :1; + }; + + uint8_t w; + +} __USBHS_TXHUBPORT_t; + +/* RXHUBPORT - Address of the hub to which the target receive device endpoint + * is connected. */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned RXHUBPRT:7; + unsigned :1; + }; + + uint8_t w; + +} __USBHS_RXHUBPORT_t; + +/* DMACONTROL - Configures a DMA channel */ +typedef union +{ + struct __attribute__((packed)) + { + unsigned DMAEN:1; + unsigned DMADIR:1; + unsigned DMAMODE:1; + unsigned DMAIE:1; + unsigned DMAEP:4; + unsigned DMAERR:1; + unsigned DMABRSTM:2; + unsigned:21; + }; + + uint32_t w; + +} __USBHS_DMACNTL_t; + +/* Endpoint Control and Status Register Set */ +typedef struct __attribute__((packed)) +{ + volatile __USBHS_TXMAXP_t TXMAXPbits; + union + { + struct + { + union + { + volatile __USBHS_CSR0L_DEVICE_t CSR0L_DEVICEbits; + volatile __USBHS_CSR0L_HOST_t CSR0L_HOSTbits; + }; + union + { + volatile __USBHS_CSR0H_DEVICE_t CSR0H_DEVICEbits; + volatile __USBHS_CSR0H_HOST_t CSR0H_HOSTbits; + }; + }; + + struct + { + union + { + volatile __USBHS_TXCSRL_DEVICE_t TXCSRL_DEVICEbits; + volatile __USBHS_TXCSRL_HOST_t TXCSRL_HOSTbits; + }; + + union + { + volatile __USBHS_TXCSRH_DEVICE_t TXCSRH_DEVICEbits; + volatile __USBHS_TXCSRH_HOST_t TXCSRH_HOSTbits; + }; + }; + }; + + volatile __USBHS_RXMAXP_t RXMAXPbits; + + union + { + volatile __USBHS_RXCSRL_DEVICE_t RXCSRL_DEVICEbits; + volatile __USBHS_RXCSRL_HOST_t RXCSRL_HOSTbits; + }; + + union + { + volatile __USBHS_RXCSRH_DEVICE_t RXCSRH_DEVICEbits; + volatile __USBHS_RXCSRH_HOST_t RXCSRH_HOSTbits; + }; + + union + { + volatile __USBHS_COUNT0_t COUNT0bits; + volatile __USBHS_RXCOUNT_t RXCOUNTbits; + }; + + union + { + volatile __USBHS_TYPE0_t TYPE0bits; + volatile __USBHS_TXTYPE_t TXTYPEbits; + }; + + union + { + volatile uint8_t NAKLIMIT0; + volatile __USBHS_TXINTERVAL_t TXINTERVALbits; + }; + + volatile __USBHS_RXTYPE_t RXTYPEbits; + volatile __USBHS_RXINTERVAL_t RXINTERVALbits; + unsigned :8; + union + { + volatile uint8_t CONFIGDATA; + volatile uint8_t FIFOSIZE; + }; + +} __USBHS_EPCSR_t; + +/* Set of registers that configure the multi-point option */ +typedef struct __attribute__((packed)) +{ + volatile __USBHS_TXFUNCADDR_t TXFUNCADDRbits; + unsigned :8; + volatile __USBHS_TXHUBADDR_t TXHUBADDRbits; + volatile __USBHS_TXHUBPORT_t TXHUBPORTbits; + volatile __USBHS_RXFUNCADDR_t RXFUNCADDRbits; + unsigned :8; + volatile __USBHS_RXHUBADDR_t RXHUBADDRbits; + volatile __USBHS_RXHUBPORT_t RXHUBPORTbits; + +} __USBHS_TARGET_ADDR_t; + +/* Set of registers that configure the DMA channel */ +typedef struct __attribute__((packed)) +{ + volatile __USBHS_DMACNTL_t DMACNTLbits; + volatile uint32_t DMAADDR; + volatile uint32_t DMACOUNT; + volatile uint32_t pad; +} __USBHS_DMA_CHANNEL_t; + +/* USBHS module register set */ +typedef struct __attribute__((aligned(4),packed)) +{ + volatile __USBHS_FADDR_t FADDRbits; + volatile __USBHS_POWER_t POWERbits; + volatile uint16_t INTRTX; + volatile uint16_t INTRRX; + volatile __USBHS_INTRTXE_t INTRTXEbits; + volatile __USBHS_INTRRXE_t INTRRXEbits; + volatile uint8_t INTRUSB; + volatile __USBHS_INTRUSBE_t INTRUSBEbits; + volatile __USBHS_FRAME_t FRAMEbits; + volatile __USBHS_INDEX_t INDEXbits; + volatile __USBHS_TESTMODE_t TESTMODEbits; + volatile __USBHS_EPCSR_t INDEXED_EPCSR; + volatile uint32_t FIFO[16]; + volatile __USBHS_DEVCTL_t DEVCTLbits; + volatile uint8_t MISC; + volatile __USBHS_TXFIFOSZ_t TXFIFOSZbits; + volatile __USBHS_RXFIFOSZ_t RXFIFOSZbits; + + volatile __USBHS_TXFIFOADD_t TXFIFOADDbits; + volatile __USBHS_RXFIFOADD_t RXFIFOADDbits; + + volatile uint32_t VCONTROL; + volatile uint16_t HWVERS; + volatile uint8_t padding1[10]; + volatile uint8_t EPINFO; + volatile uint8_t RAMINFO; + volatile uint8_t LINKINFO; + volatile uint8_t VPLEN; + volatile uint8_t HS_EOF1; + volatile uint8_t FS_EOF1; + volatile uint8_t LS_EOF1; + + volatile __USBHS_SOFTRST_t SOFTRSTbits; + + volatile __USBHS_TARGET_ADDR_t TADDR[16]; + volatile __USBHS_EPCSR_t EPCSR[16]; + volatile uint32_t DMA_INTR; + volatile __USBHS_DMA_CHANNEL_t DMA_CHANNEL[8]; + volatile uint32_t RQPKTXOUNT[16]; + +} usbhs_registers_t; + +#endif From 5f9e361f5cf2a8946b5bc4002dd7f5adac856f6c Mon Sep 17 00:00:00 2001 From: Meco Man <920369182@qq.com> Date: Sun, 2 Jan 2022 02:06:53 -0500 Subject: [PATCH 098/504] [rt-thread] add rt-thread os in readme --- README.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/README.rst b/README.rst index 03219db3f..faeef3663 100644 --- a/README.rst +++ b/README.rst @@ -90,6 +90,7 @@ TinyUSB is completely thread-safe by pushing all Interrupt Service Request (ISR) - **No OS** - **FreeRTOS** +- **RT-Thread** (https://github.com/tfx2001/tinyusb) - **Mynewt** Due to the newt package build system, Mynewt examples are better to be on its [own repo](https://github.com/hathach/mynewt-tinyusb-example) Local Docs From a79ffeb7643bb9c7e7af69f29fe2cfe7ded837d8 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 5 Jan 2022 13:47:01 -0800 Subject: [PATCH 099/504] Add Raspberry Pi Zero W and Zero 2 W These are different Broadcom chips. The peripherals are essentially the same. The main differences are: * The CPU(s) * The interrupt controller * The peripheral base address (but not the peripherals that we use) --- .../boards/raspberrypi_cm4/board.h | 0 .../bcm2835/boards/raspberrypi_cm4/board.mk | 9 +++++ .../bcm2835/boards/raspberrypi_zero2w/board.h | 38 +++++++++++++++++++ .../boards/raspberrypi_zero2w/board.mk | 9 +++++ .../bcm2835/boards/raspberrypi_zero_w/board.h | 38 +++++++++++++++++++ .../boards/raspberrypi_zero_w/board.mk | 7 ++++ hw/bsp/{raspberrypi4 => bcm2835}/family.c | 32 +++++++++++----- hw/bsp/{raspberrypi4 => bcm2835}/family.mk | 24 ++++-------- .../boards/raspberrypi_cm4/board.mk | 1 - hw/mcu/broadcom | 2 +- src/device/dcd_attr.h | 2 +- src/portable/synopsys/dwc2/dcd_dwc2.c | 5 ++- src/portable/synopsys/dwc2/dwc2_bcm.h | 3 +- src/tusb_option.h | 2 + 14 files changed, 139 insertions(+), 33 deletions(-) rename hw/bsp/{raspberrypi4 => bcm2835}/boards/raspberrypi_cm4/board.h (100%) create mode 100644 hw/bsp/bcm2835/boards/raspberrypi_cm4/board.mk create mode 100644 hw/bsp/bcm2835/boards/raspberrypi_zero2w/board.h create mode 100644 hw/bsp/bcm2835/boards/raspberrypi_zero2w/board.mk create mode 100644 hw/bsp/bcm2835/boards/raspberrypi_zero_w/board.h create mode 100644 hw/bsp/bcm2835/boards/raspberrypi_zero_w/board.mk rename hw/bsp/{raspberrypi4 => bcm2835}/family.c (82%) rename hw/bsp/{raspberrypi4 => bcm2835}/family.mk (61%) delete mode 100644 hw/bsp/raspberrypi4/boards/raspberrypi_cm4/board.mk diff --git a/hw/bsp/raspberrypi4/boards/raspberrypi_cm4/board.h b/hw/bsp/bcm2835/boards/raspberrypi_cm4/board.h similarity index 100% rename from hw/bsp/raspberrypi4/boards/raspberrypi_cm4/board.h rename to hw/bsp/bcm2835/boards/raspberrypi_cm4/board.h diff --git a/hw/bsp/bcm2835/boards/raspberrypi_cm4/board.mk b/hw/bsp/bcm2835/boards/raspberrypi_cm4/board.mk new file mode 100644 index 000000000..b4fa3dff6 --- /dev/null +++ b/hw/bsp/bcm2835/boards/raspberrypi_cm4/board.mk @@ -0,0 +1,9 @@ +CFLAGS += -mcpu=cortex-a72 \ + -DBCM_VERSION=2711 \ + -DCFG_TUSB_MCU=OPT_MCU_BCM2711 + +CROSS_COMPILE = aarch64-none-elf- + +SUFFIX = 8 + +INC += $(TOP)/lib/CMSIS_5/CMSIS/Core_A/Include diff --git a/hw/bsp/bcm2835/boards/raspberrypi_zero2w/board.h b/hw/bsp/bcm2835/boards/raspberrypi_zero2w/board.h new file mode 100644 index 000000000..1d3565d5c --- /dev/null +++ b/hw/bsp/bcm2835/boards/raspberrypi_zero2w/board.h @@ -0,0 +1,38 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, 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 BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/bcm2835/boards/raspberrypi_zero2w/board.mk b/hw/bsp/bcm2835/boards/raspberrypi_zero2w/board.mk new file mode 100644 index 000000000..f43e12e35 --- /dev/null +++ b/hw/bsp/bcm2835/boards/raspberrypi_zero2w/board.mk @@ -0,0 +1,9 @@ +CFLAGS += -mcpu=cortex-a53 \ + -DBCM_VERSION=2837 \ + -DCFG_TUSB_MCU=OPT_MCU_BCM2837 + +CROSS_COMPILE = aarch64-none-elf- + +SUFFIX = 8 + +INC += $(TOP)/lib/CMSIS_5/CMSIS/Core_A/Include diff --git a/hw/bsp/bcm2835/boards/raspberrypi_zero_w/board.h b/hw/bsp/bcm2835/boards/raspberrypi_zero_w/board.h new file mode 100644 index 000000000..1d3565d5c --- /dev/null +++ b/hw/bsp/bcm2835/boards/raspberrypi_zero_w/board.h @@ -0,0 +1,38 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, 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 BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/bcm2835/boards/raspberrypi_zero_w/board.mk b/hw/bsp/bcm2835/boards/raspberrypi_zero_w/board.mk new file mode 100644 index 000000000..79d7096ce --- /dev/null +++ b/hw/bsp/bcm2835/boards/raspberrypi_zero_w/board.mk @@ -0,0 +1,7 @@ +CFLAGS += -mcpu=arm1176jzf-s \ + -DBCM_VERSION=2835 \ + -DCFG_TUSB_MCU=OPT_MCU_BCM2835 + +CROSS_COMPILE = arm-none-eabi- + +SUFFIX = diff --git a/hw/bsp/raspberrypi4/family.c b/hw/bsp/bcm2835/family.c similarity index 82% rename from hw/bsp/raspberrypi4/family.c rename to hw/bsp/bcm2835/family.c index ba0b2700a..f7a11fb49 100644 --- a/hw/bsp/raspberrypi4/family.c +++ b/hw/bsp/bcm2835/family.c @@ -27,8 +27,9 @@ #include "bsp/board.h" #include "board.h" +#include "broadcom/cpu.h" +#include "broadcom/gpio.h" #include "broadcom/interrupts.h" -#include "broadcom/io.h" #include "broadcom/mmu.h" #include "broadcom/caches.h" #include "broadcom/vcmailbox.h" @@ -37,9 +38,8 @@ #define LED_PIN 18 #define LED_STATE_ON 1 -// Button -#define BUTTON_PIN 16 -#define BUTTON_STATE_ACTIVE 0 +// UART TX +#define UART_TX_PIN 14 //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler @@ -62,14 +62,26 @@ void board_init(void) init_caches(); // LED - gpio_initOutputPinWithPullNone(LED_PIN); + gpio_set_function(LED_PIN, GPIO_FUNCTION_OUTPUT); + gpio_set_pull(LED_PIN, BP_PULL_NONE); board_led_write(true); - // Button - // TODO - // Uart - uart_init(); + COMPLETE_MEMORY_READS; + AUX->ENABLES_b.UART_1 = true; + + UART1->IER = 0; + UART1->CNTL = 0; + UART1->LCR_b.DATA_SIZE = UART1_LCR_DATA_SIZE_MODE_8BIT; + UART1->MCR = 0; + UART1->IER = 0; + + uint32_t source_clock = vcmailbox_get_clock_rate_measured(VCMAILBOX_CLOCK_CORE); + UART1->BAUD = ((source_clock / (115200 * 8)) - 1); + UART1->CNTL |= UART1_CNTL_TX_ENABLE_Msk; + COMPLETE_MEMORY_READS; + + gpio_set_function(UART_TX_PIN, GPIO_FUNCTION_ALT5); // Turn on USB peripheral. vcmailbox_set_power_state(VCMAILBOX_DEVICE_USB_HCD, true); @@ -87,7 +99,7 @@ void board_init(void) void board_led_write(bool state) { - gpio_setPinOutputBool(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); + gpio_set_value(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); } uint32_t board_button_read(void) diff --git a/hw/bsp/raspberrypi4/family.mk b/hw/bsp/bcm2835/family.mk similarity index 61% rename from hw/bsp/raspberrypi4/family.mk rename to hw/bsp/bcm2835/family.mk index c65070a71..6de97f584 100644 --- a/hw/bsp/raspberrypi4/family.mk +++ b/hw/bsp/bcm2835/family.mk @@ -3,18 +3,14 @@ DEPS_SUBMODULES += $(MCU_DIR) include $(TOP)/$(BOARD_PATH)/board.mk -CC = clang - CFLAGS += \ - -mcpu=cortex-a72 \ -Wall \ -O0 \ -ffreestanding \ -nostdlib \ -nostartfiles \ - -std=c17 \ -mgeneral-regs-only \ - -DCFG_TUSB_MCU=OPT_MCU_BCM2711 + -std=c17 # mcu driver cause following warnings CFLAGS += -Wno-error=cast-qual @@ -22,30 +18,26 @@ CFLAGS += -Wno-error=cast-qual SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ $(MCU_DIR)/broadcom/gen/interrupt_handlers.c \ + $(MCU_DIR)/broadcom/gpio.c \ $(MCU_DIR)/broadcom/interrupts.c \ - $(MCU_DIR)/broadcom/io.c \ $(MCU_DIR)/broadcom/mmu.c \ $(MCU_DIR)/broadcom/caches.c \ $(MCU_DIR)/broadcom/vcmailbox.c - -CROSS_COMPILE = aarch64-none-elf- - SKIP_NANOLIB = 1 -LD_FILE = $(MCU_DIR)/broadcom/link.ld +LD_FILE = $(MCU_DIR)/broadcom/link$(SUFFIX).ld INC += \ $(TOP)/$(BOARD_PATH) \ - $(TOP)/$(MCU_DIR) \ - $(TOP)/lib/CMSIS_5/CMSIS/Core_A/Include + $(TOP)/$(MCU_DIR) -SRC_S += $(MCU_DIR)/broadcom/boot.S +SRC_S += $(MCU_DIR)/broadcom/boot$(SUFFIX).S -$(BUILD)/kernel8.img: $(BUILD)/$(PROJECT).elf +$(BUILD)/kernel$(SUFFIX).img: $(BUILD)/$(PROJECT).elf $(OBJCOPY) -O binary $^ $@ # Copy to kernel to netboot drive or SD card # Change destinaation to fit your need -flash: $(BUILD)/kernel8.img - $(CP) $< /home/$(USER)/Documents/code/pi4_tinyusb/boot_cpy +flash: $(BUILD)/kernel$(SUFFIX).img + @$(CP) $< /home/$(USER)/Documents/code/pi_tinyusb/boot_cpy diff --git a/hw/bsp/raspberrypi4/boards/raspberrypi_cm4/board.mk b/hw/bsp/raspberrypi4/boards/raspberrypi_cm4/board.mk deleted file mode 100644 index 897342479..000000000 --- a/hw/bsp/raspberrypi4/boards/raspberrypi_cm4/board.mk +++ /dev/null @@ -1 +0,0 @@ -CFLAGS += -DBCM_VERSION=2711 diff --git a/hw/mcu/broadcom b/hw/mcu/broadcom index 5bff1d5e0..083700860 160000 --- a/hw/mcu/broadcom +++ b/hw/mcu/broadcom @@ -1 +1 @@ -Subproject commit 5bff1d5e02c37c38ee1e5cf3f7fe82fdc7e1517e +Subproject commit 08370086080759ed54ac1136d62d2ad24c6fa267 diff --git a/src/device/dcd_attr.h b/src/device/dcd_attr.h index 3c5dadaf4..feba82ea9 100644 --- a/src/device/dcd_attr.h +++ b/src/device/dcd_attr.h @@ -190,7 +190,7 @@ #define DCD_ATTR_ENDPOINT_MAX 4 //------------- Broadcom -------------// -#elif TU_CHECK_MCU(OPT_MCU_BCM2711) +#elif TU_CHECK_MCU(OPT_MCU_BCM2711, OPT_MCU_BCM2835, OPT_MCU_BCM2837) #define DCD_ATTR_ENDPOINT_MAX 8 //------------- Broadcom -------------// diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index bb21b3dcd..188611743 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -33,7 +33,8 @@ #if TUSB_OPT_DEVICE_ENABLED && \ ( defined(DCD_ATTR_DWC2_STM32) || \ TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3, OPT_MCU_GD32VF103) || \ - TU_CHECK_MCU(OPT_MCU_EFM32GG, OPT_MCU_BCM2711, OPT_MCU_XMC4000) ) + TU_CHECK_MCU(OPT_MCU_EFM32GG, OPT_MCU_BCM2711, OPT_MCU_BCM2835) || \ + TU_CHECK_MCU(OPT_MCU_BCM2837, OPT_MCU_XMC4000) ) #include "device/dcd.h" #include "dwc2_type.h" @@ -44,7 +45,7 @@ #include "dwc2_esp32.h" #elif TU_CHECK_MCU(OPT_MCU_GD32VF103) #include "dwc2_gd32.h" -#elif TU_CHECK_MCU(OPT_MCU_BCM2711) +#elif TU_CHECK_MCU(OPT_MCU_BCM2711, OPT_MCU_BCM2835, OPT_MCU_BCM2837) #include "dwc2_bcm.h" #elif TU_CHECK_MCU(OPT_MCU_EFM32GG) #include "dwc2_efm32.h" diff --git a/src/portable/synopsys/dwc2/dwc2_bcm.h b/src/portable/synopsys/dwc2/dwc2_bcm.h index 353bc21ee..14194e754 100644 --- a/src/portable/synopsys/dwc2/dwc2_bcm.h +++ b/src/portable/synopsys/dwc2/dwc2_bcm.h @@ -31,6 +31,7 @@ extern "C" { #endif +#include "broadcom/defines.h" #include "broadcom/interrupts.h" #include "broadcom/caches.h" @@ -47,7 +48,6 @@ static inline void dwc2_dcd_int_enable(uint8_t rhport) { (void) rhport; BP_EnableIRQ(USB_IRQn); - __asm__ volatile("isb"); // needed if TIMER1 IRQ is not enabled !? } TU_ATTR_ALWAYS_INLINE @@ -55,7 +55,6 @@ static inline void dwc2_dcd_int_disable (uint8_t rhport) { (void) rhport; BP_DisableIRQ(USB_IRQn); - __asm__ volatile("isb"); // needed if TIMER1 IRQ is not enabled !? } static inline void dwc2_remote_wakeup_delay(void) diff --git a/src/tusb_option.h b/src/tusb_option.h index 2edd310fa..c7c7b2454 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -132,6 +132,8 @@ // Broadcom #define OPT_MCU_BCM2711 1700 ///< Broadcom BCM2711 +#define OPT_MCU_BCM2835 1701 ///< Broadcom BCM2835 +#define OPT_MCU_BCM2837 1702 ///< Broadcom BCM2837 // Infineon #define OPT_MCU_XMC4000 1800 ///< Infineon XMC4000 From 84e2df51be5961177a63c6842a4130bb9b8978ac Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 5 Jan 2022 14:11:39 -0800 Subject: [PATCH 100/504] Split by compiler for testing --- .github/workflows/build_aarch64.yml | 2 +- .github/workflows/build_arm.yml | 3 +- .../boards/raspberrypi_zero_w}/board.h | 0 .../boards/raspberrypi_zero_w/board.mk | 2 - hw/bsp/{bcm2835 => broadcom_32bit}/family.c | 0 hw/bsp/{bcm2835 => broadcom_32bit}/family.mk | 2 + .../boards/raspberrypi_cm4}/board.h | 0 .../boards/raspberrypi_cm4/board.mk | 6 - .../boards/raspberrypi_zero2w}/board.h | 0 .../boards/raspberrypi_zero2w/board.mk | 6 - hw/bsp/broadcom_64bit/family.c | 156 ++++++++++++++++++ hw/bsp/broadcom_64bit/family.mk | 46 ++++++ 12 files changed, 207 insertions(+), 16 deletions(-) rename hw/bsp/{bcm2835/boards/raspberrypi_cm4 => broadcom_32bit/boards/raspberrypi_zero_w}/board.h (100%) rename hw/bsp/{bcm2835 => broadcom_32bit}/boards/raspberrypi_zero_w/board.mk (78%) rename hw/bsp/{bcm2835 => broadcom_32bit}/family.c (100%) rename hw/bsp/{bcm2835 => broadcom_32bit}/family.mk (96%) rename hw/bsp/{bcm2835/boards/raspberrypi_zero2w => broadcom_64bit/boards/raspberrypi_cm4}/board.h (100%) rename hw/bsp/{bcm2835 => broadcom_64bit}/boards/raspberrypi_cm4/board.mk (51%) rename hw/bsp/{bcm2835/boards/raspberrypi_zero_w => broadcom_64bit/boards/raspberrypi_zero2w}/board.h (100%) rename hw/bsp/{bcm2835 => broadcom_64bit}/boards/raspberrypi_zero2w/board.mk (51%) create mode 100644 hw/bsp/broadcom_64bit/family.c create mode 100644 hw/bsp/broadcom_64bit/family.mk diff --git a/.github/workflows/build_aarch64.yml b/.github/workflows/build_aarch64.yml index 0cc7a5de1..8cf7852b9 100644 --- a/.github/workflows/build_aarch64.yml +++ b/.github/workflows/build_aarch64.yml @@ -18,7 +18,7 @@ jobs: matrix: family: # Alphabetical order - - 'raspberrypi4' + - 'broadcom_64bit' steps: - name: Setup Python uses: actions/setup-python@v2 diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml index dc4d9fcfb..177f1076e 100644 --- a/.github/workflows/build_arm.yml +++ b/.github/workflows/build_arm.yml @@ -39,6 +39,7 @@ jobs: matrix: family: # Alphabetical order + - 'broadcom_32bit' - 'imxrt' - 'lpc15' - 'lpc18' @@ -114,7 +115,7 @@ jobs: done # --------------------------------------- - # Build all no-family (opharned) boards + # Build all no-family (orphaned) boards # --------------------------------------- build-board: runs-on: ubuntu-latest diff --git a/hw/bsp/bcm2835/boards/raspberrypi_cm4/board.h b/hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.h similarity index 100% rename from hw/bsp/bcm2835/boards/raspberrypi_cm4/board.h rename to hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.h diff --git a/hw/bsp/bcm2835/boards/raspberrypi_zero_w/board.mk b/hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.mk similarity index 78% rename from hw/bsp/bcm2835/boards/raspberrypi_zero_w/board.mk rename to hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.mk index 79d7096ce..52e9e45c4 100644 --- a/hw/bsp/bcm2835/boards/raspberrypi_zero_w/board.mk +++ b/hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.mk @@ -2,6 +2,4 @@ CFLAGS += -mcpu=arm1176jzf-s \ -DBCM_VERSION=2835 \ -DCFG_TUSB_MCU=OPT_MCU_BCM2835 -CROSS_COMPILE = arm-none-eabi- - SUFFIX = diff --git a/hw/bsp/bcm2835/family.c b/hw/bsp/broadcom_32bit/family.c similarity index 100% rename from hw/bsp/bcm2835/family.c rename to hw/bsp/broadcom_32bit/family.c diff --git a/hw/bsp/bcm2835/family.mk b/hw/bsp/broadcom_32bit/family.mk similarity index 96% rename from hw/bsp/bcm2835/family.mk rename to hw/bsp/broadcom_32bit/family.mk index 6de97f584..4ff574744 100644 --- a/hw/bsp/bcm2835/family.mk +++ b/hw/bsp/broadcom_32bit/family.mk @@ -12,6 +12,8 @@ CFLAGS += \ -mgeneral-regs-only \ -std=c17 +CROSS_COMPILE = arm-none-eabi- + # mcu driver cause following warnings CFLAGS += -Wno-error=cast-qual diff --git a/hw/bsp/bcm2835/boards/raspberrypi_zero2w/board.h b/hw/bsp/broadcom_64bit/boards/raspberrypi_cm4/board.h similarity index 100% rename from hw/bsp/bcm2835/boards/raspberrypi_zero2w/board.h rename to hw/bsp/broadcom_64bit/boards/raspberrypi_cm4/board.h diff --git a/hw/bsp/bcm2835/boards/raspberrypi_cm4/board.mk b/hw/bsp/broadcom_64bit/boards/raspberrypi_cm4/board.mk similarity index 51% rename from hw/bsp/bcm2835/boards/raspberrypi_cm4/board.mk rename to hw/bsp/broadcom_64bit/boards/raspberrypi_cm4/board.mk index b4fa3dff6..5706b8318 100644 --- a/hw/bsp/bcm2835/boards/raspberrypi_cm4/board.mk +++ b/hw/bsp/broadcom_64bit/boards/raspberrypi_cm4/board.mk @@ -1,9 +1,3 @@ CFLAGS += -mcpu=cortex-a72 \ -DBCM_VERSION=2711 \ -DCFG_TUSB_MCU=OPT_MCU_BCM2711 - -CROSS_COMPILE = aarch64-none-elf- - -SUFFIX = 8 - -INC += $(TOP)/lib/CMSIS_5/CMSIS/Core_A/Include diff --git a/hw/bsp/bcm2835/boards/raspberrypi_zero_w/board.h b/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2w/board.h similarity index 100% rename from hw/bsp/bcm2835/boards/raspberrypi_zero_w/board.h rename to hw/bsp/broadcom_64bit/boards/raspberrypi_zero2w/board.h diff --git a/hw/bsp/bcm2835/boards/raspberrypi_zero2w/board.mk b/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2w/board.mk similarity index 51% rename from hw/bsp/bcm2835/boards/raspberrypi_zero2w/board.mk rename to hw/bsp/broadcom_64bit/boards/raspberrypi_zero2w/board.mk index f43e12e35..3060b0571 100644 --- a/hw/bsp/bcm2835/boards/raspberrypi_zero2w/board.mk +++ b/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2w/board.mk @@ -1,9 +1,3 @@ CFLAGS += -mcpu=cortex-a53 \ -DBCM_VERSION=2837 \ -DCFG_TUSB_MCU=OPT_MCU_BCM2837 - -CROSS_COMPILE = aarch64-none-elf- - -SUFFIX = 8 - -INC += $(TOP)/lib/CMSIS_5/CMSIS/Core_A/Include diff --git a/hw/bsp/broadcom_64bit/family.c b/hw/bsp/broadcom_64bit/family.c new file mode 100644 index 000000000..f7a11fb49 --- /dev/null +++ b/hw/bsp/broadcom_64bit/family.c @@ -0,0 +1,156 @@ +/* + * 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. + */ + +#include "bsp/board.h" +#include "board.h" + +#include "broadcom/cpu.h" +#include "broadcom/gpio.h" +#include "broadcom/interrupts.h" +#include "broadcom/mmu.h" +#include "broadcom/caches.h" +#include "broadcom/vcmailbox.h" + +// LED +#define LED_PIN 18 +#define LED_STATE_ON 1 + +// UART TX +#define UART_TX_PIN 14 + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void USB_IRQHandler(void) +{ + tud_int_handler(0); +} + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ +void board_init(void) +{ + setup_mmu_flat_map(); + init_caches(); + + // LED + gpio_set_function(LED_PIN, GPIO_FUNCTION_OUTPUT); + gpio_set_pull(LED_PIN, BP_PULL_NONE); + board_led_write(true); + + // Uart + COMPLETE_MEMORY_READS; + AUX->ENABLES_b.UART_1 = true; + + UART1->IER = 0; + UART1->CNTL = 0; + UART1->LCR_b.DATA_SIZE = UART1_LCR_DATA_SIZE_MODE_8BIT; + UART1->MCR = 0; + UART1->IER = 0; + + uint32_t source_clock = vcmailbox_get_clock_rate_measured(VCMAILBOX_CLOCK_CORE); + UART1->BAUD = ((source_clock / (115200 * 8)) - 1); + UART1->CNTL |= UART1_CNTL_TX_ENABLE_Msk; + COMPLETE_MEMORY_READS; + + gpio_set_function(UART_TX_PIN, GPIO_FUNCTION_ALT5); + + // Turn on USB peripheral. + vcmailbox_set_power_state(VCMAILBOX_DEVICE_USB_HCD, true); + + // Timer 1/1024 second tick + SYSTMR->CS_b.M1 = 1; + SYSTMR->C1 = SYSTMR->CLO + 977; + BP_EnableIRQ(TIMER_1_IRQn); + + BP_SetPriority(USB_IRQn, 0x00); + BP_ClearPendingIRQ(USB_IRQn); + BP_EnableIRQ(USB_IRQn); + BP_EnableIRQs(); +} + +void board_led_write(bool state) +{ + gpio_set_value(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +} + +uint32_t board_button_read(void) +{ + return 0; +} + +int board_uart_read(uint8_t* buf, int len) +{ + (void) buf; (void) len; + return 0; +} + +int board_uart_write(void const * buf, int len) +{ + for (int i = 0; i < len; i++) { + const char* cbuf = buf; + while (!UART1->STAT_b.TX_READY) {} + if (cbuf[i] == '\n') { + UART1->IO = '\r'; + while (!UART1->STAT_b.TX_READY) {} + } + UART1->IO = cbuf[i]; + } + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; + +void TIMER_1_IRQHandler(void) +{ + system_ticks++; + SYSTMR->C1 += 977; + SYSTMR->CS_b.M1 = 1; +} + +uint32_t board_millis(void) +{ + return system_ticks; +} +#endif + +void HardFault_Handler (void) +{ + // asm("bkpt"); +} + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void) +{ + +} diff --git a/hw/bsp/broadcom_64bit/family.mk b/hw/bsp/broadcom_64bit/family.mk new file mode 100644 index 000000000..723926734 --- /dev/null +++ b/hw/bsp/broadcom_64bit/family.mk @@ -0,0 +1,46 @@ +MCU_DIR = hw/mcu/broadcom +DEPS_SUBMODULES += $(MCU_DIR) + +include $(TOP)/$(BOARD_PATH)/board.mk + +CFLAGS += \ + -Wall \ + -O0 \ + -ffreestanding \ + -nostdlib \ + -nostartfiles \ + -mgeneral-regs-only \ + -std=c17 + +CROSS_COMPILE = aarch64-none-elf- + +# mcu driver cause following warnings +CFLAGS += -Wno-error=cast-qual + +SRC_C += \ + src/portable/synopsys/dwc2/dcd_dwc2.c \ + $(MCU_DIR)/broadcom/gen/interrupt_handlers.c \ + $(MCU_DIR)/broadcom/gpio.c \ + $(MCU_DIR)/broadcom/interrupts.c \ + $(MCU_DIR)/broadcom/mmu.c \ + $(MCU_DIR)/broadcom/caches.c \ + $(MCU_DIR)/broadcom/vcmailbox.c + +SKIP_NANOLIB = 1 + +LD_FILE = $(MCU_DIR)/broadcom/link8.ld + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/$(MCU_DIR) \ + $(TOP)/lib/CMSIS_5/CMSIS/Core_A/Include + +SRC_S += $(MCU_DIR)/broadcom/boot8.S + +$(BUILD)/kernel8.img: $(BUILD)/$(PROJECT).elf + $(OBJCOPY) -O binary $^ $@ + +# Copy to kernel to netboot drive or SD card +# Change destinaation to fit your need +flash: $(BUILD)/kernel8.img + @$(CP) $< /home/$(USER)/Documents/code/pi_tinyusb/boot_cpy From 4fe0a30ec7bf254c839a76da9be3a2968d1690db Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 5 Jan 2022 14:33:24 -0800 Subject: [PATCH 101/504] Skip net and freertos examples --- examples/device/cdc_msc_freertos/.skip.MCU_BCM2835 | 0 examples/device/cdc_msc_freertos/.skip.MCU_BCM2837 | 0 examples/device/hid_composite_freertos/.skip.MCU_BCM2835 | 0 examples/device/hid_composite_freertos/.skip.MCU_BCM2837 | 0 examples/device/net_lwip_webserver/.skip.MCU_BCM2835 | 1 + examples/device/net_lwip_webserver/.skip.MCU_BCM2837 | 1 + hw/bsp/board_mcu.h | 5 ++++- tools/build_family.py | 2 +- 8 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 examples/device/cdc_msc_freertos/.skip.MCU_BCM2835 create mode 100644 examples/device/cdc_msc_freertos/.skip.MCU_BCM2837 create mode 100644 examples/device/hid_composite_freertos/.skip.MCU_BCM2835 create mode 100644 examples/device/hid_composite_freertos/.skip.MCU_BCM2837 create mode 100644 examples/device/net_lwip_webserver/.skip.MCU_BCM2835 create mode 100644 examples/device/net_lwip_webserver/.skip.MCU_BCM2837 diff --git a/examples/device/cdc_msc_freertos/.skip.MCU_BCM2835 b/examples/device/cdc_msc_freertos/.skip.MCU_BCM2835 new file mode 100644 index 000000000..e69de29bb diff --git a/examples/device/cdc_msc_freertos/.skip.MCU_BCM2837 b/examples/device/cdc_msc_freertos/.skip.MCU_BCM2837 new file mode 100644 index 000000000..e69de29bb diff --git a/examples/device/hid_composite_freertos/.skip.MCU_BCM2835 b/examples/device/hid_composite_freertos/.skip.MCU_BCM2835 new file mode 100644 index 000000000..e69de29bb diff --git a/examples/device/hid_composite_freertos/.skip.MCU_BCM2837 b/examples/device/hid_composite_freertos/.skip.MCU_BCM2837 new file mode 100644 index 000000000..e69de29bb diff --git a/examples/device/net_lwip_webserver/.skip.MCU_BCM2835 b/examples/device/net_lwip_webserver/.skip.MCU_BCM2835 new file mode 100644 index 000000000..bdc68f5db --- /dev/null +++ b/examples/device/net_lwip_webserver/.skip.MCU_BCM2835 @@ -0,0 +1 @@ +tinyusb/lib/lwip/src/include/lwip/arch.h:202:13: error: conflicting types for 'ssize_t' \ No newline at end of file diff --git a/examples/device/net_lwip_webserver/.skip.MCU_BCM2837 b/examples/device/net_lwip_webserver/.skip.MCU_BCM2837 new file mode 100644 index 000000000..bdc68f5db --- /dev/null +++ b/examples/device/net_lwip_webserver/.skip.MCU_BCM2837 @@ -0,0 +1 @@ +tinyusb/lib/lwip/src/include/lwip/arch.h:202:13: error: conflicting types for 'ssize_t' \ No newline at end of file diff --git a/hw/bsp/board_mcu.h b/hw/bsp/board_mcu.h index f8b5c061c..b911e1e53 100644 --- a/hw/bsp/board_mcu.h +++ b/hw/bsp/board_mcu.h @@ -32,7 +32,7 @@ //--------------------------------------------------------------------+ // Low Level MCU header include. TinyUSB stack and example should be -// platform independent and mostly doens't need to include this file. +// platform independent and mostly doesn't need to include this file. // However there are still certain situation where this file is needed: // - FreeRTOSConfig.h to set up correct clock and NVIC interrupts for ARM Cortex // - SWO logging for Cortex M with ITM_SendChar() / ITM_ReceiveChar() @@ -146,6 +146,9 @@ #elif CFG_TUSB_MCU == OPT_MCU_TM4C123 #include "TM4C123.h" +#elif TU_CHECK_MCU(OPT_MCU_BCM2711, OPT_MCU_BCM2835, OPT_MCU_BCM2837) + // no header needed + #else #error "Missing MCU header" #endif diff --git a/tools/build_family.py b/tools/build_family.py index 4195c259b..ccbcfa3f8 100644 --- a/tools/build_family.py +++ b/tools/build_family.py @@ -38,7 +38,7 @@ all_examples.sort() # If family are not specified in arguments, build all all_families = [] for entry in os.scandir("hw/bsp"): - if entry.is_dir() and os.path.isdir(entry.path + "/boards") and entry.name != "esp32s2" and entry.name != "esp32s3": + if entry.is_dir() and os.path.isdir(entry.path + "/boards") and entry.name not in ("esp32s2", "esp32s3"): all_families.append(entry.name) filter_with_input(all_families) From 7b27b8f498a185d8a7c1bea5dac8f43e7030ebd7 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 5 Jan 2022 15:44:23 -0800 Subject: [PATCH 102/504] Unify skip and only logic for build scripts And switch to a single file that can include mcu, family or board. --- .gitignore | 2 + .../audio_4_channel_mic/.skip.MCU_SAMD11 | 0 .../audio_4_channel_mic/.skip.MCU_SAME5X | 0 .../device/audio_4_channel_mic/.skip.MCU_SAMG | 0 examples/device/audio_4_channel_mic/skip.txt | 3 + examples/device/audio_test/.skip.MCU_SAMD11 | 0 examples/device/audio_test/.skip.MCU_SAME5X | 0 examples/device/audio_test/.skip.MCU_SAMG | 0 examples/device/audio_test/skip.txt | 3 + examples/device/cdc_msc/.skip.MCU_SAMD11 | 0 examples/device/cdc_msc/skip.txt | 1 + .../device/cdc_msc_freertos/.skip.MCU_BCM2711 | 0 .../device/cdc_msc_freertos/.skip.MCU_BCM2835 | 0 .../device/cdc_msc_freertos/.skip.MCU_BCM2837 | 0 .../device/cdc_msc_freertos/.skip.MCU_CXD56 | 0 .../cdc_msc_freertos/.skip.MCU_GD32VF103 | 0 .../cdc_msc_freertos/.skip.MCU_MKL25ZXX | 0 .../cdc_msc_freertos/.skip.MCU_MSP430x5xx | 0 .../device/cdc_msc_freertos/.skip.MCU_RP2040 | 0 .../device/cdc_msc_freertos/.skip.MCU_SAMD11 | 0 .../device/cdc_msc_freertos/.skip.MCU_SAMX7X | 0 .../.skip.MCU_VALENTYUSB_EPTRI | 0 examples/device/cdc_msc_freertos/skip.txt | 10 +++ examples/device/dfu/.skip.MCU_TM4C123 | 4 -- examples/device/dfu/skip.txt | 1 + .../dynamic_configuration/.skip.MCU_SAMD11 | 0 .../device/dynamic_configuration/skip.txt | 1 + .../hid_composite_freertos/.skip.MCU_BCM2711 | 0 .../hid_composite_freertos/.skip.MCU_BCM2835 | 0 .../hid_composite_freertos/.skip.MCU_BCM2837 | 0 .../hid_composite_freertos/.skip.MCU_CXD56 | 0 .../.skip.MCU_GD32VF103 | 0 .../.skip.MCU_MSP430x5xx | 0 .../hid_composite_freertos/.skip.MCU_RP2040 | 0 .../hid_composite_freertos/.skip.MCU_SAMD11 | 0 .../hid_composite_freertos/.skip.MCU_SAMX7X | 0 .../.skip.MCU_VALENTYUSB_EPTRI | 0 .../device/hid_composite_freertos/skip.txt | 9 +++ .../device/msc_dual_lun/.skip.MCU_MKL25ZXX | 0 examples/device/msc_dual_lun/.skip.MCU_SAMD11 | 0 examples/device/msc_dual_lun/skip.txt | 2 + .../net_lwip_webserver/.skip.MCU_BCM2711 | 1 - .../net_lwip_webserver/.skip.MCU_BCM2835 | 1 - .../net_lwip_webserver/.skip.MCU_BCM2837 | 1 - .../net_lwip_webserver/.skip.MCU_LPC11UXX | 0 .../net_lwip_webserver/.skip.MCU_LPC13XX | 0 .../net_lwip_webserver/.skip.MCU_MKL25ZXX | 0 .../net_lwip_webserver/.skip.MCU_MSP430x5xx | 1 - .../net_lwip_webserver/.skip.MCU_NUC121 | 0 .../net_lwip_webserver/.skip.MCU_SAMD11 | 0 .../net_lwip_webserver/.skip.MCU_STM32L0 | 0 examples/device/net_lwip_webserver/skip.txt | 10 +++ .../device/uac2_headset/.skip.MCU_LPC11UXX | 0 .../device/uac2_headset/.skip.MCU_LPC13XX | 0 examples/device/uac2_headset/.skip.MCU_NUC121 | 0 examples/device/uac2_headset/.skip.MCU_SAMD11 | 0 examples/device/uac2_headset/.skip.MCU_SAME5X | 0 examples/device/uac2_headset/.skip.MCU_SAMG | 0 examples/device/uac2_headset/skip.txt | 6 ++ .../device/video_capture/.skip.MCU_MSP430x5xx | 1 - .../device/video_capture/.skip.MCU_SAMD11 | 0 examples/device/video_capture/skip.txt | 2 + .../host/cdc_msc_hid/.only.MCU_LPC175X_6X | 0 .../host/cdc_msc_hid/.only.MCU_LPC177X_8X | 0 examples/host/cdc_msc_hid/.only.MCU_LPC18XX | 0 examples/host/cdc_msc_hid/.only.MCU_LPC40XX | 0 examples/host/cdc_msc_hid/.only.MCU_LPC43XX | 0 .../host/cdc_msc_hid/.only.MCU_MIMXRT10XX | 0 examples/host/cdc_msc_hid/.only.MCU_MSP432E4 | 0 examples/host/cdc_msc_hid/.only.MCU_RP2040 | 0 examples/host/cdc_msc_hid/only.txt | 8 +++ .../host/hid_controller/.only.MCU_LPC175X_6X | 0 .../host/hid_controller/.only.MCU_LPC177X_8X | 0 .../host/hid_controller/.only.MCU_LPC18XX | 0 .../host/hid_controller/.only.MCU_LPC40XX | 0 .../host/hid_controller/.only.MCU_LPC43XX | 0 .../host/hid_controller/.only.MCU_MIMXRT10XX | 0 .../host/hid_controller/.only.MCU_MSP432E4 | 0 examples/host/hid_controller/.only.MCU_RP2040 | 0 examples/host/hid_controller/only.txt | 8 +++ .../.skip.device.net_lwip_webserver | 0 tools/build_board.py | 31 +--------- tools/build_esp32sx.py | 7 +-- tools/build_family.py | 44 +------------ tools/build_utils.py | 61 +++++++++++++++++++ 85 files changed, 136 insertions(+), 82 deletions(-) delete mode 100644 examples/device/audio_4_channel_mic/.skip.MCU_SAMD11 delete mode 100644 examples/device/audio_4_channel_mic/.skip.MCU_SAME5X delete mode 100644 examples/device/audio_4_channel_mic/.skip.MCU_SAMG create mode 100644 examples/device/audio_4_channel_mic/skip.txt delete mode 100644 examples/device/audio_test/.skip.MCU_SAMD11 delete mode 100644 examples/device/audio_test/.skip.MCU_SAME5X delete mode 100644 examples/device/audio_test/.skip.MCU_SAMG create mode 100644 examples/device/audio_test/skip.txt delete mode 100644 examples/device/cdc_msc/.skip.MCU_SAMD11 create mode 100644 examples/device/cdc_msc/skip.txt delete mode 100644 examples/device/cdc_msc_freertos/.skip.MCU_BCM2711 delete mode 100644 examples/device/cdc_msc_freertos/.skip.MCU_BCM2835 delete mode 100644 examples/device/cdc_msc_freertos/.skip.MCU_BCM2837 delete mode 100644 examples/device/cdc_msc_freertos/.skip.MCU_CXD56 delete mode 100644 examples/device/cdc_msc_freertos/.skip.MCU_GD32VF103 delete mode 100644 examples/device/cdc_msc_freertos/.skip.MCU_MKL25ZXX delete mode 100644 examples/device/cdc_msc_freertos/.skip.MCU_MSP430x5xx delete mode 100644 examples/device/cdc_msc_freertos/.skip.MCU_RP2040 delete mode 100644 examples/device/cdc_msc_freertos/.skip.MCU_SAMD11 delete mode 100644 examples/device/cdc_msc_freertos/.skip.MCU_SAMX7X delete mode 100644 examples/device/cdc_msc_freertos/.skip.MCU_VALENTYUSB_EPTRI create mode 100644 examples/device/cdc_msc_freertos/skip.txt delete mode 100644 examples/device/dfu/.skip.MCU_TM4C123 create mode 100644 examples/device/dfu/skip.txt delete mode 100644 examples/device/dynamic_configuration/.skip.MCU_SAMD11 create mode 100644 examples/device/dynamic_configuration/skip.txt delete mode 100644 examples/device/hid_composite_freertos/.skip.MCU_BCM2711 delete mode 100644 examples/device/hid_composite_freertos/.skip.MCU_BCM2835 delete mode 100644 examples/device/hid_composite_freertos/.skip.MCU_BCM2837 delete mode 100644 examples/device/hid_composite_freertos/.skip.MCU_CXD56 delete mode 100644 examples/device/hid_composite_freertos/.skip.MCU_GD32VF103 delete mode 100644 examples/device/hid_composite_freertos/.skip.MCU_MSP430x5xx delete mode 100644 examples/device/hid_composite_freertos/.skip.MCU_RP2040 delete mode 100644 examples/device/hid_composite_freertos/.skip.MCU_SAMD11 delete mode 100644 examples/device/hid_composite_freertos/.skip.MCU_SAMX7X delete mode 100644 examples/device/hid_composite_freertos/.skip.MCU_VALENTYUSB_EPTRI create mode 100644 examples/device/hid_composite_freertos/skip.txt delete mode 100644 examples/device/msc_dual_lun/.skip.MCU_MKL25ZXX delete mode 100644 examples/device/msc_dual_lun/.skip.MCU_SAMD11 create mode 100644 examples/device/msc_dual_lun/skip.txt delete mode 100644 examples/device/net_lwip_webserver/.skip.MCU_BCM2711 delete mode 100644 examples/device/net_lwip_webserver/.skip.MCU_BCM2835 delete mode 100644 examples/device/net_lwip_webserver/.skip.MCU_BCM2837 delete mode 100644 examples/device/net_lwip_webserver/.skip.MCU_LPC11UXX delete mode 100644 examples/device/net_lwip_webserver/.skip.MCU_LPC13XX delete mode 100644 examples/device/net_lwip_webserver/.skip.MCU_MKL25ZXX delete mode 100644 examples/device/net_lwip_webserver/.skip.MCU_MSP430x5xx delete mode 100644 examples/device/net_lwip_webserver/.skip.MCU_NUC121 delete mode 100644 examples/device/net_lwip_webserver/.skip.MCU_SAMD11 delete mode 100644 examples/device/net_lwip_webserver/.skip.MCU_STM32L0 create mode 100644 examples/device/net_lwip_webserver/skip.txt delete mode 100644 examples/device/uac2_headset/.skip.MCU_LPC11UXX delete mode 100644 examples/device/uac2_headset/.skip.MCU_LPC13XX delete mode 100644 examples/device/uac2_headset/.skip.MCU_NUC121 delete mode 100644 examples/device/uac2_headset/.skip.MCU_SAMD11 delete mode 100644 examples/device/uac2_headset/.skip.MCU_SAME5X delete mode 100644 examples/device/uac2_headset/.skip.MCU_SAMG create mode 100644 examples/device/uac2_headset/skip.txt delete mode 100644 examples/device/video_capture/.skip.MCU_MSP430x5xx delete mode 100644 examples/device/video_capture/.skip.MCU_SAMD11 create mode 100644 examples/device/video_capture/skip.txt delete mode 100644 examples/host/cdc_msc_hid/.only.MCU_LPC175X_6X delete mode 100644 examples/host/cdc_msc_hid/.only.MCU_LPC177X_8X delete mode 100644 examples/host/cdc_msc_hid/.only.MCU_LPC18XX delete mode 100644 examples/host/cdc_msc_hid/.only.MCU_LPC40XX delete mode 100644 examples/host/cdc_msc_hid/.only.MCU_LPC43XX delete mode 100644 examples/host/cdc_msc_hid/.only.MCU_MIMXRT10XX delete mode 100644 examples/host/cdc_msc_hid/.only.MCU_MSP432E4 delete mode 100644 examples/host/cdc_msc_hid/.only.MCU_RP2040 create mode 100644 examples/host/cdc_msc_hid/only.txt delete mode 100644 examples/host/hid_controller/.only.MCU_LPC175X_6X delete mode 100644 examples/host/hid_controller/.only.MCU_LPC177X_8X delete mode 100644 examples/host/hid_controller/.only.MCU_LPC18XX delete mode 100644 examples/host/hid_controller/.only.MCU_LPC40XX delete mode 100644 examples/host/hid_controller/.only.MCU_LPC43XX delete mode 100644 examples/host/hid_controller/.only.MCU_MIMXRT10XX delete mode 100644 examples/host/hid_controller/.only.MCU_MSP432E4 delete mode 100644 examples/host/hid_controller/.only.MCU_RP2040 create mode 100644 examples/host/hid_controller/only.txt delete mode 100644 hw/bsp/samd21/boards/curiosity_nano/.skip.device.net_lwip_webserver create mode 100644 tools/build_utils.py diff --git a/.gitignore b/.gitignore index f7adff4c9..87a5faa80 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,5 @@ cov-int # cppcheck build directories *-build-dir /_bin/ +__pycache__ + diff --git a/examples/device/audio_4_channel_mic/.skip.MCU_SAMD11 b/examples/device/audio_4_channel_mic/.skip.MCU_SAMD11 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/audio_4_channel_mic/.skip.MCU_SAME5X b/examples/device/audio_4_channel_mic/.skip.MCU_SAME5X deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/audio_4_channel_mic/.skip.MCU_SAMG b/examples/device/audio_4_channel_mic/.skip.MCU_SAMG deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/audio_4_channel_mic/skip.txt b/examples/device/audio_4_channel_mic/skip.txt new file mode 100644 index 000000000..ae9b57f1f --- /dev/null +++ b/examples/device/audio_4_channel_mic/skip.txt @@ -0,0 +1,3 @@ +mcu:SAMD11 +mcu:SAME5X +mcu:SAMG \ No newline at end of file diff --git a/examples/device/audio_test/.skip.MCU_SAMD11 b/examples/device/audio_test/.skip.MCU_SAMD11 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/audio_test/.skip.MCU_SAME5X b/examples/device/audio_test/.skip.MCU_SAME5X deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/audio_test/.skip.MCU_SAMG b/examples/device/audio_test/.skip.MCU_SAMG deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/audio_test/skip.txt b/examples/device/audio_test/skip.txt new file mode 100644 index 000000000..ae9b57f1f --- /dev/null +++ b/examples/device/audio_test/skip.txt @@ -0,0 +1,3 @@ +mcu:SAMD11 +mcu:SAME5X +mcu:SAMG \ No newline at end of file diff --git a/examples/device/cdc_msc/.skip.MCU_SAMD11 b/examples/device/cdc_msc/.skip.MCU_SAMD11 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/cdc_msc/skip.txt b/examples/device/cdc_msc/skip.txt new file mode 100644 index 000000000..d844feae8 --- /dev/null +++ b/examples/device/cdc_msc/skip.txt @@ -0,0 +1 @@ +mcu:SAMD11 \ No newline at end of file diff --git a/examples/device/cdc_msc_freertos/.skip.MCU_BCM2711 b/examples/device/cdc_msc_freertos/.skip.MCU_BCM2711 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/cdc_msc_freertos/.skip.MCU_BCM2835 b/examples/device/cdc_msc_freertos/.skip.MCU_BCM2835 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/cdc_msc_freertos/.skip.MCU_BCM2837 b/examples/device/cdc_msc_freertos/.skip.MCU_BCM2837 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/cdc_msc_freertos/.skip.MCU_CXD56 b/examples/device/cdc_msc_freertos/.skip.MCU_CXD56 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/cdc_msc_freertos/.skip.MCU_GD32VF103 b/examples/device/cdc_msc_freertos/.skip.MCU_GD32VF103 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/cdc_msc_freertos/.skip.MCU_MKL25ZXX b/examples/device/cdc_msc_freertos/.skip.MCU_MKL25ZXX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/cdc_msc_freertos/.skip.MCU_MSP430x5xx b/examples/device/cdc_msc_freertos/.skip.MCU_MSP430x5xx deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/cdc_msc_freertos/.skip.MCU_RP2040 b/examples/device/cdc_msc_freertos/.skip.MCU_RP2040 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/cdc_msc_freertos/.skip.MCU_SAMD11 b/examples/device/cdc_msc_freertos/.skip.MCU_SAMD11 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/cdc_msc_freertos/.skip.MCU_SAMX7X b/examples/device/cdc_msc_freertos/.skip.MCU_SAMX7X deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/cdc_msc_freertos/.skip.MCU_VALENTYUSB_EPTRI b/examples/device/cdc_msc_freertos/.skip.MCU_VALENTYUSB_EPTRI deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/cdc_msc_freertos/skip.txt b/examples/device/cdc_msc_freertos/skip.txt new file mode 100644 index 000000000..7137b78af --- /dev/null +++ b/examples/device/cdc_msc_freertos/skip.txt @@ -0,0 +1,10 @@ +mcu:CXD56 +mcu:MSP430x5xx +mcu:SAMD11 +mcu:VALENTYUSB_EPTRI +mcu:MKL25ZXX +mcu:RP2040 +mcu:SAMX7X +mcu:GD32VF103 +family:broadcom_64bit +family:broadcom_32bit \ No newline at end of file diff --git a/examples/device/dfu/.skip.MCU_TM4C123 b/examples/device/dfu/.skip.MCU_TM4C123 deleted file mode 100644 index 6260e6e25..000000000 --- a/examples/device/dfu/.skip.MCU_TM4C123 +++ /dev/null @@ -1,4 +0,0 @@ -LINK _build/ek-tm4c123gxl/dfu.elf -/home/runner/cache/toolchain/xpack-arm-none-eabi-gcc-10.2.1-1.1/bin/../lib/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/bin/ld: section .ARM.exidx.text._close LMA [0000000000002980,0000000000002987] overlaps section .data LMA [0000000000002980,0000000000002a03] -collect2: error: ld returned 1 exit status -make: *** [../../rules.mk:94: _build/ek-tm4c123gxl/dfu.elf] Error 1 \ No newline at end of file diff --git a/examples/device/dfu/skip.txt b/examples/device/dfu/skip.txt new file mode 100644 index 000000000..2c9d94902 --- /dev/null +++ b/examples/device/dfu/skip.txt @@ -0,0 +1 @@ +mcu:TM4C123 \ No newline at end of file diff --git a/examples/device/dynamic_configuration/.skip.MCU_SAMD11 b/examples/device/dynamic_configuration/.skip.MCU_SAMD11 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/dynamic_configuration/skip.txt b/examples/device/dynamic_configuration/skip.txt new file mode 100644 index 000000000..d844feae8 --- /dev/null +++ b/examples/device/dynamic_configuration/skip.txt @@ -0,0 +1 @@ +mcu:SAMD11 \ No newline at end of file diff --git a/examples/device/hid_composite_freertos/.skip.MCU_BCM2711 b/examples/device/hid_composite_freertos/.skip.MCU_BCM2711 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/hid_composite_freertos/.skip.MCU_BCM2835 b/examples/device/hid_composite_freertos/.skip.MCU_BCM2835 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/hid_composite_freertos/.skip.MCU_BCM2837 b/examples/device/hid_composite_freertos/.skip.MCU_BCM2837 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/hid_composite_freertos/.skip.MCU_CXD56 b/examples/device/hid_composite_freertos/.skip.MCU_CXD56 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/hid_composite_freertos/.skip.MCU_GD32VF103 b/examples/device/hid_composite_freertos/.skip.MCU_GD32VF103 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/hid_composite_freertos/.skip.MCU_MSP430x5xx b/examples/device/hid_composite_freertos/.skip.MCU_MSP430x5xx deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/hid_composite_freertos/.skip.MCU_RP2040 b/examples/device/hid_composite_freertos/.skip.MCU_RP2040 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/hid_composite_freertos/.skip.MCU_SAMD11 b/examples/device/hid_composite_freertos/.skip.MCU_SAMD11 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/hid_composite_freertos/.skip.MCU_SAMX7X b/examples/device/hid_composite_freertos/.skip.MCU_SAMX7X deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/hid_composite_freertos/.skip.MCU_VALENTYUSB_EPTRI b/examples/device/hid_composite_freertos/.skip.MCU_VALENTYUSB_EPTRI deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/hid_composite_freertos/skip.txt b/examples/device/hid_composite_freertos/skip.txt new file mode 100644 index 000000000..e64187fd4 --- /dev/null +++ b/examples/device/hid_composite_freertos/skip.txt @@ -0,0 +1,9 @@ +mcu:CXD56 +mcu:MSP430x5xx +mcu:SAMD11 +mcu:VALENTYUSB_EPTRI +mcu:RP2040 +mcu:SAMX7X +mcu:GD32VF103 +family:broadcom_64bit +family:broadcom_32bit \ No newline at end of file diff --git a/examples/device/msc_dual_lun/.skip.MCU_MKL25ZXX b/examples/device/msc_dual_lun/.skip.MCU_MKL25ZXX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/msc_dual_lun/.skip.MCU_SAMD11 b/examples/device/msc_dual_lun/.skip.MCU_SAMD11 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/msc_dual_lun/skip.txt b/examples/device/msc_dual_lun/skip.txt new file mode 100644 index 000000000..3549c702a --- /dev/null +++ b/examples/device/msc_dual_lun/skip.txt @@ -0,0 +1,2 @@ +mcu:SAMD11 +mcu:MKL25ZXX \ No newline at end of file diff --git a/examples/device/net_lwip_webserver/.skip.MCU_BCM2711 b/examples/device/net_lwip_webserver/.skip.MCU_BCM2711 deleted file mode 100644 index bdc68f5db..000000000 --- a/examples/device/net_lwip_webserver/.skip.MCU_BCM2711 +++ /dev/null @@ -1 +0,0 @@ -tinyusb/lib/lwip/src/include/lwip/arch.h:202:13: error: conflicting types for 'ssize_t' \ No newline at end of file diff --git a/examples/device/net_lwip_webserver/.skip.MCU_BCM2835 b/examples/device/net_lwip_webserver/.skip.MCU_BCM2835 deleted file mode 100644 index bdc68f5db..000000000 --- a/examples/device/net_lwip_webserver/.skip.MCU_BCM2835 +++ /dev/null @@ -1 +0,0 @@ -tinyusb/lib/lwip/src/include/lwip/arch.h:202:13: error: conflicting types for 'ssize_t' \ No newline at end of file diff --git a/examples/device/net_lwip_webserver/.skip.MCU_BCM2837 b/examples/device/net_lwip_webserver/.skip.MCU_BCM2837 deleted file mode 100644 index bdc68f5db..000000000 --- a/examples/device/net_lwip_webserver/.skip.MCU_BCM2837 +++ /dev/null @@ -1 +0,0 @@ -tinyusb/lib/lwip/src/include/lwip/arch.h:202:13: error: conflicting types for 'ssize_t' \ No newline at end of file diff --git a/examples/device/net_lwip_webserver/.skip.MCU_LPC11UXX b/examples/device/net_lwip_webserver/.skip.MCU_LPC11UXX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/net_lwip_webserver/.skip.MCU_LPC13XX b/examples/device/net_lwip_webserver/.skip.MCU_LPC13XX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/net_lwip_webserver/.skip.MCU_MKL25ZXX b/examples/device/net_lwip_webserver/.skip.MCU_MKL25ZXX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/net_lwip_webserver/.skip.MCU_MSP430x5xx b/examples/device/net_lwip_webserver/.skip.MCU_MSP430x5xx deleted file mode 100644 index 17600f062..000000000 --- a/examples/device/net_lwip_webserver/.skip.MCU_MSP430x5xx +++ /dev/null @@ -1 +0,0 @@ -too many warnings for 16-bit integer overflow diff --git a/examples/device/net_lwip_webserver/.skip.MCU_NUC121 b/examples/device/net_lwip_webserver/.skip.MCU_NUC121 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/net_lwip_webserver/.skip.MCU_SAMD11 b/examples/device/net_lwip_webserver/.skip.MCU_SAMD11 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/net_lwip_webserver/.skip.MCU_STM32L0 b/examples/device/net_lwip_webserver/.skip.MCU_STM32L0 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/net_lwip_webserver/skip.txt b/examples/device/net_lwip_webserver/skip.txt new file mode 100644 index 000000000..68761b058 --- /dev/null +++ b/examples/device/net_lwip_webserver/skip.txt @@ -0,0 +1,10 @@ +mcu:LPC11UXX +mcu:LPC13XX +mcu:MSP430x5xx +mcu:NUC121 +mcu:SAMD11 +mcu:STM32L0 +mcu:MKL25ZXX +family:broadcom_64bit +family:broadcom_32bit +board:curiosity_nano \ No newline at end of file diff --git a/examples/device/uac2_headset/.skip.MCU_LPC11UXX b/examples/device/uac2_headset/.skip.MCU_LPC11UXX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/uac2_headset/.skip.MCU_LPC13XX b/examples/device/uac2_headset/.skip.MCU_LPC13XX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/uac2_headset/.skip.MCU_NUC121 b/examples/device/uac2_headset/.skip.MCU_NUC121 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/uac2_headset/.skip.MCU_SAMD11 b/examples/device/uac2_headset/.skip.MCU_SAMD11 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/uac2_headset/.skip.MCU_SAME5X b/examples/device/uac2_headset/.skip.MCU_SAME5X deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/uac2_headset/.skip.MCU_SAMG b/examples/device/uac2_headset/.skip.MCU_SAMG deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/uac2_headset/skip.txt b/examples/device/uac2_headset/skip.txt new file mode 100644 index 000000000..9471822a4 --- /dev/null +++ b/examples/device/uac2_headset/skip.txt @@ -0,0 +1,6 @@ +mcu:LPC11UXX +mcu:LPC13XX +mcu:NUC121 +mcu:SAMD11 +mcu:SAME5X +mcu:SAMG \ No newline at end of file diff --git a/examples/device/video_capture/.skip.MCU_MSP430x5xx b/examples/device/video_capture/.skip.MCU_MSP430x5xx deleted file mode 100644 index 17600f062..000000000 --- a/examples/device/video_capture/.skip.MCU_MSP430x5xx +++ /dev/null @@ -1 +0,0 @@ -too many warnings for 16-bit integer overflow diff --git a/examples/device/video_capture/.skip.MCU_SAMD11 b/examples/device/video_capture/.skip.MCU_SAMD11 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/video_capture/skip.txt b/examples/device/video_capture/skip.txt new file mode 100644 index 000000000..892a8c6a7 --- /dev/null +++ b/examples/device/video_capture/skip.txt @@ -0,0 +1,2 @@ +mcu:MSP430x5xx +mcu:SAMD11 \ No newline at end of file diff --git a/examples/host/cdc_msc_hid/.only.MCU_LPC175X_6X b/examples/host/cdc_msc_hid/.only.MCU_LPC175X_6X deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/cdc_msc_hid/.only.MCU_LPC177X_8X b/examples/host/cdc_msc_hid/.only.MCU_LPC177X_8X deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/cdc_msc_hid/.only.MCU_LPC18XX b/examples/host/cdc_msc_hid/.only.MCU_LPC18XX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/cdc_msc_hid/.only.MCU_LPC40XX b/examples/host/cdc_msc_hid/.only.MCU_LPC40XX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/cdc_msc_hid/.only.MCU_LPC43XX b/examples/host/cdc_msc_hid/.only.MCU_LPC43XX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/cdc_msc_hid/.only.MCU_MIMXRT10XX b/examples/host/cdc_msc_hid/.only.MCU_MIMXRT10XX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/cdc_msc_hid/.only.MCU_MSP432E4 b/examples/host/cdc_msc_hid/.only.MCU_MSP432E4 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/cdc_msc_hid/.only.MCU_RP2040 b/examples/host/cdc_msc_hid/.only.MCU_RP2040 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/cdc_msc_hid/only.txt b/examples/host/cdc_msc_hid/only.txt new file mode 100644 index 000000000..db9a337e5 --- /dev/null +++ b/examples/host/cdc_msc_hid/only.txt @@ -0,0 +1,8 @@ +mcu:LPC175X_6X +mcu:LPC177X_8X +mcu:LPC18XX +mcu:LPC40XX +mcu:LPC43XX +mcu:MIMXRT10XX +mcu:RP2040 +mcu:MSP432E4 \ No newline at end of file diff --git a/examples/host/hid_controller/.only.MCU_LPC175X_6X b/examples/host/hid_controller/.only.MCU_LPC175X_6X deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/hid_controller/.only.MCU_LPC177X_8X b/examples/host/hid_controller/.only.MCU_LPC177X_8X deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/hid_controller/.only.MCU_LPC18XX b/examples/host/hid_controller/.only.MCU_LPC18XX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/hid_controller/.only.MCU_LPC40XX b/examples/host/hid_controller/.only.MCU_LPC40XX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/hid_controller/.only.MCU_LPC43XX b/examples/host/hid_controller/.only.MCU_LPC43XX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/hid_controller/.only.MCU_MIMXRT10XX b/examples/host/hid_controller/.only.MCU_MIMXRT10XX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/hid_controller/.only.MCU_MSP432E4 b/examples/host/hid_controller/.only.MCU_MSP432E4 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/hid_controller/.only.MCU_RP2040 b/examples/host/hid_controller/.only.MCU_RP2040 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/hid_controller/only.txt b/examples/host/hid_controller/only.txt new file mode 100644 index 000000000..db9a337e5 --- /dev/null +++ b/examples/host/hid_controller/only.txt @@ -0,0 +1,8 @@ +mcu:LPC175X_6X +mcu:LPC177X_8X +mcu:LPC18XX +mcu:LPC40XX +mcu:LPC43XX +mcu:MIMXRT10XX +mcu:RP2040 +mcu:MSP432E4 \ No newline at end of file diff --git a/hw/bsp/samd21/boards/curiosity_nano/.skip.device.net_lwip_webserver b/hw/bsp/samd21/boards/curiosity_nano/.skip.device.net_lwip_webserver deleted file mode 100644 index e69de29bb..000000000 diff --git a/tools/build_board.py b/tools/build_board.py index 9397c754f..b2a80c680 100644 --- a/tools/build_board.py +++ b/tools/build_board.py @@ -4,6 +4,8 @@ import sys import subprocess import time +import build_utils + SUCCEEDED = "\033[32msucceeded\033[0m" FAILED = "\033[31mfailed\033[0m" SKIPPED = "\033[33mskipped\033[0m" @@ -50,7 +52,7 @@ def build_board(example, board): sram_size = "-" # Check if board is skipped - if skip_example(example, board): + if build_utils.skip_example(example, board): success = SKIPPED skip_count += 1 print(build_format.format(example, board, success, '-', flash_size, sram_size)) @@ -82,33 +84,6 @@ def build_size(example, board): sram_size = int(size_list[1]) + int(size_list[2]) return (flash_size, sram_size) -def skip_example(example, board): - ex_dir = 'examples/' + example - board_mk = 'hw/bsp/{}/board.mk'.format(board) - with open(board_mk) as mk: - mk_contents = mk.read() - - # Skip all OPT_MCU_NONE these are WIP port - if '-DCFG_TUSB_MCU=OPT_MCU_NONE' in mk_contents: - return 1 - - # Skip if CFG_TUSB_MCU in board.mk to match skip file - for skip_file in glob.iglob(ex_dir + '/.skip.MCU_*'): - mcu_cflag = '-DCFG_TUSB_MCU=OPT_' + os.path.basename(skip_file).split('.')[2] - if mcu_cflag in mk_contents: - return 1 - - # Build only list, if exists only these MCU are built - only_list = list(glob.iglob(ex_dir + '/.only.MCU_*')) - if len(only_list) > 0: - for only_file in only_list: - mcu_cflag = '-DCFG_TUSB_MCU=OPT_' + os.path.basename(only_file).split('.')[2] - if mcu_cflag in mk_contents: - return 0 - return 1 - - return 0 - print(build_separator) print(build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) diff --git a/tools/build_esp32sx.py b/tools/build_esp32sx.py index 91953f080..2947a0a6b 100644 --- a/tools/build_esp32sx.py +++ b/tools/build_esp32sx.py @@ -4,6 +4,8 @@ import sys import subprocess import time +import build_utils + SUCCEEDED = "\033[32msucceeded\033[0m" FAILED = "\033[31mfailed\033[0m" SKIPPED = "\033[33mskipped\033[0m" @@ -51,7 +53,7 @@ def build_board(example, board): sram_size = "-" # Check if board is skipped - if skip_example(example, board): + if build_utils.skip_example(example, board): success = SKIPPED skip_count += 1 print(build_format.format(example, board, success, '-', flash_size, sram_size)) @@ -83,9 +85,6 @@ def build_size(example, board): sram_size = int(size_list[1]) + int(size_list[2]) return (flash_size, sram_size) -def skip_example(example, board): - return 0 - print(build_separator) print(build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) print(build_separator) diff --git a/tools/build_family.py b/tools/build_family.py index ccbcfa3f8..4094d07db 100644 --- a/tools/build_family.py +++ b/tools/build_family.py @@ -4,6 +4,8 @@ import sys import subprocess import time +import build_utils + SUCCEEDED = "\033[32msucceeded\033[0m" FAILED = "\033[31mfailed\033[0m" SKIPPED = "\033[33mskipped\033[0m" @@ -62,7 +64,7 @@ def build_board(example, board): sram_size = "-" # Check if board is skipped - if skip_example(example, board): + if build_utils.skip_example(example, board): success = SKIPPED skip_count += 1 print(build_format.format(example, board, success, '-', flash_size, sram_size)) @@ -95,46 +97,6 @@ def build_size(example, board): sram_size = int(size_list[1]) + int(size_list[2]) return (flash_size, sram_size) -def skip_example(example, board): - ex_dir = 'examples/' + example - - # Check if example is skipped by family or board directory - skip_file = ".skip." + example.replace('/', '.'); - if os.path.isfile("hw/bsp/{}/{}".format(family, skip_file)) or os.path.isfile("hw/bsp/{}/boards/{}/{}".format(family, board, skip_file)): - return 1 - - # Otherwise check if mcu is excluded by example directory - - # family CMake - family_mk = 'hw/bsp/{}/family.cmake'.format(family) - - # family.mk - if not os.path.exists(family_mk): - family_mk = 'hw/bsp/{}/family.mk'.format(family) - - with open(family_mk) as mk: - mk_contents = mk.read() - - # Skip all OPT_MCU_NONE these are WIP port - if 'CFG_TUSB_MCU=OPT_MCU_NONE' in mk_contents: - return 1 - - # Skip if CFG_TUSB_MCU in family.mk to match skip file - for skip_file in glob.iglob(ex_dir + '/.skip.MCU_*'): - mcu_cflag = 'CFG_TUSB_MCU=OPT_' + os.path.basename(skip_file).split('.')[2] - if mcu_cflag in mk_contents: - return 1 - - # Build only list, if exists only these MCU are built - only_list = list(glob.iglob(ex_dir + '/.only.MCU_*')) - if len(only_list) > 0: - for only_file in only_list: - mcu_cflag = 'CFG_TUSB_MCU=OPT_' + os.path.basename(only_file).split('.')[2] - if mcu_cflag in mk_contents: - return 0 - return 1 - return 0 - print(build_separator) print(build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) diff --git a/tools/build_utils.py b/tools/build_utils.py new file mode 100644 index 000000000..299fffa4d --- /dev/null +++ b/tools/build_utils.py @@ -0,0 +1,61 @@ +import pathlib + +def skip_example(example, board): + ex_dir = pathlib.Path('examples/') / example + bsp = pathlib.Path("hw/bsp") + + board_dir = list(bsp.glob("*/boards/" + board)) + if not board_dir: + # Skip unknown boards + return True + + board_dir = list(board_dir)[0] + + family_dir = board_dir.parent.parent + family = family_dir.name + + # family CMake + family_mk = family_dir / "family.cmake" + + # family.mk + if not family_mk.exists(): + family_mk = family_dir / "family.mk" + + mk_contents = family_mk.read_text() + + # Find the mcu + if "CFG_TUSB_MCU=OPT_MCU_" not in mk_contents: + board_mk = board_dir / "board.cmake" + if not board_mk.exists(): + board_mk = board_dir / "board.mk" + + mk_contents = board_mk.read_text() + + for token in mk_contents.split(): + if "CFG_TUSB_MCU=OPT_MCU_" in token: + # Strip " because cmake files has them. + token = token.strip("\"") + _, opt_mcu = token.split("=") + mcu = opt_mcu[len("OPT_MCU_"):] + + # Skip all OPT_MCU_NONE these are WIP port + if mcu == "NONE": + return True + + skip_file = ex_dir / "skip.txt" + only_file = ex_dir / "only.txt" + + if skip_file.exists() and only_file.exists(): + raise RuntimeError("Only have a skip or only file. Not both.") + elif skip_file.exists(): + skips = skip_file.read_text().split() + return ("mcu:" + mcu in skips or + "board:" + board in skips or + "family:" + family in skips) + elif only_file.exists(): + onlys = only_file.read_text().split() + return not ("mcu:" + mcu in onlys or + "board:" + board in onlys or + "family:" + family in onlys) + + return False From 47218eeb674789db9dbd9b8b305c6390c3e00577 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 5 Jan 2022 16:07:17 -0800 Subject: [PATCH 103/504] No exceptions on broadcom. Add parens to if --- hw/bsp/broadcom_32bit/family.mk | 1 + src/class/usbtmc/usbtmc_device.c | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/hw/bsp/broadcom_32bit/family.mk b/hw/bsp/broadcom_32bit/family.mk index 4ff574744..98744c5d0 100644 --- a/hw/bsp/broadcom_32bit/family.mk +++ b/hw/bsp/broadcom_32bit/family.mk @@ -10,6 +10,7 @@ CFLAGS += \ -nostdlib \ -nostartfiles \ -mgeneral-regs-only \ + -fno-exceptions \ -std=c17 CROSS_COMPILE = arm-none-eabi- diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 4bd1edf12..26be987cf 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -235,17 +235,19 @@ void usbtmcd_init_cb(void) usbtmc_state.capabilities = tud_usbtmc_get_capabilities_cb(); #ifndef NDEBUG # if CFG_TUD_USBTMC_ENABLE_488 - if(usbtmc_state.capabilities->bmIntfcCapabilities488.supportsTrigger) - TU_ASSERT(&tud_usbtmc_msg_trigger_cb != NULL,); - // Per USB488 spec: table 8 - TU_ASSERT(!usbtmc_state.capabilities->bmIntfcCapabilities.listenOnly,); - TU_ASSERT(!usbtmc_state.capabilities->bmIntfcCapabilities.talkOnly,); + if (usbtmc_state.capabilities->bmIntfcCapabilities488.supportsTrigger) { + TU_ASSERT(&tud_usbtmc_msg_trigger_cb != NULL,); + } + // Per USB488 spec: table 8 + TU_ASSERT(!usbtmc_state.capabilities->bmIntfcCapabilities.listenOnly,); + TU_ASSERT(!usbtmc_state.capabilities->bmIntfcCapabilities.talkOnly,); # endif - if(usbtmc_state.capabilities->bmIntfcCapabilities.supportsIndicatorPulse) - TU_ASSERT(&tud_usbtmc_indicator_pulse_cb != NULL,); + if (usbtmc_state.capabilities->bmIntfcCapabilities.supportsIndicatorPulse) { + TU_ASSERT(&tud_usbtmc_indicator_pulse_cb != NULL,); + } #endif - usbtmcLock = osal_mutex_create(&usbtmcLockBuffer); + usbtmcLock = osal_mutex_create(&usbtmcLockBuffer); } uint16_t usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) From bed8913107efeb4b38d80f5cc4caef2fd351b57f Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 5 Jan 2022 16:17:19 -0800 Subject: [PATCH 104/504] Skip dfu and usbtmc on pi zero --- examples/device/dfu/skip.txt | 3 ++- examples/device/usbtmc/skip.txt | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 examples/device/usbtmc/skip.txt diff --git a/examples/device/dfu/skip.txt b/examples/device/dfu/skip.txt index 2c9d94902..9ac346bad 100644 --- a/examples/device/dfu/skip.txt +++ b/examples/device/dfu/skip.txt @@ -1 +1,2 @@ -mcu:TM4C123 \ No newline at end of file +mcu:TM4C123 +mcu:BCM2835 diff --git a/examples/device/usbtmc/skip.txt b/examples/device/usbtmc/skip.txt new file mode 100644 index 000000000..a43106cf0 --- /dev/null +++ b/examples/device/usbtmc/skip.txt @@ -0,0 +1 @@ +mcu:BCM2835 From 44406a8940a96bbe03e103a4f4895ec19183941f Mon Sep 17 00:00:00 2001 From: EmergReanimator Date: Thu, 6 Jan 2022 09:56:45 +0100 Subject: [PATCH 105/504] Enable breakpoints for ARM8M (e.g. cortex-m33) --- src/common/tusb_verify.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/common/tusb_verify.h b/src/common/tusb_verify.h index 56ba8bcd1..8fef11dc7 100644 --- a/src/common/tusb_verify.h +++ b/src/common/tusb_verify.h @@ -37,31 +37,31 @@ * manipulation that you are told to stay away. * * This contains macros for both VERIFY and ASSERT: - * + * * VERIFY: Used when there is an error condition which is not the * fault of the MCU. For example, bounds checking on data * sent to the micro over USB should use this function. * Another example is checking for buffer overflows, where * returning from the active function causes a NAK. - * + * * ASSERT: Used for error conditions that are caused by MCU firmware * bugs. This is used to discover bugs in the code more * quickly. One example would be adding assertions in library * function calls to confirm a function's (untainted) * parameters are valid. - * + * * The difference in behavior is that ASSERT triggers a breakpoint while * verify does not. * * #define TU_VERIFY(cond) if(cond) return false; * #define TU_VERIFY(cond,ret) if(cond) return ret; - * + * * #define TU_VERIFY_HDLR(cond,handler) if(cond) {handler; return false;} * #define TU_VERIFY_HDLR(cond,ret,handler) if(cond) {handler; return ret;} * * #define TU_ASSERT(cond) if(cond) {_MESS_FAILED(); TU_BREAKPOINT(), return false;} * #define TU_ASSERT(cond,ret) if(cond) {_MESS_FAILED(); TU_BREAKPOINT(), return ret;} - * + * *------------------------------------------------------------------*/ #ifdef __cplusplus @@ -81,8 +81,8 @@ #define _MESS_FAILED() do {} while (0) #endif -// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 -#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) +// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7, M33 +#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__) #define TU_BREAKPOINT() do \ { \ volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ From 13015a17a4f40ffdd7a5e38c54f9e1370b167335 Mon Sep 17 00:00:00 2001 From: "Man, Jianting (Meco)" <920369182@qq.com> Date: Thu, 6 Jan 2022 12:40:08 -0500 Subject: [PATCH 106/504] Update README.rst --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index faeef3663..b72436390 100644 --- a/README.rst +++ b/README.rst @@ -90,7 +90,7 @@ TinyUSB is completely thread-safe by pushing all Interrupt Service Request (ISR) - **No OS** - **FreeRTOS** -- **RT-Thread** (https://github.com/tfx2001/tinyusb) +- **RT-Thread** (https://github.com/RT-Thread/rt-thread) - **Mynewt** Due to the newt package build system, Mynewt examples are better to be on its [own repo](https://github.com/hathach/mynewt-tinyusb-example) Local Docs From a284e438f1952315631f354dee2b30b264afb324 Mon Sep 17 00:00:00 2001 From: Valentin Milea Date: Fri, 7 Jan 2022 15:02:52 +0200 Subject: [PATCH 107/504] Disable feedback format correction by default #1234 --- src/class/audio/audio_device.c | 6 ++---- src/class/audio/audio_device.h | 22 +++++++++++----------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index a461e97c5..5ffc9b0dc 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -2247,14 +2247,12 @@ static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -// Input value feedback has to be in 16.16 format - the format will be converted according to speed settings automatically -// unless format correction is disabled. bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) { TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); // Format the feedback value -#if !TUD_OPT_HIGH_SPEED && !CFG_TUD_AUDIO_DISABLE_FEEDBACK_FORMAT_CORRECTION +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION && !TUD_OPT_HIGH_SPEED uint8_t * fb = (uint8_t *) &_audiod_fct[func_id].fb_val; // For FS format is 10.14 @@ -2264,7 +2262,7 @@ bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) // 4th byte is needed to work correctly with MS Windows *fb = 0; #else - // For HS format is 16.16 as originally demanded + // Send value as-is, caller will choose the appropriate format _audiod_fct[func_id].fb_val = feedback; #endif diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index 731fd6c01..f406cf281 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -186,9 +186,9 @@ #define CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP 0 // Feedback - 0 or 1 #endif -// Disable/enable conversion from 16.16 to 10.14 format on high-speed devices. See tud_audio_n_fb_set(). -#ifndef CFG_TUD_AUDIO_DISABLE_FEEDBACK_FORMAT_CORRECTION -#define CFG_TUD_AUDIO_DISABLE_FEEDBACK_FORMAT_CORRECTION 0 // 0 or 1 +// Enable/disable conversion from 16.16 to 10.14 format on full-speed devices. See tud_audio_n_fb_set(). +#ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION 0 // 0 or 1 #endif // Audio interrupt control EP size - disabled if 0 @@ -459,15 +459,15 @@ TU_ATTR_WEAK bool tud_audio_rx_done_post_read_cb(uint8_t rhport, uint16_t n_byte #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP TU_ATTR_WEAK bool tud_audio_fb_done_cb(uint8_t rhport); -// User code should call this function with feedback value in 16.16 format for FS and HS. -// Value will be corrected for FS to 10.14 format automatically. -// (see Universal Serial Bus Specification Revision 2.0 5.12.4.2). -// Feedback value will be sent at FB endpoint interval till it's changed. + +// This function is used to provide data rate feedback from an asynchronous sink. Feedback value will be sent at FB endpoint interval till it's changed. // -// Note that the USB Audio 2.0 driver on Windows 10 is not following the spec and expects 16.16 -// format for FS. You can define CFG_TUD_AUDIO_DISABLE_FEEDBACK_FORMAT_CORRECTION=1 as a workaround -// to transmit the feedback value unchanged. Be aware that this might break feedback on other hosts, -// though at least on Linux the ALSA driver will happily accept either format. +// The feedback format is specified to be 16.16 for HS and 10.14 for FS devices (see Universal Serial Bus Specification Revision 2.0 5.12.4.2). By default, +// the choice of format is left to the caller and feedback argument is sent as-is. If CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION is set, then tinyusb +// expects 16.16 format and handles the conversion to 10.14 on FS. +// +// Note that due to a bug in its USB Audio 2.0 driver, Windows currently requires 16.16 format for _all_ USB 2.0 devices. On Linux and macOS it seems the +// driver can work with either format. So a good compromise is to keep format correction disabled and stick to 16.16 format. bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); static inline bool tud_audio_fb_set(uint32_t feedback); #endif From 340309561dbf10f17798dc74731e9804e892e0f4 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Sun, 26 Dec 2021 22:37:27 +0100 Subject: [PATCH 108/504] Add driver for PIC32MZ MCUs Device-only driver for PIC32MZ MCUs. --- src/device/dcd_attr.h | 4 + src/portable/microchip/pic32mz/dcd_pic32mz.c | 737 +++++++++++++++++++ src/tusb_option.h | 1 + 3 files changed, 742 insertions(+) create mode 100644 src/portable/microchip/pic32mz/dcd_pic32mz.c diff --git a/src/device/dcd_attr.h b/src/device/dcd_attr.h index 3c5dadaf4..bd8994fd8 100644 --- a/src/device/dcd_attr.h +++ b/src/device/dcd_attr.h @@ -86,6 +86,10 @@ #define DCD_ATTR_ENDPOINT_MAX 10 #define DCD_ATTR_ENDPOINT_EXCLUSIVE_NUMBER +#elif TU_CHECK_MCU(OPT_MCU_PIC32MZ) + #define DCD_ATTR_ENDPOINT_MAX 8 + #define DCD_ATTR_ENDPOINT_EXCLUSIVE_NUMBER + //------------- ST -------------// #elif TU_CHECK_MCU(OPT_MCU_STM32F0) #define DCD_ATTR_ENDPOINT_MAX 8 diff --git a/src/portable/microchip/pic32mz/dcd_pic32mz.c b/src/portable/microchip/pic32mz/dcd_pic32mz.c new file mode 100644 index 000000000..323d01a71 --- /dev/null +++ b/src/portable/microchip/pic32mz/dcd_pic32mz.c @@ -0,0 +1,737 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2022 Jerzy Kasenberg + * + * 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 TUSB_OPT_DEVICE_ENABLED && CFG_TUSB_MCU == OPT_MCU_PIC32MZ + +#include +#include + +#include +#include "usbhs_registers.h" + +#define USB_REGS ((usbhs_registers_t *) (_USB_BASE_ADDRESS)) + +// Maximum number of endpoints, could be trimmed down in tusb_config to reduce RAM usage. +#ifndef EP_MAX +#define EP_MAX 8 +#endif + + +typedef enum { + EP0_STAGE_NONE, + EP0_STAGE_SETUP_IN_DATA, + EP0_STAGE_SETUP_OUT_NO_DATA, + EP0_STAGE_SETUP_OUT_DATA, + EP0_STAGE_DATA_IN, + EP0_STAGE_DATA_IN_LAST_PACKET_FILLED, + EP0_STAGE_DATA_IN_SENT, + EP0_STAGE_DATA_OUT, + EP0_STAGE_DATA_OUT_COMPLETE, + EP0_STAGE_STATUS_IN, + EP0_STAGE_ADDRESS_CHANGE, +} ep0_stage_t; + +typedef struct { + uint8_t * buffer; + // Total length of current transfer + uint16_t total_len; + // Bytes transferred so far + uint16_t transferred; + uint16_t max_packet_size; + uint16_t fifo_size; + // Packet size sent or received so far. It is used to modify transferred field + // after ACK is received or when filling ISO endpoint with size larger then + // FIFO size. + uint16_t last_packet_size; + uint8_t ep_addr; +} xfer_ctl_t; + +static struct +{ + // Current FIFO RAM address used for FIFO allocation + uint16_t fifo_addr_top; + // EP0 transfer stage + ep0_stage_t ep0_stage; + // Device address + uint8_t dev_addr; + xfer_ctl_t xfer_status[EP_MAX][2]; +} _dcd; + +// Two endpoint 0 descriptor definition for unified dcd_edpt_open() +static tusb_desc_endpoint_t const ep0OUT_desc = +{ + .bLength = sizeof(tusb_desc_endpoint_t), + .bDescriptorType = TUSB_DESC_ENDPOINT, + + .bEndpointAddress = 0x00, + .bmAttributes = { .xfer = TUSB_XFER_CONTROL }, + .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, + .bInterval = 0 +}; + +static tusb_desc_endpoint_t const ep0IN_desc = +{ + .bLength = sizeof(tusb_desc_endpoint_t), + .bDescriptorType = TUSB_DESC_ENDPOINT, + + .bEndpointAddress = 0x80, + .bmAttributes = { .xfer = TUSB_XFER_CONTROL }, + .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, + .bInterval = 0 +}; + +#define XFER_CTL_BASE(_ep, _dir) &_dcd.xfer_status[_ep][_dir] + +static void ep0_set_stage(ep0_stage_t stage) +{ + _dcd.ep0_stage = stage; +} + +static ep0_stage_t ep0_get_stage(void) +{ + return _dcd.ep0_stage; +} + +/*------------------------------------------------------------------*/ +/* Controller API + *------------------------------------------------------------------*/ +void dcd_init(uint8_t rhport) +{ + // Disable endpoint interrupts for now + USB_REGS->INTRRXEbits.w = 0; + USB_REGS->INTRTXEbits.w = 0; + // Enable Reset/Suspend/Resume interrupts only + USB_REGS->INTRUSBEbits.w = 7; + + dcd_connect(rhport); +} + +void dcd_int_enable(uint8_t rhport) +{ + (void) rhport; + + USBCRCONbits.USBIE = 1; +} + +void dcd_int_disable(uint8_t rhport) +{ + (void) rhport; + + USBCRCONbits.USBIE = 0; +} + +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + (void) rhport; + + ep0_set_stage(EP0_STAGE_ADDRESS_CHANGE); + // Store address it will be used later after status stage is done + _dcd.dev_addr = dev_addr; + // Confirm packet now, address will be set when status stage is detected + USB_REGS->EPCSR[0].CSR0L_DEVICEbits.w = (USBHS_EP0_DEVICE_SERVICED_RXPKTRDY | USBHS_EP0_DEVICE_DATAEND); +} + +void dcd_remote_wakeup(uint8_t rhport) +{ + (void) rhport; + + USB_REGS->POWERbits.RESUME = 1; +#if CFG_TUSB_OS != OPT_OS_NONE + osal_task_delay(10); +#endif + USB_REGS->POWERbits.RESUME = 0; +} + +void dcd_connect(uint8_t rhport) +{ + (void) rhport; + + USB_REGS->POWERbits.HSEN = TUD_OPT_HIGH_SPEED ? 1 : 0; + USB_REGS->POWERbits.SOFTCONN = 1; +} + +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + + USB_REGS->POWERbits.SOFTCONN = 1; +} + +TU_ATTR_ALWAYS_INLINE static inline bool is_in_isr(void) +{ + return (_CP0_GET_STATUS() & (_CP0_STATUS_EXL_MASK | _CP0_STATUS_IPL_MASK)) != 0; +} + +static void epn_rx_configure(uint8_t endpoint, uint16_t endpointSize, + uint16_t fifoAddress, uint8_t fifoSize, + uint32_t transferType) +{ + uint8_t old_index = USB_REGS->INDEXbits.ENDPOINT; + + // Select endpoint register set (same register address is used for all endpoints. + USB_REGS->INDEXbits.ENDPOINT = endpoint; + + // Configure the Endpoint size + USB_REGS->INDEXED_EPCSR.RXMAXPbits.RXMAXP = endpointSize; + + // Set up the fifo address. + USB_REGS->RXFIFOADDbits.RXFIFOAD = fifoAddress; + + // Resets the endpoint data toggle to 0 + USB_REGS->INDEXED_EPCSR.RXCSRL_DEVICEbits.CLRDT = 1; + + // Set up the FIFO size + USB_REGS->RXFIFOSZbits.RXFIFOSZ = fifoSize; + + USB_REGS->INDEXED_EPCSR.RXCSRH_DEVICEbits.ISO = transferType == 1 ? 1 : 0; + // Disable NYET Handshakes for interrupt endpoints + USB_REGS->INDEXED_EPCSR.RXCSRH_DEVICEbits.DISNYET = transferType == 3 ? 1 : 0; + + // Restore the index register. + USB_REGS->INDEXbits.ENDPOINT = old_index; + + // Enable the endpoint interrupt. + USB_REGS->INTRRXEbits.w |= (1 << endpoint); +} + +static void epn_tx_configure(uint8_t endpoint, uint16_t endpointSize, + uint16_t fifoAddress, uint8_t fifoSize, + uint32_t transferType) +{ + uint8_t old_index = USB_REGS->INDEXbits.ENDPOINT; + + // Select endpoint register set (same register address is used for all endpoints. + USB_REGS->INDEXbits.ENDPOINT = endpoint; + + // Configure the Endpoint size + USB_REGS->INDEXED_EPCSR.TXMAXPbits.TXMAXP = endpointSize; + + // Set up the fifo address + USB_REGS->TXFIFOADDbits.TXFIFOAD = fifoAddress; + + // Resets the endpoint data toggle to 0 + USB_REGS->INDEXED_EPCSR.TXCSRL_DEVICEbits.CLRDT = 1; + + // Set up the FIFO size + USB_REGS->TXFIFOSZbits.TXFIFOSZ = fifoSize; + + USB_REGS->INDEXED_EPCSR.TXCSRH_DEVICEbits.ISO = 1 == transferType ? 1 : 0; + + // Restore the index register + USB_REGS->INDEXbits.ENDPOINT = old_index; + + // Enable the interrupt + USB_REGS->INTRTXEbits.w |= (1 << endpoint); +} + +static void tx_fifo_write(uint8_t endpoint, uint8_t const * buffer, size_t count) +{ + size_t i; + volatile uint8_t * fifo_reg; + + fifo_reg = (volatile uint8_t *) (&USB_REGS->FIFO[endpoint]); + + for (i = 0; i < count; i++) + { + *fifo_reg = buffer[i]; + } +} + +static int rx_fifo_read(uint8_t epnum, uint8_t * buffer) +{ + uint32_t i; + uint32_t count; + volatile uint8_t * fifo_reg; + + fifo_reg = (volatile uint8_t *) (&USB_REGS->FIFO[epnum]); + + count = USB_REGS->EPCSR[epnum].RXCOUNTbits.RXCNT; + + for (i = 0; i < count; i++) + { + buffer[i] = fifo_reg[i & 3]; + } + + return count; +} + +static void xfer_complete(xfer_ctl_t * xfer, uint8_t result, bool in_isr) +{ + dcd_event_xfer_complete(0, xfer->ep_addr, xfer->transferred, result, in_isr); +} + +static void ep0_fill_tx(xfer_ctl_t * xfer_in) +{ + uint16_t left = xfer_in->total_len - xfer_in->transferred; + + if (left) + { + xfer_in->last_packet_size = tu_min16(xfer_in->max_packet_size, left); + tx_fifo_write(0, xfer_in->buffer + xfer_in->transferred, xfer_in->last_packet_size); + xfer_in->transferred += xfer_in->last_packet_size; + left = xfer_in->total_len - xfer_in->transferred; + } + + if (xfer_in->last_packet_size < xfer_in->max_packet_size || left == 0) + { + switch (ep0_get_stage()) + { + case EP0_STAGE_SETUP_IN_DATA: + case EP0_STAGE_DATA_IN: + case EP0_STAGE_DATA_IN_SENT: + ep0_set_stage(EP0_STAGE_DATA_IN_LAST_PACKET_FILLED); + USB_REGS->EPCSR[0].CSR0L_DEVICEbits.TXPKTRDY = 1; + break; + case EP0_STAGE_SETUP_OUT_NO_DATA: + ep0_set_stage(EP0_STAGE_STATUS_IN); + USB_REGS->EPCSR[0].CSR0L_DEVICEbits.w = (USBHS_EP0_DEVICE_SERVICED_RXPKTRDY | USBHS_EP0_DEVICE_DATAEND); + break; + case EP0_STAGE_DATA_OUT_COMPLETE: + ep0_set_stage(EP0_STAGE_STATUS_IN); + USB_REGS->EPCSR[0].CSR0L_DEVICEbits.w = (USBHS_EP0_DEVICE_SERVICED_RXPKTRDY | USBHS_EP0_DEVICE_DATAEND); + break; + default: + break; + } + } + else + { + switch (ep0_get_stage()) + { + case EP0_STAGE_SETUP_IN_DATA: + ep0_set_stage(EP0_STAGE_DATA_IN); + // fall through + case EP0_STAGE_DATA_IN: + USB_REGS->EPCSR[0].CSR0L_DEVICEbits.TXPKTRDY = 1; + break; + default: + break; + } + } +} + +static void epn_fill_tx(xfer_ctl_t * xfer_in, uint8_t epnum) +{ + uint16_t left = xfer_in->total_len - xfer_in->transferred; + if (left) + { + xfer_in->last_packet_size = tu_min16(xfer_in->max_packet_size, left); + tx_fifo_write(epnum, xfer_in->buffer + xfer_in->transferred, xfer_in->last_packet_size); + } + USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.TXPKTRDY = 1; +} + +static bool ep0_xfer(xfer_ctl_t * xfer, int dir) +{ + if (dir == TUSB_DIR_OUT) + { + if (xfer->total_len) + { + switch (_dcd.ep0_stage) + { + case EP0_STAGE_DATA_OUT_COMPLETE: + case EP0_STAGE_SETUP_OUT_DATA: + ep0_set_stage(EP0_STAGE_DATA_OUT); + USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SVCRPR = 1; + break; + default: + TU_ASSERT(0); + } + } + else + { + switch (_dcd.ep0_stage) + { + case EP0_STAGE_DATA_IN_SENT: + ep0_set_stage(EP0_STAGE_NONE); + // fall through + case EP0_STAGE_NONE: + xfer_complete(xfer, XFER_RESULT_SUCCESS, true); + break; + default: + break; + } + } + } + else // IN + { + ep0_fill_tx(xfer); + } + + return true; +} + +/*------------------------------------------------------------------*/ +/* DCD Endpoint port + *------------------------------------------------------------------*/ + +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) +{ + (void) rhport; + uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); + uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); + + TU_ASSERT(epnum < EP_MAX); + + xfer->max_packet_size = tu_edpt_packet_size(desc_edpt); + xfer->fifo_size = xfer->max_packet_size; + xfer->ep_addr = desc_edpt->bEndpointAddress; + + if (epnum != 0) + { + if (dir == TUSB_DIR_OUT) + { + epn_rx_configure(epnum, xfer->max_packet_size, _dcd.fifo_addr_top, __builtin_ctz(xfer->fifo_size) - 3, desc_edpt->bmAttributes.xfer); + _dcd.fifo_addr_top += (xfer->fifo_size + 7) >> 3; + } + else + { + epn_tx_configure(epnum, xfer->max_packet_size, _dcd.fifo_addr_top, __builtin_ctz(xfer->fifo_size) - 3, desc_edpt->bmAttributes.xfer); + _dcd.fifo_addr_top += (xfer->fifo_size + 7) >> 3; + } + } + return true; +} + +void dcd_edpt_close_all (uint8_t rhport) +{ + (void) rhport; + + // Reserve EP0 FIFO address + _dcd.fifo_addr_top = 64 >> 3; + for (int i = 1; i < EP_MAX; ++i) + { + tu_memclr(&_dcd.xfer_status[i], sizeof(_dcd.xfer_status[i])); + } +} + +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + (void) ep_addr; +} + +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); + (void) rhport; + + xfer->buffer = buffer; + xfer->total_len = total_bytes; + xfer->last_packet_size = 0; + xfer->transferred = 0; + + if (epnum == 0) + { + return ep0_xfer(xfer, dir); + } + if (dir == TUSB_DIR_OUT) + { + USB_REGS->INTRRXEbits.w |= (1u << epnum); + } + else // IN + { + epn_fill_tx(xfer, epnum); + } + + return true; +} + +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + (void) rhport; + + if (epnum == 0) + { + USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SENDSTALL = 1; + } + else + { + if (dir == TUSB_DIR_OUT) + { + USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.SENDSTALL = 1; + } + else + { + USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.SENDSTALL = 1; + } + } +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + (void) rhport; + + if (epnum == 0) + { + USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SENDSTALL = 0; + } + else + { + if (dir == TUSB_DIR_OUT) + { + USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.w &= ~(USBHS_EP_DEVICE_RX_SENT_STALL | USBHS_EP_DEVICE_RX_SEND_STALL); + USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.CLRDT = 1; + } + else + { + USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.w &= ~(USBHS_EP_DEVICE_TX_SENT_STALL | USBHS_EP_DEVICE_TX_SEND_STALL); + USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.CLRDT = 1; + } + } +} + +/*------------------------------------------------------------------*/ +/* Interrupt Handler + *------------------------------------------------------------------*/ + +static void ep0_handle_rx(void) +{ + int transferred; + xfer_ctl_t * xfer = XFER_CTL_BASE(0, TUSB_DIR_OUT); + + TU_ASSERT(xfer->buffer,); + + transferred = rx_fifo_read(0, xfer->buffer + xfer->transferred); + xfer->transferred += transferred; + if (transferred < xfer->max_packet_size || xfer->transferred == xfer->total_len) + { + ep0_set_stage(EP0_STAGE_DATA_OUT_COMPLETE); + xfer_complete(xfer, XFER_RESULT_SUCCESS, true); + } + else + { + USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SVCRPR = 1; + } +} + +static void epn_handle_rx_int(uint8_t epnum) +{ + uint8_t ep_status; + int transferred; + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); + + ep_status = USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.w; + if (ep_status & USBHS_EP_DEVICE_RX_SENT_STALL) + { + USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.w &= ~USBHS_EP_DEVICE_RX_SENT_STALL; + } + + if (ep_status & USBHS_EP0_HOST_RXPKTRDY) + { + TU_ASSERT(xfer->buffer != NULL,); + + transferred = rx_fifo_read(epnum, xfer->buffer + xfer->transferred); + USB_REGS->EPCSR[epnum].RXCSRL_HOSTbits.RXPKTRDY = 0; + xfer->transferred += transferred; + if (transferred < xfer->max_packet_size || xfer->transferred == xfer->total_len) + { + xfer_complete(xfer, XFER_RESULT_SUCCESS, true); + } + } +} + +static void epn_handle_tx_int(uint8_t epnum) +{ + uint8_t ep_status = USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.w; + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, TUSB_DIR_IN); + + if (ep_status & USBHS_EP_DEVICE_TX_SENT_STALL) + { + USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.w &= ~USBHS_EP_DEVICE_TX_SENT_STALL; + } + else + { + xfer->transferred += xfer->last_packet_size; + if (xfer->last_packet_size < xfer->max_packet_size || xfer->transferred == xfer->total_len) + { + xfer->last_packet_size = 0; + xfer_complete(xfer, XFER_RESULT_SUCCESS, true); + } + else + { + epn_fill_tx(xfer, epnum); + } + } +} + +static void ep0_handle_int(void) +{ + __USBHS_CSR0L_DEVICE_t ep0_status; + union { + tusb_control_request_t request; + uint32_t setup_buffer[2]; + } setup_packet; + xfer_ctl_t * xfer_in = XFER_CTL_BASE(0, TUSB_DIR_IN); + uint8_t old_index = USB_REGS->INDEXbits.ENDPOINT; + + // Select EP0 registers + USB_REGS->INDEXbits.ENDPOINT = 0; + + ep0_status = USB_REGS->EPCSR[0].CSR0L_DEVICEbits; + + if (ep0_status.SENTSTALL) + { + // Stall was sent. Reset the endpoint 0 state. + // Clear the sent stall bit. + ep0_set_stage(EP0_STAGE_NONE); + USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SENTSTALL = 0; + } + + if (ep0_status.SETUPEND) + { + // This means the current control transfer end prematurely. We don't + // need to end any transfers. The device layer will manage the + // premature transfer end. We clear the SetupEnd bit and reset the + // driver control transfer state machine to waiting for next setup + // packet from host. + USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SVSSETEND = 1; + ep0_set_stage(EP0_STAGE_NONE); + } + + if (ep0_status.RXPKTRDY) + { + switch (ep0_get_stage()) + { + default: + // Data arrived at unexpected state, this must be setup stage packet after all. + // Fall through + case EP0_STAGE_NONE: + // This means we were expecting a SETUP packet and we got one. + setup_packet.setup_buffer[0] = USB_REGS->FIFO[0]; + setup_packet.setup_buffer[1] = USB_REGS->FIFO[0]; + if (setup_packet.request.bmRequestType_bit.direction == TUSB_DIR_OUT) + { + // SVCRPR is not set yet, it will be set later when out xfer is started + // Till then NAKs will hold incommint data + ep0_set_stage(setup_packet.request.wLength == 0 ? EP0_STAGE_SETUP_OUT_NO_DATA : EP0_STAGE_SETUP_OUT_DATA); + } + else + { + USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SVCRPR = 1; + ep0_set_stage(EP0_STAGE_SETUP_IN_DATA); + } + dcd_event_setup_received(0, &setup_packet.request.bmRequestType, true); + break; + case EP0_STAGE_DATA_OUT: + ep0_handle_rx(); + break; + } + } + else + { + switch (ep0_get_stage()) + { + case EP0_STAGE_STATUS_IN: + // Status was just sent, this concludes request, notify client + ep0_set_stage(EP0_STAGE_NONE); + xfer_complete(xfer_in, XFER_RESULT_SUCCESS, true); + break; + case EP0_STAGE_DATA_IN: + // Packet sent, fill more data + ep0_fill_tx(xfer_in); + break; + case EP0_STAGE_DATA_IN_LAST_PACKET_FILLED: + ep0_set_stage(EP0_STAGE_DATA_IN_SENT); + xfer_complete(xfer_in, XFER_RESULT_SUCCESS, true); + break; + case EP0_STAGE_ADDRESS_CHANGE: + // Status stage after set address request finished, address can be changed + USB_REGS->FADDRbits.FUNC = _dcd.dev_addr; + ep0_set_stage(EP0_STAGE_NONE); + break; + default: + break; + } + } + // Restore register index + USB_REGS->INDEXbits.ENDPOINT = old_index; +} + +void dcd_int_handler(uint8_t rhport) +{ + int i; + uint8_t mask; + __USBCSR2bits_t csr2_bits; + uint16_t rxints = USB_REGS->INTRRX; + uint16_t txints = USB_REGS->INTRTX; + csr2_bits = USBCSR2bits; + (void) rhport; + + IFS4CLR = _IFS4_USBIF_MASK; + + if (csr2_bits.SOFIF && csr2_bits.SOFIE) + { + dcd_event_bus_signal(0, DCD_EVENT_SOF, true); + } + if (csr2_bits.RESETIF) + { + dcd_edpt_open(0, &ep0OUT_desc); + dcd_edpt_open(0, &ep0IN_desc); + dcd_event_bus_reset(0, USB_REGS->POWERbits.HSMODE ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true); + } + if (csr2_bits.SUSPIF) + { + dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); + } + if (csr2_bits.RESUMEIF) + { + dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); + } + // INTRTX has bit for EP0 + if (txints & 1) + { + txints ^= 1; + ep0_handle_int(); + } + for (mask = 0x02, i = 1; rxints != 0 && mask != 0; mask <<= 1, ++i) + { + if (rxints & mask) + { + rxints ^= mask; + epn_handle_rx_int(i); + } + } + for (mask = 0x02, i = 1; txints != 0 && mask != 0; mask <<= 1, ++i) + { + if (txints & mask) + { + txints ^= mask; + epn_handle_tx_int(i); + } + } +} + +#endif diff --git a/src/tusb_option.h b/src/tusb_option.h index 2edd310fa..4f16a3c1a 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -66,6 +66,7 @@ #define OPT_MCU_SAML22 205 ///< MicroChip SAML22 #define OPT_MCU_SAML21 206 ///< MicroChip SAML21 #define OPT_MCU_SAMX7X 207 ///< MicroChip SAME70, S70, V70, V71 family +#define OPT_MCU_PIC32MZ 220 ///< MicroChip PIC32MZ family // STM32 #define OPT_MCU_STM32F0 300 ///< ST F0 From fff4a248bea532f34b5cc27dfc64b7f85c5bef73 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Sun, 26 Dec 2021 22:43:45 +0100 Subject: [PATCH 109/504] Add BSPs for Microchip PIC32MZ MCUs Two boards from Olimex are added: olimex_hmz144 with PIC32MZ2048EFM144 olimex_emz64.c with PIC32MZ2048EFH064 Both can be programmed with Segger JLINK probe using ICSP interface. (JTAG not tested but could also work but header is not mounted). --- hw/bsp/pic32mz/boards/olimex_emz64/board.mk | 5 + .../boards/olimex_emz64/olimex_emz64.c | 144 ++++++++++++++++++ hw/bsp/pic32mz/boards/olimex_hmz144/board.mk | 5 + .../boards/olimex_hmz144/olimex_hmz144.c | 142 +++++++++++++++++ hw/bsp/pic32mz/family.c | 110 +++++++++++++ hw/bsp/pic32mz/family.mk | 20 +++ 6 files changed, 426 insertions(+) create mode 100644 hw/bsp/pic32mz/boards/olimex_emz64/board.mk create mode 100644 hw/bsp/pic32mz/boards/olimex_emz64/olimex_emz64.c create mode 100644 hw/bsp/pic32mz/boards/olimex_hmz144/board.mk create mode 100644 hw/bsp/pic32mz/boards/olimex_hmz144/olimex_hmz144.c create mode 100644 hw/bsp/pic32mz/family.c create mode 100644 hw/bsp/pic32mz/family.mk diff --git a/hw/bsp/pic32mz/boards/olimex_emz64/board.mk b/hw/bsp/pic32mz/boards/olimex_emz64/board.mk new file mode 100644 index 000000000..3df5ed92b --- /dev/null +++ b/hw/bsp/pic32mz/boards/olimex_emz64/board.mk @@ -0,0 +1,5 @@ +JLINK_DEVICE=PIC32MZ2048EFH064 +JLINK_IF=ICSP + +CFLAGS += \ + -mprocessor=32MZ2048EFH064 \ diff --git a/hw/bsp/pic32mz/boards/olimex_emz64/olimex_emz64.c b/hw/bsp/pic32mz/boards/olimex_emz64/olimex_emz64.c new file mode 100644 index 000000000..0f6dc37e2 --- /dev/null +++ b/hw/bsp/pic32mz/boards/olimex_emz64/olimex_emz64.c @@ -0,0 +1,144 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2022 Jerzy Kasenberg + * + * 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 +#include +#include "tusb.h" + +/* JTAG on, WDT off */ +#pragma config FDMTEN=0, FSOSCEN=0, DMTCNT=1 +#pragma config DEBUG=ON +#pragma config JTAGEN=ON +#pragma config FSLEEP=OFF +#pragma config TRCEN=OFF +#pragma config ICESEL=ICS_PGx2 + +#pragma config POSCMOD = EC +#pragma config FNOSC = SPLL +/* 24MHz posc input to pll, div by 3, multiply by 50, div by 2 -> 200mhz*/ +#pragma config FPLLICLK=0, FPLLIDIV=DIV_3, FPLLRNG=RANGE_5_10_MHZ, FPLLMULT=MUL_50, FPLLODIV=DIV_2 +#pragma config FUSBIDIO=1 +#pragma config WINDIS=NORMAL +#pragma config WDTSPGM=1 +#pragma config WDTPS=15 +#pragma config FWDTEN=OFF + +void button_init(void) +{ + // RB12 - button + // ANSELB B12 not analog + ANSELBCLR = TU_BIT(12); + // TRISB B12 input + TRISBSET = TU_BIT(12); + // Pull-up + CNPUBSET = TU_BIT(12); +} + +void led_init(void) +{ + // RB8 - LED + // ANASELB RB8 not analog + ANSELBCLR = TU_BIT(8); + // TRISH RH2 input + TRISBCLR = TU_BIT(8); + // Initial value 0, LED off + LATBCLR = TU_BIT(8); +} + +void uart_init(void) +{ + // RD4/RD0 Uart4 TX/RX + // ANSELD - not present on 64 pin device + + /* Unlock system for PPS configuration */ + SYSKEY = 0x00000000; + SYSKEY = 0xAA996655; + SYSKEY = 0x556699AA; + CFGCONbits.IOLOCK = 0; + + // PPS Input Remapping + // U4RX -> RD0 + U4RXR = 3; + + // PPS Output Remapping + // RD4 -> U4TX + RPD4R = 2; + + // Lock back the system after PPS configuration + CFGCONbits.IOLOCK = 1; + SYSKEY = 0x00000000; + + // UART4 + // High speed mode + // 8 bits, no parity, no RTS/CTS, no flow control + U4MODE = 0x0; + + // Enable UART2 Receiver and Transmitter + U4STASET = (_U4STA_UTXEN_MASK | _U4STA_URXEN_MASK | _U4STA_UTXISEL1_MASK); + + // BAUD Rate register Setup + U4BRG = 100000000 / (16 * 115200) + 1; + + // Disable Interrupts + IEC4CLR = _IEC5_U4EIE_MASK | _IEC5_U4RXIE_MASK | _IEC5_U4TXIE_MASK; + + // Turn ON UART2 + U4MODESET = _U4MODE_ON_MASK; +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + if (state) + { + LATBSET = TU_BIT(8); + } + else + { + LATBCLR = TU_BIT(8); + } +} + +uint32_t board_button_read(void) +{ + return (PORTB >> 12) & 1; +} + +int board_uart_write(void const * buf, int len) +{ + int i = len; + uint8_t const * data = buf; + while (i--) + { + while (U4STAbits.UTXBF) ; + U4TXREG = *data++; + } + return len; +} diff --git a/hw/bsp/pic32mz/boards/olimex_hmz144/board.mk b/hw/bsp/pic32mz/boards/olimex_hmz144/board.mk new file mode 100644 index 000000000..a43b62d32 --- /dev/null +++ b/hw/bsp/pic32mz/boards/olimex_hmz144/board.mk @@ -0,0 +1,5 @@ +JLINK_DEVICE=PIC32MZ2048EFM144 +JLINK_IF=ICSP + +CFLAGS += \ + -mprocessor=32MZ2048EFM144 \ diff --git a/hw/bsp/pic32mz/boards/olimex_hmz144/olimex_hmz144.c b/hw/bsp/pic32mz/boards/olimex_hmz144/olimex_hmz144.c new file mode 100644 index 000000000..4ecbe75a1 --- /dev/null +++ b/hw/bsp/pic32mz/boards/olimex_hmz144/olimex_hmz144.c @@ -0,0 +1,142 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2022 Jerzy Kasenberg + * + * 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 +#include +#include "tusb.h" + +/* JTAG on, WDT off */ +#pragma config FDMTEN=0, FSOSCEN=0, DMTCNT=1 +#pragma config DEBUG=ON +#pragma config JTAGEN=ON +#pragma config FSLEEP=OFF +#pragma config TRCEN=OFF +#pragma config ICESEL=ICS_PGx2 + +#pragma config POSCMOD = HS +#pragma config FNOSC = SPLL +/* 24MHz posc input to pll, div by 3, multiply by 50, div by 2 -> 200mhz*/ +#pragma config FPLLICLK=0, FPLLIDIV=DIV_3, FPLLRNG=RANGE_5_10_MHZ, FPLLMULT=MUL_50, FPLLODIV=DIV_2 +#pragma config FUSBIDIO=1 +#pragma config WINDIS=NORMAL +#pragma config WDTSPGM=1 +#pragma config WDTPS=15 +#pragma config FWDTEN=OFF + +void button_init(void) +{ + // RB12 - button + // ANSELB B12 not analog + ANSELBCLR = TU_BIT(12); + // TRISB B12 input + TRISBSET = TU_BIT(12); +} + +void led_init(void) +{ + // RH2 - LED + // ANASELH no analog function on RH2 + // TRISH RH2 input + TRISHCLR = TU_BIT(2); + // Initial value 0, LED off + LATHCLR = TU_BIT(2); +} + +void uart_init(void) +{ + // RE8/RE9 Uart2 TX/RX + // ANSELE - TX/RX not analog + ANSELECLR = TU_BIT(8) | TU_BIT(9); + + /* Unlock system for PPS configuration */ + SYSKEY = 0x00000000; + SYSKEY = 0xAA996655; + SYSKEY = 0x556699AA; + CFGCONbits.IOLOCK = 0; + + // PPS Input Remapping + // U2RX -> RE9 + U2RXR = 13; + + // PPS Output Remapping + // RE8 -> U2TX + RPE8R = 2; + + // Lock back the system after PPS configuration + CFGCONbits.IOLOCK = 1; + SYSKEY = 0x00000000; + + // UART2 + // High speed mode + // 8 bits, no parity, no RTS/CTS, no flow control + U2MODE = 0x0; + + // Enable UART2 Receiver and Transmitter + U2STASET = (_U2STA_UTXEN_MASK | _U2STA_URXEN_MASK | _U2STA_UTXISEL1_MASK); + + // BAUD Rate register Setup + U2BRG = 100000000 / (16 * 115200) + 1; + + // Disable Interrupts + IEC4CLR = _IEC4_U2EIE_MASK | _IEC4_U2RXIE_MASK | _IEC4_U2TXIE_MASK; + + // Turn ON UART2 + U2MODESET = _U2MODE_ON_MASK; +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + if (state) + { + LATHSET = TU_BIT(2); + } + else + { + LATHCLR = TU_BIT(2); + } +} + +uint32_t board_button_read(void) +{ + return (PORTB >> 12) & 1; +} + +int board_uart_write(void const * buf, int len) +{ + int i = len; + uint8_t const * data = buf; + while (i--) + { + while (U2STAbits.UTXBF) ; + U2TXREG = *data++; + } + return len; +} diff --git a/hw/bsp/pic32mz/family.c b/hw/bsp/pic32mz/family.c new file mode 100644 index 000000000..786f04978 --- /dev/null +++ b/hw/bsp/pic32mz/family.c @@ -0,0 +1,110 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2022 Jerzy Kasenberg + * + * 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 +#include +#include "tusb.h" + +void __attribute__((interrupt(IPL2AUTO), vector(_USB_VECTOR), no_fpu)) +USBD_IRQHandler(void) +{ + IFS4CLR = _IFS4_USBIF_MASK; + tud_int_handler(0); +} + +TU_ATTR_WEAK void button_init(void) +{ +} + +TU_ATTR_WEAK void led_init(void) +{ +} + +TU_ATTR_WEAK void uart_init(void) +{ +} + +void board_init(void) +{ + button_init(); + led_init(); + uart_init(); + + // Force device mode by overriding USB ID and settings it to 1 + USBCRCONbits.PHYIDEN = 0; + USBCRCONbits.USBIDVAL = 1; + USBCRCONbits.USBIDOVEN = 1; + + // set interrupt priority (must much IPL2AUTO) + IPC33CLR = _IPC33_USBIP_MASK; + IPC33SET = (2 << _IPC33_USBIP_POSITION); + // set interrupt subpriority + IPC33CLR = _IPC33_USBIS_MASK; + IPC33SET = (0 << _IPC33_USBIS_POSITION); + + USBCRCONbits.USBIE = 0; + IFS4CLR = _IFS4_USBIF_MASK; + IEC4SET = _IEC4_USBIE_MASK; + + __builtin_enable_interrupts(); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +TU_ATTR_WEAK void board_led_write(bool state) +{ + (void) state; +} + +TU_ATTR_WEAK uint32_t board_button_read(void) +{ + return 0; +} + +TU_ATTR_WEAK int board_uart_read(uint8_t * buf, int len) +{ + (void) buf; + (void) len; + + return 0; +} + +TU_ATTR_WEAK int board_uart_write(void const * buf, int len) +{ + (void) buf; + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +uint32_t board_millis(void) +{ + // COUNTER is system clock (200MHz / 2 = 100MHz) convert to ms) + return _CP0_GET_COUNT() / (100000000 / 1000); +} +#endif diff --git a/hw/bsp/pic32mz/family.mk b/hw/bsp/pic32mz/family.mk new file mode 100644 index 000000000..48e08689f --- /dev/null +++ b/hw/bsp/pic32mz/family.mk @@ -0,0 +1,20 @@ +CROSS_COMPILE = xc32- +CFLAGS_OPTIMIZED = -O2 +LIBS_GCC = -lgcc -lm +SKIP_NANOLIB = 1 + +CFLAGS = \ + -std=c99 \ + -DCFG_TUSB_MCU=OPT_MCU_PIC32MZ + +include $(TOP)/$(BOARD_PATH)/board.mk + +SRC_C += \ + src/portable/microchip/pic32mz/dcd_pic32mz.c \ + +INC += \ + $(TOP)/hw/mcu/microchip/pic32mz \ + $(TOP)/$(BOARD_PATH) \ + +# flash target using jlink +flash: flash-jlink From c5d825450ab35f11bf9370b5cacc21706d3d0780 Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Thu, 13 Jan 2022 00:24:56 +0900 Subject: [PATCH 110/504] Fix dwFrameIntervalStep and dwMaxFrameInterval dwMaxFrameInterval minus dwMinFrameInterval should be evenly divisible by dwFrameIntervalStep. --- examples/device/video_capture/src/usb_descriptors.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/device/video_capture/src/usb_descriptors.h b/examples/device/video_capture/src/usb_descriptors.h index eeaef6bd2..23511c909 100644 --- a/examples/device/video_capture/src/usb_descriptors.h +++ b/examples/device/video_capture/src/usb_descriptors.h @@ -103,7 +103,7 @@ enum { TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT(/*bFrameIndex */1, 0, _width, _height, \ _width * _height * 16, _width * _height * 16 * _fps, \ _width * _height * 16, \ - (10000000/_fps), (10000000/_fps), 10000000, 100000), \ + (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ /* VS alt 1 */\ TUD_VIDEO_DESC_STD_VS(1, 1, 1, 0), \ From 3db9cf354795603dd815aa4b85995f52bf9fc530 Mon Sep 17 00:00:00 2001 From: Liam Fraser Date: Thu, 13 Jan 2022 13:42:28 +0000 Subject: [PATCH 111/504] Fix family_support.cmake to use new skip.txt and only.txt files for skipping mcus --- hw/bsp/family_support.cmake | 55 ++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index af0e00b2d..a8cc1f363 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -11,23 +11,52 @@ if (NOT TARGET _family_support_marker) function(family_filter RESULT DIR) get_filename_component(DIR ${DIR} ABSOLUTE BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) - file(GLOB ONLYS "${DIR}/.only.MCU_*") - if (ONLYS) + + if (EXISTS "${DIR}/only.txt") + file(READ "${DIR}/only.txt" ONLYS) + # Replace newlines with semicolon so that it is treated as a list by CMake + string(REPLACE "\n" ";" ONLYS_LINES ${ONLYS}) + # For each mcu foreach(MCU IN LISTS FAMILY_MCUS) - if (EXISTS ${DIR}/.only.MCU_${MCU}) - set(${RESULT} 1 PARENT_SCOPE) - return() - endif() + # For each line in only.txt + foreach(_line ${ONLYS_LINES}) + # If mcu:xxx exists for this mcu then include + if (${_line} STREQUAL "mcu:${MCU}") + set(${RESULT} 1 PARENT_SCOPE) + return() + endif() + endforeach() endforeach() + + # Didn't find it in only file so don't build + set(${RESULT} 0 PARENT_SCOPE) + + elseif (EXISTS "${DIR}/skip.txt") + file(READ "${DIR}/skip.txt" SKIPS) + # Replace newlines with semicolon so that it is treated as a list by CMake + string(REPLACE "\n" ";" SKIPS_LINES ${SKIPS}) + # For each mcu + foreach(MCU IN LISTS FAMILY_MCUS) + # For each line in only.txt + foreach(_line ${SKIPS_LINES}) + # If mcu:xxx exists for this mcu then skip + if (${_line} STREQUAL "mcu:${MCU}") + set(${RESULT} 0 PARENT_SCOPE) + return() + endif() + endforeach() + endforeach() + + # Didn't find in skip file so build + set(${RESULT} 1 PARENT_SCOPE) + else() - foreach(MCU IN LISTS FAMILY_MCUS) - if (EXISTS ${DIR}/.skip.MCU_${MCU}) - set(${RESULT} 0 PARENT_SCOPE) - return() - endif() - endforeach() + + # Didn't find skip or only file so build + set(${RESULT} 1 PARENT_SCOPE) + endif() - set(${RESULT} 1 PARENT_SCOPE) + endfunction() function(family_add_subdirectory DIR) From da44fe3fc91ad643ec3892cc01a68eb52ed3dc5e Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Fri, 14 Jan 2022 09:44:38 +0100 Subject: [PATCH 112/504] nrf5x: Fix EP OUT race conditions When dcd_edpt_xfer() starts new transfer two separate problems were observed. For both problems stream of OUT packets was pouring from host. First problem was that total_len and actual_len were not atomic. In case where incoming OUT packets are less (63) than MPS (64), actual_len and total_len are set 63. Then transfer complete from USBD is called that will schedule next 64 bytes transfer. At that point incoming packet would start DMA if there is place in RAM, normally it does not happen since actual_len == total_len. If packets arrives and interrupt is raised after total_len is set (64) but actual_len is still 63 from previous transfer, interrupt code sees that there is place in ram (1 byte) and transfer this 1 byte to buffer that was already filled with previous packet. To remedy this USB interrupt is blocked during transfer setup. Second problem can happen when dcd_edpt_xfer setups xfer->total_len and actual_len correctly but then context switch happens before xfer->data_received is checked. If during this time two packets arrive one will be copied to RAM second will stay in endpoint with data_received set to 1. Then when xfer_edpt_xfer() checks data_receive flag it starts DMA again overwriting data. To remedy this, data_received is checked together with check if data was already transferred. If transfer was complete, there is no need to start DMA yet. In such case data_received will be handled in same place by next xfer_edpt_xfer() correctly. --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index ed597a34f..db3b06ee4 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -453,9 +453,11 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t xfer_td_t* xfer = get_td(epnum, dir); + dcd_int_disable(rhport); xfer->buffer = buffer; xfer->total_len = total_bytes; xfer->actual_len = 0; + dcd_int_enable(rhport); // Control endpoint with zero-length packet and opposite direction to 1st request byte --> status stage bool const control_status = (epnum == 0 && total_bytes == 0 && dir != tu_edpt_dir(NRF_USBD->BMREQUESTTYPE)); @@ -476,7 +478,7 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t edpt_dma_start(&NRF_USBD->TASKS_EP0RCVOUT); }else { - if ( xfer->data_received ) + if ( xfer->data_received && xfer->total_len > xfer->actual_len) { // Data is already received previously // start DMA to copy to SRAM From 45fb60e883b62a550420d88426e443d0a2e7dd45 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 16 Jan 2022 12:12:57 +0700 Subject: [PATCH 113/504] update format correction with actual bus speed --- src/class/audio/audio_device.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 5ffc9b0dc..d21980060 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -2252,18 +2252,23 @@ bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); // Format the feedback value -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION && !TUD_OPT_HIGH_SPEED - uint8_t * fb = (uint8_t *) &_audiod_fct[func_id].fb_val; +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION + if ( TUSB_SPEED_FULL == tud_speed_get() ) + { + uint8_t * fb = (uint8_t *) &_audiod_fct[func_id].fb_val; - // For FS format is 10.14 - *(fb++) = (feedback >> 2) & 0xFF; - *(fb++) = (feedback >> 10) & 0xFF; - *(fb++) = (feedback >> 18) & 0xFF; - // 4th byte is needed to work correctly with MS Windows - *fb = 0; + // For FS format is 10.14 + *(fb++) = (feedback >> 2) & 0xFF; + *(fb++) = (feedback >> 10) & 0xFF; + *(fb++) = (feedback >> 18) & 0xFF; + // 4th byte is needed to work correctly with MS Windows + *fb = 0; + }else #else - // Send value as-is, caller will choose the appropriate format - _audiod_fct[func_id].fb_val = feedback; + { + // Send value as-is, caller will choose the appropriate format + _audiod_fct[func_id].fb_val = feedback; + } #endif // Schedule a transmit with the new value if EP is not busy - this triggers repetitive scheduling of the feedback value From e635c16de089953e305e94cba8524cb6f3aeae6f Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 16 Jan 2022 13:12:27 +0700 Subject: [PATCH 114/504] fix esp ci build with IDF version 5 --- hw/bsp/esp32s2/boards/esp32s2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hw/bsp/esp32s2/boards/esp32s2.c b/hw/bsp/esp32s2/boards/esp32s2.c index 358c0c803..77754908e 100644 --- a/hw/bsp/esp32s2/boards/esp32s2.c +++ b/hw/bsp/esp32s2/boards/esp32s2.c @@ -98,7 +98,11 @@ static void configure_pins(usb_hal_context_t *usb) esp_rom_gpio_connect_out_signal(iopin->pin, iopin->func, false, false); } else { esp_rom_gpio_connect_in_signal(iopin->pin, iopin->func, false); +#if ESP_IDF_VERSION_MAJOR > 4 + if ((iopin->pin != GPIO_MATRIX_CONST_ZERO_INPUT) && (iopin->pin != GPIO_MATRIX_CONST_ONE_INPUT)) { +#else if ((iopin->pin != GPIO_FUNC_IN_LOW) && (iopin->pin != GPIO_FUNC_IN_HIGH)) { +#endif gpio_ll_input_enable(&GPIO, iopin->pin); } } From e1e457761656a489aded7039ad173351e2e6a7c2 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 16 Jan 2022 13:24:36 +0700 Subject: [PATCH 115/504] more ci fix --- hw/bsp/esp32s2/boards/esp32s2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/bsp/esp32s2/boards/esp32s2.c b/hw/bsp/esp32s2/boards/esp32s2.c index 77754908e..de4b1e5ba 100644 --- a/hw/bsp/esp32s2/boards/esp32s2.c +++ b/hw/bsp/esp32s2/boards/esp32s2.c @@ -70,7 +70,7 @@ void board_init(void) #endif // Button - gpio_pad_select_gpio(BUTTON_PIN); + esp_rom_gpio_pad_select_gpio(BUTTON_PIN); gpio_set_direction(BUTTON_PIN, GPIO_MODE_INPUT); gpio_set_pull_mode(BUTTON_PIN, BUTTON_STATE_ACTIVE ? GPIO_PULLDOWN_ONLY : GPIO_PULLUP_ONLY); From cb57f047e762c32c94e376b9f5c172d6b5b92f5b Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 16 Jan 2022 13:26:50 +0700 Subject: [PATCH 116/504] update for s3 --- hw/bsp/esp32s2/boards/esp32s2.c | 5 +++-- hw/bsp/esp32s3/boards/esp32s3.c | 9 +++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/hw/bsp/esp32s2/boards/esp32s2.c b/hw/bsp/esp32s2/boards/esp32s2.c index de4b1e5ba..a81181672 100644 --- a/hw/bsp/esp32s2/boards/esp32s2.c +++ b/hw/bsp/esp32s2/boards/esp32s2.c @@ -99,10 +99,11 @@ static void configure_pins(usb_hal_context_t *usb) } else { esp_rom_gpio_connect_in_signal(iopin->pin, iopin->func, false); #if ESP_IDF_VERSION_MAJOR > 4 - if ((iopin->pin != GPIO_MATRIX_CONST_ZERO_INPUT) && (iopin->pin != GPIO_MATRIX_CONST_ONE_INPUT)) { + if ((iopin->pin != GPIO_MATRIX_CONST_ZERO_INPUT) && (iopin->pin != GPIO_MATRIX_CONST_ONE_INPUT)) #else - if ((iopin->pin != GPIO_FUNC_IN_LOW) && (iopin->pin != GPIO_FUNC_IN_HIGH)) { + if ((iopin->pin != GPIO_FUNC_IN_LOW) && (iopin->pin != GPIO_FUNC_IN_HIGH)) #endif + { gpio_ll_input_enable(&GPIO, iopin->pin); } } diff --git a/hw/bsp/esp32s3/boards/esp32s3.c b/hw/bsp/esp32s3/boards/esp32s3.c index 358c0c803..a81181672 100644 --- a/hw/bsp/esp32s3/boards/esp32s3.c +++ b/hw/bsp/esp32s3/boards/esp32s3.c @@ -70,7 +70,7 @@ void board_init(void) #endif // Button - gpio_pad_select_gpio(BUTTON_PIN); + esp_rom_gpio_pad_select_gpio(BUTTON_PIN); gpio_set_direction(BUTTON_PIN, GPIO_MODE_INPUT); gpio_set_pull_mode(BUTTON_PIN, BUTTON_STATE_ACTIVE ? GPIO_PULLDOWN_ONLY : GPIO_PULLUP_ONLY); @@ -98,7 +98,12 @@ static void configure_pins(usb_hal_context_t *usb) esp_rom_gpio_connect_out_signal(iopin->pin, iopin->func, false, false); } else { esp_rom_gpio_connect_in_signal(iopin->pin, iopin->func, false); - if ((iopin->pin != GPIO_FUNC_IN_LOW) && (iopin->pin != GPIO_FUNC_IN_HIGH)) { +#if ESP_IDF_VERSION_MAJOR > 4 + if ((iopin->pin != GPIO_MATRIX_CONST_ZERO_INPUT) && (iopin->pin != GPIO_MATRIX_CONST_ONE_INPUT)) +#else + if ((iopin->pin != GPIO_FUNC_IN_LOW) && (iopin->pin != GPIO_FUNC_IN_HIGH)) +#endif + { gpio_ll_input_enable(&GPIO, iopin->pin); } } From c722133671a632d6baf60506bd93c3c6d1ed6435 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 16 Jan 2022 15:38:23 +0700 Subject: [PATCH 117/504] change OPT_MCU_PIC32MZ to value of 1900 --- src/tusb_option.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tusb_option.h b/src/tusb_option.h index 4f16a3c1a..351eeab88 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -66,7 +66,6 @@ #define OPT_MCU_SAML22 205 ///< MicroChip SAML22 #define OPT_MCU_SAML21 206 ///< MicroChip SAML21 #define OPT_MCU_SAMX7X 207 ///< MicroChip SAME70, S70, V70, V71 family -#define OPT_MCU_PIC32MZ 220 ///< MicroChip PIC32MZ family // STM32 #define OPT_MCU_STM32F0 300 ///< ST F0 @@ -137,6 +136,9 @@ // Infineon #define OPT_MCU_XMC4000 1800 ///< Infineon XMC4000 +// PIC +#define OPT_MCU_PIC32MZ 1900 ///< MicroChip PIC32MZ family + // Helper to check if configured MCU is one of listed // Apply _TU_CHECK_MCU with || as separator to list of input #define _TU_CHECK_MCU(_m) (CFG_TUSB_MCU == _m) From 1a7de71e7999d028c3a03079c5908d0943f0586d Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 17 Jan 2022 12:15:54 +0700 Subject: [PATCH 118/504] correct link in rst --- README.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index b72436390..4946e997e 100644 --- a/README.rst +++ b/README.rst @@ -74,7 +74,7 @@ Supports multiple device configurations by dynamically changing USB descriptors, - Vendor-specific class support with generic In & Out endpoints. Can be used with MS OS 2.0 compatible descriptor to load winUSB driver without INF file. - `WebUSB `__ with vendor-specific class -If you have a special requirement, `usbd_app_driver_get_cb()` can be used to write your own class driver without modifying the stack. Here is how the RPi team added their reset interface [raspberrypi/pico-sdk#197](https://github.com/raspberrypi/pico-sdk/pull/197) +If you have a special requirement, `usbd_app_driver_get_cb()` can be used to write your own class driver without modifying the stack. Here is how the RPi team added their reset interface `raspberrypi/pico-sdk#197 `_ Host Stack ========== @@ -90,8 +90,8 @@ TinyUSB is completely thread-safe by pushing all Interrupt Service Request (ISR) - **No OS** - **FreeRTOS** -- **RT-Thread** (https://github.com/RT-Thread/rt-thread) -- **Mynewt** Due to the newt package build system, Mynewt examples are better to be on its [own repo](https://github.com/hathach/mynewt-tinyusb-example) +- `RT-Thread `_ +- **Mynewt** Due to the newt package build system, Mynewt examples are better to be on its `own repo `_ Local Docs ========== From ec01428820ae5ea35bb559adf4894c4e816b7651 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Mon, 17 Jan 2022 08:50:11 +0100 Subject: [PATCH 119/504] ft9xx: Fix Mynewt build Includes were moved few lines down to restore build with Mynewt build system. --- src/portable/bridgetek/ft9xx/dcd_ft9xx.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c index 793d40f81..d46723caa 100644 --- a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c +++ b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c @@ -29,16 +29,17 @@ * in https://brtchip.com/BRTSourceCodeLicenseAgreement */ +#include "tusb_option.h" + +#if TUSB_OPT_DEVICE_ENABLED && \ + (CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X) + #include #include #include #include "board.h" #include "bsp/board.h" -#include "tusb_option.h" - -#if TUSB_OPT_DEVICE_ENABLED && \ - (CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X) #define USBD_USE_STREAMS From 168c7095e849e448cb7d3b755ea3b6e236f502ed Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Sun, 16 Jan 2022 16:13:21 +0100 Subject: [PATCH 120/504] pic32mz: Fix remote_wakeup without OS Remote wakeup requires 10ms of delay when RESUME bit is toggled. It was covered for OS build. For non-OS build simple delay based on board_millis() is used to wait required amount of time. Without this remote wakup may not work. --- src/portable/microchip/pic32mz/dcd_pic32mz.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/portable/microchip/pic32mz/dcd_pic32mz.c b/src/portable/microchip/pic32mz/dcd_pic32mz.c index 323d01a71..740e5edbb 100644 --- a/src/portable/microchip/pic32mz/dcd_pic32mz.c +++ b/src/portable/microchip/pic32mz/dcd_pic32mz.c @@ -163,6 +163,10 @@ void dcd_remote_wakeup(uint8_t rhport) USB_REGS->POWERbits.RESUME = 1; #if CFG_TUSB_OS != OPT_OS_NONE osal_task_delay(10); +#else + // TODO: Wait in non blocking mode + unsigned cnt = 2000; + while (cnt--) __asm__("nop"); #endif USB_REGS->POWERbits.RESUME = 0; } From 45d56915d157b4c38949a148391dcd10c19b50a5 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Sun, 16 Jan 2022 16:16:00 +0100 Subject: [PATCH 121/504] pic32/olimex boards: Fix active state of button Buttons for olimex_emz64 and olimex_hmz144 should be set to active low in board configuration. --- hw/bsp/pic32mz/boards/olimex_emz64/olimex_emz64.c | 4 ++-- hw/bsp/pic32mz/boards/olimex_hmz144/olimex_hmz144.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/bsp/pic32mz/boards/olimex_emz64/olimex_emz64.c b/hw/bsp/pic32mz/boards/olimex_emz64/olimex_emz64.c index 0f6dc37e2..e47ec5f31 100644 --- a/hw/bsp/pic32mz/boards/olimex_emz64/olimex_emz64.c +++ b/hw/bsp/pic32mz/boards/olimex_emz64/olimex_emz64.c @@ -63,7 +63,7 @@ void led_init(void) // RB8 - LED // ANASELB RB8 not analog ANSELBCLR = TU_BIT(8); - // TRISH RH2 input + // TRISH RH2 output TRISBCLR = TU_BIT(8); // Initial value 0, LED off LATBCLR = TU_BIT(8); @@ -128,7 +128,7 @@ void board_led_write(bool state) uint32_t board_button_read(void) { - return (PORTB >> 12) & 1; + return ((PORTB >> 12) & 1) == 0; } int board_uart_write(void const * buf, int len) diff --git a/hw/bsp/pic32mz/boards/olimex_hmz144/olimex_hmz144.c b/hw/bsp/pic32mz/boards/olimex_hmz144/olimex_hmz144.c index 4ecbe75a1..93a8da5fb 100644 --- a/hw/bsp/pic32mz/boards/olimex_hmz144/olimex_hmz144.c +++ b/hw/bsp/pic32mz/boards/olimex_hmz144/olimex_hmz144.c @@ -60,7 +60,7 @@ void led_init(void) { // RH2 - LED // ANASELH no analog function on RH2 - // TRISH RH2 input + // TRISH RH2 output TRISHCLR = TU_BIT(2); // Initial value 0, LED off LATHCLR = TU_BIT(2); @@ -126,7 +126,7 @@ void board_led_write(bool state) uint32_t board_button_read(void) { - return (PORTB >> 12) & 1; + return ((PORTB >> 12) & 1) == 0; } int board_uart_write(void const * buf, int len) From f4725120a42edc853aa6db87c1d21b2ffc401a92 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Tue, 11 Jan 2022 10:45:36 +0100 Subject: [PATCH 122/504] nrf5x: Request HFXO via OS Mynewt (similar to Soft Device) has its own reference counting for HFXO oscillator. So far TinyUSB requested HFXO when VBUS was detected and stopped when VBUS was removed. But with Mynewt running HFXO can be stopped when other interested parties don't require HFXO anymore. This results in very difficult to track USB transmission errors. This change enables Mynewt specific HFXO management in Soft Device fashion. --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index ed597a34f..49e352d39 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -38,6 +38,10 @@ #include "device/usbd.h" #include "device/usbd_pvt.h" // to use defer function helper +#if CFG_TUSB_OS == OPT_OS_MYNEWT +#include "mcu/mcu.h" +#endif + /*------------------------------------------------------------------*/ /* MACRO TYPEDEF CONSTANT ENUM *------------------------------------------------------------------*/ @@ -891,6 +895,11 @@ static bool hfclk_running(void) static void hfclk_enable(void) { +#if CFG_TUSB_OS == OPT_OS_MYNEWT + usb_clock_request(); + return; +#else + // already running, nothing to do if ( hfclk_running() ) return; @@ -904,10 +913,16 @@ static void hfclk_enable(void) nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_HFCLKSTARTED); nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTART); +#endif } static void hfclk_disable(void) { +#if CFG_TUSB_OS == OPT_OS_MYNEWT + usb_clock_release(); + return; +#else + #ifdef SOFTDEVICE_PRESENT if ( is_sd_enabled() ) { @@ -917,6 +932,7 @@ static void hfclk_disable(void) #endif nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTOP); +#endif } // Power & Clock Peripheral on nRF5x to manage USB From 161ba73c8b01c6de637309fbfc8c6dcea58c9d06 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 19 Jan 2022 10:17:39 +0700 Subject: [PATCH 123/504] fix locked mutex when fifo is full --- src/common/tusb_fifo.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index 564687e02..0d35405db 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -741,21 +741,28 @@ bool tu_fifo_write(tu_fifo_t* f, const void * data) { _ff_lock(f->mutex_wr); - uint16_t w = f->wr_idx; + bool ret; + uint16_t const w = f->wr_idx; - if ( _tu_fifo_full(f, w, f->rd_idx) && !f->overwritable ) return false; + if ( _tu_fifo_full(f, w, f->rd_idx) && !f->overwritable ) + { + ret = false; + }else + { + uint16_t wRel = get_relative_pointer(f, w); - uint16_t wRel = get_relative_pointer(f, w); + // Write data + _ff_push(f, data, wRel); - // Write data - _ff_push(f, data, wRel); + // Advance pointer + f->wr_idx = advance_pointer(f, w, 1); - // Advance pointer - f->wr_idx = advance_pointer(f, w, 1); + ret = true; + } _ff_unlock(f->mutex_wr); - return true; + return ret; } /******************************************************************************/ From af9a3f646cecd8895f488a8bc3b3c39838b55296 Mon Sep 17 00:00:00 2001 From: email <{ID}+{username}@users.noreply.github.com> Date: Wed, 19 Jan 2022 09:00:32 +0100 Subject: [PATCH 124/504] fix idfgh-6508: return type in tu_fifo_peek_n() https://github.com/espressif/esp-idf/issues/8161 --- src/common/tusb_fifo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index 0d35405db..183c9c6fc 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -716,7 +716,7 @@ bool tu_fifo_peek(tu_fifo_t* f, void * p_buffer) uint16_t tu_fifo_peek_n(tu_fifo_t* f, void * p_buffer, uint16_t n) { _ff_lock(f->mutex_rd); - bool ret = _tu_fifo_peek_n(f, p_buffer, n, f->wr_idx, f->rd_idx, TU_FIFO_COPY_INC); + uint16_t ret = _tu_fifo_peek_n(f, p_buffer, n, f->wr_idx, f->rd_idx, TU_FIFO_COPY_INC); _ff_unlock(f->mutex_rd); return ret; } From 980ffe3b4e41ce5e43c3e8ae13f605f7d7b50b7f Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Fri, 14 Jan 2022 09:14:49 +0100 Subject: [PATCH 125/504] nrf5x: Fix DMA access race condition In multi-thread mode starting DMA in thread mode was prone to race condition resulting in infinite loop. It may happen on single core CPU with strict priority based tasks scheduler where ready high prio task never yields to ready low prio task (Mynewt). Sequence that failed (T1 - low priority task, T2 - high priority task) - T1 called start_dma() - T1 set _dcd.dma_running (DMA not started yet, context switch happens) - T2 took CPU and saw that _dcd.dma_running is set, so waits for _dcd.dma_running to be 0 - T1 never gets CPU again, DMA is not started T2 waits forever OSAL mutex resolves problem of DMA starting from thread-context. --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 6b2cd83fd..e70565a02 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -79,6 +79,9 @@ typedef struct } xfer_td_t; +static osal_mutex_def_t dcd_mutex_def; +static osal_mutex_t dcd_mutex; + // Data for managing dcd static struct { @@ -154,6 +157,7 @@ static void edpt_dma_start(volatile uint32_t* reg_startep) // Should be safe to blocking wait until previous DMA transfer complete uint8_t const rhport = 0; bool started = false; + osal_mutex_lock(dcd_mutex, OSAL_TIMEOUT_WAIT_FOREVER); while(!started) { // LDREX/STREX may be needed in form of std atomic (required C11) or @@ -170,6 +174,7 @@ static void edpt_dma_start(volatile uint32_t* reg_startep) // osal_yield(); } + osal_mutex_unlock(dcd_mutex); } } @@ -243,6 +248,7 @@ static void xact_in_dma(uint8_t epnum) void dcd_init (uint8_t rhport) { TU_LOG1("dcd init\r\n"); + dcd_mutex = osal_mutex_create(&dcd_mutex_def); (void) rhport; } From 36b6ed8ff9035ad0c2e75de92e08799dc3a4b7ed Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Fri, 14 Jan 2022 09:44:38 +0100 Subject: [PATCH 126/504] nrf5x: Fix EP OUT race conditions in OS build When two tasks entered dcd_edpt_xfer() it was possible that first disabled interrupt to setup total_len and actual_len but second task for another endpoint enabled interrupt between total_len and actual_len resulting in race condition with interrupt, hence mutex is added on top of interrupt being blocked. --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index e70565a02..024ea0d90 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -463,11 +463,17 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t xfer_td_t* xfer = get_td(epnum, dir); - dcd_int_disable(rhport); + if (!is_in_isr()) { + osal_mutex_lock(dcd_mutex, OSAL_TIMEOUT_WAIT_FOREVER); + dcd_int_disable(rhport); + } xfer->buffer = buffer; xfer->total_len = total_bytes; xfer->actual_len = 0; - dcd_int_enable(rhport); + if (!is_in_isr()) { + dcd_int_enable(rhport); + osal_mutex_unlock(dcd_mutex); + } // Control endpoint with zero-length packet and opposite direction to 1st request byte --> status stage bool const control_status = (epnum == 0 && total_bytes == 0 && dir != tu_edpt_dir(NRF_USBD->BMREQUESTTYPE)); From 3b66bbf6d5a1122a67b970288713febc740dbe49 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 19 Jan 2022 19:12:21 +0700 Subject: [PATCH 127/504] enable ci build for RX65X host example update comment for unit not ready 3a-00 additional sense --- examples/device/cdc_msc/src/msc_disk.c | 1 + examples/host/cdc_msc_hid/only.txt | 3 ++- examples/host/hid_controller/only.txt | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/device/cdc_msc/src/msc_disk.c b/examples/device/cdc_msc/src/msc_disk.c index 134bda392..3076192af 100644 --- a/examples/device/cdc_msc/src/msc_disk.c +++ b/examples/device/cdc_msc/src/msc_disk.c @@ -142,6 +142,7 @@ bool tud_msc_test_unit_ready_cb(uint8_t lun) // RAM disk is ready until ejected if (ejected) { + // Additional Sense 3A-00 is NOT_FOUND tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3a, 0x00); return false; } diff --git a/examples/host/cdc_msc_hid/only.txt b/examples/host/cdc_msc_hid/only.txt index db9a337e5..7fe4e3f5c 100644 --- a/examples/host/cdc_msc_hid/only.txt +++ b/examples/host/cdc_msc_hid/only.txt @@ -5,4 +5,5 @@ mcu:LPC40XX mcu:LPC43XX mcu:MIMXRT10XX mcu:RP2040 -mcu:MSP432E4 \ No newline at end of file +mcu:MSP432E4 +mcu:RX65X diff --git a/examples/host/hid_controller/only.txt b/examples/host/hid_controller/only.txt index db9a337e5..7fe4e3f5c 100644 --- a/examples/host/hid_controller/only.txt +++ b/examples/host/hid_controller/only.txt @@ -5,4 +5,5 @@ mcu:LPC40XX mcu:LPC43XX mcu:MIMXRT10XX mcu:RP2040 -mcu:MSP432E4 \ No newline at end of file +mcu:MSP432E4 +mcu:RX65X From d069ea1421eace1768157e76c44164262ed9a1e6 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Wed, 25 Aug 2021 10:41:07 +0200 Subject: [PATCH 128/504] vendor: Add tx callback Other drivers already have notification about data sent. It allows batter control in application on vendor protocol level. --- src/class/vendor/vendor_device.c | 1 + src/class/vendor/vendor_device.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index 8a4ca1d2e..02a4220be 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -247,6 +247,7 @@ bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint } else if ( ep_addr == p_itf->ep_in ) { + if (tud_vendor_tx_cb) tud_vendor_tx_cb(itf, xferred_bytes); // Send complete, try to send more if possible maybe_transmit(p_itf); } diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h index d71c2a3e9..75cb77f5b 100644 --- a/src/class/vendor/vendor_device.h +++ b/src/class/vendor/vendor_device.h @@ -71,6 +71,8 @@ static inline uint32_t tud_vendor_write_available (void); // Invoked when received new data TU_ATTR_WEAK void tud_vendor_rx_cb(uint8_t itf); +// Invoked when last rx transfer finished +TU_ATTR_WEAK void tud_vendor_tx_cb(uint8_t itf, uint32_t sent_bytes); //--------------------------------------------------------------------+ // Inline Functions From 4ca22156845162b69410a47a2b43e03ac552b9f3 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Wed, 25 Aug 2021 10:57:35 +0200 Subject: [PATCH 129/504] vendor: Add tx flush functionality So far tud_vendor_n_write() always flushed data. It requires to have whole vendor packed constructed before in one buffer. With this change data do get flushed when endpoint size is filled on write, when there is no enough data to fill endpoint data is not sent and subsequent calls to write functions can add more bytes. Vendor code needs to call tud_vendor_n_flush() when packet is ready to be sent. --- src/class/vendor/vendor_device.c | 16 +++++++++++++--- src/class/vendor/vendor_device.h | 7 +++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index 02a4220be..586822f39 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -113,7 +113,7 @@ void tud_vendor_n_read_flush (uint8_t itf) //--------------------------------------------------------------------+ // Write API //--------------------------------------------------------------------+ -static bool maybe_transmit(vendord_interface_t* p_itf) +static uint16_t maybe_transmit(vendord_interface_t* p_itf) { // skip if previous transfer not complete TU_VERIFY( !usbd_edpt_busy(TUD_OPT_RHPORT, p_itf->ep_in) ); @@ -123,14 +123,24 @@ static bool maybe_transmit(vendord_interface_t* p_itf) { TU_ASSERT( usbd_edpt_xfer(TUD_OPT_RHPORT, p_itf->ep_in, p_itf->epin_buf, count) ); } - return true; + return count; } uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize) { vendord_interface_t* p_itf = &_vendord_itf[itf]; uint16_t ret = tu_fifo_write_n(&p_itf->tx_ff, buffer, bufsize); - maybe_transmit(p_itf); + if (tu_fifo_count(&p_itf->tx_ff) >= CFG_TUD_VENDOR_EPSIZE) { + maybe_transmit(p_itf); + } + return ret; +} + +uint32_t tud_vendor_n_flush (uint8_t itf) +{ + vendord_interface_t* p_itf = &_vendord_itf[itf]; + uint32_t ret = maybe_transmit(p_itf); + return ret; } diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h index 75cb77f5b..4a873e5fc 100644 --- a/src/class/vendor/vendor_device.h +++ b/src/class/vendor/vendor_device.h @@ -52,6 +52,7 @@ uint32_t tud_vendor_n_write_available (uint8_t itf); static inline uint32_t tud_vendor_n_write_str (uint8_t itf, char const* str); +uint32_t tud_vendor_n_flush (uint8_t itf); //--------------------------------------------------------------------+ // Application API (Single Port) @@ -64,6 +65,7 @@ static inline void tud_vendor_read_flush (void); static inline uint32_t tud_vendor_write (void const* buffer, uint32_t bufsize); static inline uint32_t tud_vendor_write_str (char const* str); static inline uint32_t tud_vendor_write_available (void); +static inline uint32_t tud_vendor_flush (void); //--------------------------------------------------------------------+ // Application Callback API (weak is optional) @@ -123,6 +125,11 @@ static inline uint32_t tud_vendor_write_available (void) return tud_vendor_n_write_available(0); } +static inline uint32_t tud_vendor_flush (void) +{ + return tud_vendor_n_flush(0); +} + //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ From ae4d901d8351437c499cecef349b84af4bb6c239 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Thu, 20 Jan 2022 09:55:25 +0100 Subject: [PATCH 130/504] dcd_da1469x: Fix over-run/under-run mask Bit mask enabling/disabling over-run/unde-run was shifted by one nibble, so interrupt was never enabled. It did not force any issue as this situation could only happen on ISO endpoints without DMA. --- src/portable/dialog/da146xx/dcd_da146xx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/portable/dialog/da146xx/dcd_da146xx.c b/src/portable/dialog/da146xx/dcd_da146xx.c index 311119747..5713f5cca 100644 --- a/src/portable/dialog/da146xx/dcd_da146xx.c +++ b/src/portable/dialog/da146xx/dcd_da146xx.c @@ -935,13 +935,13 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) if (dir == TUSB_DIR_OUT) { regs->epc_out = epnum | USB_USB_EPC1_REG_USB_EP_EN_Msk | iso_mask; - USB->USB_RXMSK_REG |= 0x101 << (epnum - 1); + USB->USB_RXMSK_REG |= 0x11 << (epnum - 1); REG_SET_BIT(USB_MAMSK_REG, USB_M_RX_EV); } else { regs->epc_in = epnum | USB_USB_EPC1_REG_USB_EP_EN_Msk | iso_mask; - USB->USB_TXMSK_REG |= 0x101 << (epnum - 1); + USB->USB_TXMSK_REG |= 0x11 << (epnum - 1); REG_SET_BIT(USB_MAMSK_REG, USB_M_TX_EV); } } @@ -982,7 +982,7 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { regs->rxc = USB_USB_RXC1_REG_USB_FLUSH_Msk; regs->epc_out = 0; - USB->USB_RXMSK_REG &= ~(0x101 << (epnum - 1)); + USB->USB_RXMSK_REG &= ~(0x11 << (epnum - 1)); // Release DMA if needed if (_dcd.dma_ep[TUSB_DIR_OUT] == epnum) { @@ -994,7 +994,7 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { regs->txc = USB_USB_TXC1_REG_USB_FLUSH_Msk; regs->epc_in = 0; - USB->USB_TXMSK_REG &= ~(0x101 << (epnum - 1)); + USB->USB_TXMSK_REG &= ~(0x11 << (epnum - 1)); // Release DMA if needed if (_dcd.dma_ep[TUSB_DIR_IN] == epnum) { From 7b078367e82fae8ef4ec094f6db9e584db82f06a Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Thu, 20 Jan 2022 09:58:40 +0100 Subject: [PATCH 131/504] dcd_da1469x: Re-enable RX after resume Going to suspend states disable reception on non-0 RX endpoints. Now when USB resume condition is detected, all RX endpoints with pending transfers are resumed. --- src/portable/dialog/da146xx/dcd_da146xx.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/portable/dialog/da146xx/dcd_da146xx.c b/src/portable/dialog/da146xx/dcd_da146xx.c index 5713f5cca..02fad8165 100644 --- a/src/portable/dialog/da146xx/dcd_da146xx.c +++ b/src/portable/dialog/da146xx/dcd_da146xx.c @@ -733,6 +733,15 @@ static void handle_alt_ev(void) set_nfsr(NFSR_NODE_OPERATIONAL); USB->USB_ALTMSK_REG = USB_USB_ALTMSK_REG_USB_M_RESET_Msk | USB_USB_ALTMSK_REG_USB_M_SD3_Msk; + // Re-enable reception of endpoint with pending transfer + for (int epnum = 1; epnum <= 3; ++epnum) + { + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); + if (xfer->total_len > xfer->transferred) + { + start_rx_packet(xfer); + } + } dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); } } From a80f23711eefb8d59f76bc70183705d7c368de64 Mon Sep 17 00:00:00 2001 From: Iain Sharp Date: Mon, 24 Jan 2022 20:56:13 +0000 Subject: [PATCH 132/504] Some platforms require SDKs and use of cmake --- docs/reference/getting_started.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/reference/getting_started.rst b/docs/reference/getting_started.rst index 875372c81..7f2c03faa 100644 --- a/docs/reference/getting_started.rst +++ b/docs/reference/getting_started.rst @@ -52,6 +52,8 @@ Some TinyUSB examples also requires external submodule libraries in ``/lib`` suc In addition, MCU driver submodule is also needed to provide low-level MCU peripheral's driver. Luckily, it will be fetched if needed when you run the ``make`` to build your board. +Some modules will also require a module-specific SDK (e.g. RP2040) or binary (e.g. Sony Spresense) to build examples. + Note: some examples especially those that uses Vendor class (e.g webUSB) may requires udev permission on Linux (and/or macOS) to access usb device. It depends on your OS distro, typically copy ``/examples/device/99-tinyusb.rules`` file to /etc/udev/rules.d/ then run ``sudo udevadm control --reload-rules && sudo udevadm trigger`` is good enough. Build @@ -63,6 +65,8 @@ To build example, first change directory to an example folder. $ cd examples/device/cdc_msc +Some modules (e.g. RP2040 and ESP32s2) require the project makefiles to be customized using CMake. If necessary apply any setup steps for the platform's SDK. + Then compile with ``make BOARD=[board_name] all``\ , for example .. code-block:: From 578a12328290592aa315f13339cbbd7d31a6bafd Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 26 Jan 2022 12:59:53 +0700 Subject: [PATCH 133/504] fix mynewt build sunxi --- src/portable/sunxi/dcd_sunxi_musb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/portable/sunxi/dcd_sunxi_musb.c b/src/portable/sunxi/dcd_sunxi_musb.c index 89464c5b2..cf93c9bc4 100644 --- a/src/portable/sunxi/dcd_sunxi_musb.c +++ b/src/portable/sunxi/dcd_sunxi_musb.c @@ -28,6 +28,9 @@ #include #include "tusb_option.h" + +#if TUSB_OPT_DEVICE_ENABLED && CFG_TUSB_MCU == OPT_MCU_F1C100S + #include "osal/osal.h" #include #include @@ -38,7 +41,6 @@ typedef uint32_t u32; typedef uint16_t u16; typedef uint8_t u8; -#if TUSB_OPT_DEVICE_ENABLED && CFG_TUSB_MCU == OPT_MCU_F1C100S #define REQUEST_TYPE_INVALID (0xFFu) From 6085999e2be6974bfb59475213331ba21a7b5872 Mon Sep 17 00:00:00 2001 From: "Man, Jianting (Meco)" <920369182@qq.com> Date: Wed, 26 Jan 2022 20:08:34 -0500 Subject: [PATCH 134/504] add rt-thread's tinyusb repo address --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index f21cd9bca..8cf4a98da 100644 --- a/README.rst +++ b/README.rst @@ -91,7 +91,7 @@ TinyUSB is completely thread-safe by pushing all Interrupt Service Request (ISR) - **No OS** - **FreeRTOS** -- `RT-Thread `_ +- `RT-Thread `_: `repo `_ - **Mynewt** Due to the newt package build system, Mynewt examples are better to be on its `own repo `_ Local Docs From a4bc6075cef1685ecc896730e704400b35e2392a Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Sun, 21 Nov 2021 16:17:50 +0900 Subject: [PATCH 135/504] Add HCD functions for KL25Z --- hw/bsp/frdm_kl25z/frdm_kl25z.c | 5 + src/portable/nxp/khci/hcd_khci.c | 475 +++++++++++++++++++++++++++++++ 2 files changed, 480 insertions(+) create mode 100644 src/portable/nxp/khci/hcd_khci.c diff --git a/hw/bsp/frdm_kl25z/frdm_kl25z.c b/hw/bsp/frdm_kl25z/frdm_kl25z.c index 72982ed8a..2930ed56e 100644 --- a/hw/bsp/frdm_kl25z/frdm_kl25z.c +++ b/hw/bsp/frdm_kl25z/frdm_kl25z.c @@ -39,7 +39,12 @@ //--------------------------------------------------------------------+ void USB0_IRQHandler(void) { +#if TUSB_OPT_HOST_ENABLED + tuh_int_handler(0); +#endif +#if TUSB_OPT_DEVICE_ENABLED tud_int_handler(0); +#endif } //--------------------------------------------------------------------+ diff --git a/src/portable/nxp/khci/hcd_khci.c b/src/portable/nxp/khci/hcd_khci.c new file mode 100644 index 000000000..877c4813b --- /dev/null +++ b/src/portable/nxp/khci/hcd_khci.c @@ -0,0 +1,475 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 Koji Kitayama + * + * 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 TUSB_OPT_HOST_ENABLED && ( \ + ( CFG_TUSB_MCU == OPT_MCU_MKL25ZXX ) || ( CFG_TUSB_MCU == OPT_MCU_K32L2BXX ) \ + ) + +#include "fsl_device_registers.h" +#define KHCI USB0 + +#include "host/hcd.h" + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ + +enum { + TOK_PID_OUT = 0x1u, + TOK_PID_IN = 0x9u, + TOK_PID_SETUP = 0xDu, + TOK_PID_DATA0 = 0x3u, + TOK_PID_DATA1 = 0xbu, + TOK_PID_ACK = 0x2u, + TOK_PID_STALL = 0xeu, + TOK_PID_NAK = 0xau, + TOK_PID_BUSTO = 0x0u, + TOK_PID_ERR = 0xfu, +}; + +typedef struct TU_ATTR_PACKED +{ + union { + uint32_t head; + struct { + union { + struct { + uint16_t : 2; + __IO uint16_t tok_pid : 4; + uint16_t data : 1; + __IO uint16_t own : 1; + uint16_t : 8; + }; + struct { + uint16_t : 2; + uint16_t bdt_stall : 1; + uint16_t dts : 1; + uint16_t ninc : 1; + uint16_t keep : 1; + uint16_t : 10; + }; + }; + __IO uint16_t bc : 10; + uint16_t : 6; + }; + }; + uint8_t *addr; +}buffer_descriptor_t; + +TU_VERIFY_STATIC( sizeof(buffer_descriptor_t) == 8, "size is not correct" ); + +typedef struct TU_ATTR_PACKED +{ + union { + uint32_t state; + struct { + uint32_t max_packet_size :11; + uint32_t : 5; + uint32_t odd : 1; + uint32_t :15; + }; + }; + uint16_t length; + uint16_t remaining; +} endpoint_state_t; + +TU_VERIFY_STATIC( sizeof(endpoint_state_t) == 8, "size is not correct" ); + +typedef struct TU_ATTR_PACKED +{ + uint8_t dev_addr; + uint8_t ep_addr; + uint16_t max_packet_size; + union { + uint8_t flags; + struct { + uint8_t data : 1; + uint8_t xfer : 2; + uint8_t : 0; + }; + }; +} pipe_state_t; + + +typedef struct +{ + union { + /* [#EP][OUT,IN][EVEN,ODD] */ + buffer_descriptor_t bdt[16][2][2]; + uint16_t bda[512]; + }; + endpoint_state_t endpoint[2]; + pipe_state_t pipe[HCD_MAX_XFER]; +} hcd_data_t; + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ +// BDT(Buffer Descriptor Table) must be 256-byte aligned +CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(512) static hcd_data_t _hcd; + +TU_VERIFY_STATIC( sizeof(_hcd.bdt) == 512, "size is not correct" ); + +static pipe_state_t *find_pipe(uint8_t dev_addr, uint8_t ep_addr) +{ + /* Find the target pipe */ + pipe_state_t *p = _hcd.pipe; + pipe_state_t *end = p + HCD_MAX_XFER; + for (;p != end; ++p) { + if ((p->dev_addr == dev_addr) && (p->ep_addr != ep_addr)) + return p; + } + return NULL; +} + +static int prepare_packets(uint8_t rhport, uint_fast8_t dir_in, uint8_t* buffer, uint_fast16_t total_bytes) +{ + (void)rhport; + const unsigned dir_tx = dir_in ? 0 : 1; + endpoint_state_t *ep = &_hcd.endpoint[dir_tx]; + buffer_descriptor_t *bd = &_hcd.bdt[0][dir_tx][ep->odd]; + TU_ASSERT(0 == bd->own, 0); + + ep->length = total_bytes; + ep->remaining = total_bytes; + + int num_pkts = 0; /* The number of prepared packets */ + const unsigned mps = ep->max_packet_size; + if (total_bytes > mps) { + buffer_descriptor_t *next = ep->odd ? bd - 1: bd + 1; + /* When total_bytes is greater than the max packet size, + * it prepares to the next transfer to avoid NAK in advance. */ + next->bc = total_bytes >= 2 * mps ? mps: total_bytes - mps; + next->addr = buffer + mps; + next->own = 1; + ++num_pkts; + } + bd->bc = total_bytes >= mps ? mps: total_bytes; + bd->addr = buffer; + __DSB(); + bd->own = 1; /* This bit must be set last */ + ++num_pkts; + return num_pkts; +} + +static void process_tokdne(uint8_t rhport) +{ + (void)rhport; + const unsigned s = KHCI->STAT; + KHCI->ISTAT = USB_ISTAT_TOKDNE_MASK; /* fetch the next token if received */ + + uint8_t const epnum = (s >> USB_STAT_ENDP_SHIFT); + TU_ASSERT(0 == epnum,); + uint8_t const dir_in = (s & USB_STAT_TX_MASK) ? TUSB_DIR_OUT: TUSB_DIR_IN; + unsigned const odd = (s & USB_STAT_ODD_MASK) ? 1 : 0; + + buffer_descriptor_t *bd = (buffer_descriptor_t *)&_hcd.bda[s]; + endpoint_state_t *ep = &_hcd.endpoint[s >> 3]; + + /* fetch status before discarded by the next steps */ + const unsigned pid = bd->tok_pid; + + /* reset values for a next transfer */ + bd->bdt_stall = 0; + bd->dts = 1; + bd->ninc = 0; + bd->keep = 0; + /* Update the odd variable to prepare for the next transfer */ + ep->odd = odd ^ 1; + + const unsigned bc = bd->bc; + const unsigned remaining = ep->remaining - bc; + if ((TOK_PID_DATA0 == pid) || (TOK_PID_DATA1 == pid) || (TOK_PID_ACK == pid)) { + /* Go on the next packet transfer */ + if (remaining && bc == ep->max_packet_size) { + ep->remaining = remaining; + const int next_remaining = remaining - ep->max_packet_size; + if (next_remaining > 0) { + /* Prepare to the after next transfer */ + bd->addr += ep->max_packet_size * 2; + bd->bc = next_remaining > ep->max_packet_size ? ep->max_packet_size: next_remaining; + __DSB(); + bd->own = 1; /* This bit must be set last */ + while (KHCI->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) ; + KHCI->TOKEN = KHCI->TOKEN; /* Queue the same token as the last */ + } + return; + } + } + const unsigned length = ep->length; + xfer_result_t result; + switch (pid) { + default: + result = XFER_RESULT_SUCCESS; + break; + case TOK_PID_STALL: + result = XFER_RESULT_STALLED; + break; + case TOK_PID_NAK: + case TOK_PID_ERR: + case TOK_PID_BUSTO: + result = XFER_RESULT_FAILED; + break; + } + hcd_event_xfer_complete(KHCI->ADDR & USB_ADDR_ADDR_MASK, + tu_edpt_addr(KHCI->TOKEN & USB_TOKEN_TOKENENDPT_MASK, dir_in), + length - remaining, result, true); +} + +static void process_attach(uint8_t rhport) +{ + unsigned ctl = KHCI->CTL; + if (!(ctl & USB_CTL_JSTATE_MASK)) { + /* The attached device is a low speed device. */ + KHCI->ADDR = USB_ADDR_LSEN_MASK; + KHCI->ENDPOINT[0].ENDPT = USB_ENDPT_HOSTWOHUB_MASK; + } + hcd_event_device_attach(rhport, true); +} + +/*------------------------------------------------------------------*/ +/* Host API + *------------------------------------------------------------------*/ +bool hcd_init(uint8_t rhport) +{ + (void)rhport; + + KHCI->USBTRC0 |= USB_USBTRC0_USBRESET_MASK; + while (KHCI->USBTRC0 & USB_USBTRC0_USBRESET_MASK); + + tu_memclr(&_hcd, sizeof(_hcd)); + KHCI->USBTRC0 |= TU_BIT(6); /* software must set this bit to 1 */ + KHCI->BDTPAGE1 = (uint8_t)((uintptr_t)_hcd.bdt >> 8); + KHCI->BDTPAGE2 = (uint8_t)((uintptr_t)_hcd.bdt >> 16); + KHCI->BDTPAGE3 = (uint8_t)((uintptr_t)_hcd.bdt >> 24); + + KHCI->USBCTRL &= ~USB_USBCTRL_SUSP_MASK; + KHCI->CTL |= USB_CTL_ODDRST_MASK; + for (unsigned i = 0; i < 16; ++i) { + KHCI->ENDPOINT[i].ENDPT = 0; + } + const endpoint_state_t ep0 = { + .max_packet_size = CFG_TUD_ENDPOINT0_SIZE, + .odd = 0, + .length = 0, + .remaining = 0, + }; + _hcd.endpoint[0] = ep0; + _hcd.endpoint[1] = ep0; + KHCI->CTL &= ~USB_CTL_ODDRST_MASK; + + KHCI->SOFTHLD = 74; /* for 64-byte packets */ + KHCI->CTL = USB_CTL_HOSTMODEEN_MASK | USB_CTL_SE0_MASK; + KHCI->USBCTRL = USB_USBCTRL_PDE_MASK; + + NVIC_ClearPendingIRQ(USB0_IRQn); + KHCI->INTEN = USB_INTEN_ATTACHEN_MASK; + return true; +} + +void hcd_int_enable(uint8_t rhport) +{ + (void)rhport; + NVIC_EnableIRQ(USB0_IRQn); +} + +void hcd_int_disable(uint8_t rhport) +{ + (void)rhport; + NVIC_DisableIRQ(USB0_IRQn); +} + +uint32_t hcd_frame_number(uint8_t rhport) +{ + (void)rhport; + uint32_t frmnum = KHCI->FRMNUML; + frmnum |= KHCI->FRMNUMH << 8u; + return frmnum; +} + +/*--------------------------------------------------------------------+ + * Port API + *--------------------------------------------------------------------+ */ +bool hcd_port_connect_status(uint8_t rhport) +{ + (void)rhport; + return false; +} + +void hcd_port_reset(uint8_t rhport) +{ + (void)rhport; + KHCI->CTL &= ~USB_CTL_USBENSOFEN_MASK; + KHCI->CTL |= USB_CTL_RESET_MASK; + unsigned cnt = SystemCoreClock / 100; + while (cnt--) __NOP(); + KHCI->CTL &= ~USB_CTL_RESET_MASK; + KHCI->CTL |= USB_CTL_USBENSOFEN_MASK; +} + +tusb_speed_t hcd_port_speed_get(uint8_t rhport) +{ + (void)rhport; + tusb_speed_t speed = TUSB_SPEED_FULL; + const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn); + NVIC_DisableIRQ(USB0_IRQn); + if (KHCI->ADDR & USB_ADDR_LSEN_MASK) + speed = TUSB_SPEED_LOW; + if (ie) NVIC_EnableIRQ(USB0_IRQn); + return speed; +} + +void hcd_device_close(uint8_t rhport, uint8_t dev_addr) +{ + (void)rhport; + pipe_state_t *p = _hcd.pipe; + pipe_state_t *end = p + HCD_MAX_XFER; + for (;p != end; ++p) { + if (p->dev_addr == dev_addr) + tu_memclr(p, sizeof(*p)); + } +} + +//--------------------------------------------------------------------+ +// Endpoints API +//--------------------------------------------------------------------+ +bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) +{ + (void)rhport; + const unsigned rx_odd = _hcd.endpoint[0].odd; + const unsigned tx_odd = _hcd.endpoint[1].odd; + TU_ASSERT(0 == _hcd.bdt[0][0][tx_odd].own); + + const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn); + NVIC_DisableIRQ(USB0_IRQn); + + _hcd.bdt[0][0][rx_odd ].data = 1; + _hcd.bdt[0][0][rx_odd ^ 1].data = 0; + _hcd.bdt[0][1][tx_odd ].data = 0; + _hcd.bdt[0][1][tx_odd ^ 1].data = 1; + + unsigned hostwohub = KHCI->ENDPOINT[0].ENDPT & USB_ENDPT_HOSTWOHUB_MASK; + KHCI->ENDPOINT[0].ENDPT = hostwohub | + USB_ENDPT_EPHSHK_MASK | USB_ENDPT_EPRXEN_MASK | USB_ENDPT_EPTXEN_MASK; + bool ret = false; + if (prepare_packets(rhport, TUSB_DIR_OUT, (void*)(uintptr_t)setup_packet, 8)) { + KHCI->ADDR = (KHCI->ADDR & USB_ADDR_LSEN_MASK) | dev_addr; + while (KHCI->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) ; + KHCI->TOKEN = (TOK_PID_SETUP << USB_TOKEN_TOKENPID_SHIFT); + ret = true; + } + if (ie) NVIC_EnableIRQ(USB0_IRQn); + return ret; +} + +bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) +{ + (void)rhport; + /* Find a free pipe */ + pipe_state_t *p = _hcd.pipe; + pipe_state_t *end = p + HCD_MAX_XFER; + for (;p < end && p->dev_addr; ++p) ; + if (p == end) return false; + p->dev_addr = dev_addr; + p->ep_addr = ep_desc->bEndpointAddress; + p->max_packet_size = ep_desc->wMaxPacketSize; + p->xfer = ep_desc->bmAttributes.xfer; + p->data = 0; + return true; +} + +bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) +{ + (void)rhport; + const unsigned dir_in = tu_edpt_dir(ep_addr); + const unsigned odd = _hcd.endpoint[dir_in ^ 1].odd; + buffer_descriptor_t *bd = _hcd.bdt[0][dir_in ^ 1]; + TU_ASSERT(0 == bd[odd].own); + + unsigned flags = USB_ENDPT_EPHSHK_MASK | USB_ENDPT_EPRXEN_MASK | USB_ENDPT_EPTXEN_MASK; + if (tu_edpt_number(ep_addr)) { + pipe_state_t *p = find_pipe(dev_addr, ep_addr); + if (!p) return false; + bd[odd ].data = p->data; + bd[odd ^ 1].data = p->data ^ 1; + bd[odd ^ 1].own = 0; + flags |= USB_ENDPT_EPCTLDIS_MASK; + /* Disable retry for a interrupt transfer. */ + if (TUSB_XFER_INTERRUPT == p->xfer) + flags |= USB_ENDPT_RETRYDIS_MASK; + } + unsigned hostwohub = KHCI->ENDPOINT[0].ENDPT & USB_ENDPT_HOSTWOHUB_MASK; + KHCI->ENDPOINT[0].ENDPT = hostwohub | flags; + int num_pkts = prepare_packets(rhport, dir_in, buffer, buflen); + if (!num_pkts) return false; + KHCI->ADDR = (KHCI->ADDR & USB_ADDR_LSEN_MASK) | dev_addr; + const unsigned token = tu_edpt_number(ep_addr) | + ((dir_in ? TOK_PID_IN: TOK_PID_OUT) << USB_TOKEN_TOKENPID_SHIFT); + const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn); + NVIC_DisableIRQ(USB0_IRQn); + do { + while (KHCI->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) ; + KHCI->TOKEN = token; + } while (--num_pkts); + if (ie) NVIC_EnableIRQ(USB0_IRQn); + return true; +} + +bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) +{ + if (!tu_edpt_number(ep_addr)) return true; + pipe_state_t *p = find_pipe(dev_addr, ep_addr); + if (!p) return false; + p->data = 0; /* Reset data toggle */ + return true; +} + +/*--------------------------------------------------------------------+ + * ISR + *--------------------------------------------------------------------+*/ +void hcd_int_handler(uint8_t rhport) +{ + uint32_t is = KHCI->ISTAT; + uint32_t msk = KHCI->INTEN; + + /* clear disabled interrupts */ + KHCI->ISTAT = is & ~msk; + is &= msk; + + if (is & USB_ISTAT_ATTACH_MASK) { + process_attach(rhport); + } + if (is & USB_ISTAT_STALL_MASK) { + KHCI->ISTAT = USB_ISTAT_STALL_MASK; + } + if (is & USB_ISTAT_TOKDNE_MASK) { + process_tokdne(rhport); + } +} + +#endif From cdab869472e18d393d43769c8a087ff1e69deb02 Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Wed, 29 Dec 2021 21:45:32 +0900 Subject: [PATCH 136/504] Fix handling control transfer --- src/portable/nxp/khci/hcd_khci.c | 135 ++++++++++++++++++++----------- 1 file changed, 90 insertions(+), 45 deletions(-) diff --git a/src/portable/nxp/khci/hcd_khci.c b/src/portable/nxp/khci/hcd_khci.c index 877c4813b..937d69f9b 100644 --- a/src/portable/nxp/khci/hcd_khci.c +++ b/src/portable/nxp/khci/hcd_khci.c @@ -88,10 +88,9 @@ typedef struct TU_ATTR_PACKED union { uint32_t state; struct { - uint32_t max_packet_size :11; - uint32_t : 5; - uint32_t odd : 1; - uint32_t :15; + uint32_t pipenum:16; + uint32_t odd : 1; + uint32_t : 0; }; }; uint16_t length; @@ -125,6 +124,7 @@ typedef struct }; endpoint_state_t endpoint[2]; pipe_state_t pipe[HCD_MAX_XFER]; + bool need_reset; /* The device has not been reset after connection. */ } hcd_data_t; //--------------------------------------------------------------------+ @@ -135,31 +135,34 @@ CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(512) static hcd_data_t _hcd; TU_VERIFY_STATIC( sizeof(_hcd.bdt) == 512, "size is not correct" ); -static pipe_state_t *find_pipe(uint8_t dev_addr, uint8_t ep_addr) +int find_pipe(uint8_t dev_addr, uint8_t ep_addr) { /* Find the target pipe */ - pipe_state_t *p = _hcd.pipe; - pipe_state_t *end = p + HCD_MAX_XFER; - for (;p != end; ++p) { - if ((p->dev_addr == dev_addr) && (p->ep_addr != ep_addr)) - return p; + int num; + if (0 == tu_edpt_number(ep_addr)) ep_addr = 0; + for (num = 0; num < HCD_MAX_XFER; ++num) { + pipe_state_t *p = &_hcd.pipe[num]; + if ((p->dev_addr == dev_addr) && (p->ep_addr == ep_addr)) + return num; } - return NULL; + return -1; } -static int prepare_packets(uint8_t rhport, uint_fast8_t dir_in, uint8_t* buffer, uint_fast16_t total_bytes) +static int prepare_packets(int pipenum, + uint_fast8_t dir_in, uint8_t* buffer, + uint_fast16_t total_bytes) { - (void)rhport; const unsigned dir_tx = dir_in ? 0 : 1; endpoint_state_t *ep = &_hcd.endpoint[dir_tx]; buffer_descriptor_t *bd = &_hcd.bdt[0][dir_tx][ep->odd]; TU_ASSERT(0 == bd->own, 0); + ep->pipenum = pipenum; ep->length = total_bytes; ep->remaining = total_bytes; int num_pkts = 0; /* The number of prepared packets */ - const unsigned mps = ep->max_packet_size; + const unsigned mps = _hcd.pipe[pipenum].max_packet_size; if (total_bytes > mps) { buffer_descriptor_t *next = ep->odd ? bd - 1: bd + 1; /* When total_bytes is greater than the max packet size, @@ -174,6 +177,7 @@ static int prepare_packets(uint8_t rhport, uint_fast8_t dir_in, uint8_t* buffer, __DSB(); bd->own = 1; /* This bit must be set last */ ++num_pkts; + // TU_LOG1("BD pipe=%d %d %lx %x\n", pipenum, num_pkts, bd->head, (uintptr_t)bd->addr); return num_pkts; } @@ -182,12 +186,13 @@ static void process_tokdne(uint8_t rhport) (void)rhport; const unsigned s = KHCI->STAT; KHCI->ISTAT = USB_ISTAT_TOKDNE_MASK; /* fetch the next token if received */ - uint8_t const epnum = (s >> USB_STAT_ENDP_SHIFT); TU_ASSERT(0 == epnum,); uint8_t const dir_in = (s & USB_STAT_TX_MASK) ? TUSB_DIR_OUT: TUSB_DIR_IN; unsigned const odd = (s & USB_STAT_ODD_MASK) ? 1 : 0; + // TU_LOG1("TOKDNE %x\n", s); + buffer_descriptor_t *bd = (buffer_descriptor_t *)&_hcd.bda[s]; endpoint_state_t *ep = &_hcd.endpoint[s >> 3]; @@ -204,19 +209,24 @@ static void process_tokdne(uint8_t rhport) const unsigned bc = bd->bc; const unsigned remaining = ep->remaining - bc; + pipe_state_t *pipe = &_hcd.pipe[ep->pipenum]; + + // TU_LOG1(" pid %x bc %x remaining %d\n", pid, bc, remaining); if ((TOK_PID_DATA0 == pid) || (TOK_PID_DATA1 == pid) || (TOK_PID_ACK == pid)) { /* Go on the next packet transfer */ - if (remaining && bc == ep->max_packet_size) { + if (remaining && bc == pipe->max_packet_size) { ep->remaining = remaining; - const int next_remaining = remaining - ep->max_packet_size; + const int next_remaining = remaining - pipe->max_packet_size; if (next_remaining > 0) { /* Prepare to the after next transfer */ - bd->addr += ep->max_packet_size * 2; - bd->bc = next_remaining > ep->max_packet_size ? ep->max_packet_size: next_remaining; + bd->addr += pipe->max_packet_size * 2; + bd->bc = next_remaining > pipe->max_packet_size ? pipe->max_packet_size: next_remaining; __DSB(); bd->own = 1; /* This bit must be set last */ while (KHCI->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) ; KHCI->TOKEN = KHCI->TOKEN; /* Queue the same token as the last */ + } else if (dir_in) { + KHCI->TOKEN = KHCI->TOKEN; } return; } @@ -236,7 +246,7 @@ static void process_tokdne(uint8_t rhport) result = XFER_RESULT_FAILED; break; } - hcd_event_xfer_complete(KHCI->ADDR & USB_ADDR_ADDR_MASK, + hcd_event_xfer_complete(pipe->dev_addr, tu_edpt_addr(KHCI->TOKEN & USB_TOKEN_TOKENENDPT_MASK, dir_in), length - remaining, result, true); } @@ -252,6 +262,21 @@ static void process_attach(uint8_t rhport) hcd_event_device_attach(rhport, true); } +static void process_bus_reset(uint8_t rhport) +{ + KHCI->USBCTRL &= ~USB_USBCTRL_SUSP_MASK; + KHCI->CTL &= ~USB_CTL_USBENSOFEN_MASK; + KHCI->ADDR = 0; + KHCI->ENDPOINT[0].ENDPT = 0; + + hcd_event_device_remove(rhport, true); + + buffer_descriptor_t *bd = _hcd.bdt[0][0]; + for (unsigned i = 0; i < 2; ++i, ++bd) { + bd->head = 0; + } +} + /*------------------------------------------------------------------*/ /* Host API *------------------------------------------------------------------*/ @@ -273,14 +298,6 @@ bool hcd_init(uint8_t rhport) for (unsigned i = 0; i < 16; ++i) { KHCI->ENDPOINT[i].ENDPT = 0; } - const endpoint_state_t ep0 = { - .max_packet_size = CFG_TUD_ENDPOINT0_SIZE, - .odd = 0, - .length = 0, - .remaining = 0, - }; - _hcd.endpoint[0] = ep0; - _hcd.endpoint[1] = ep0; KHCI->CTL &= ~USB_CTL_ODDRST_MASK; KHCI->SOFTHLD = 74; /* for 64-byte packets */ @@ -288,7 +305,8 @@ bool hcd_init(uint8_t rhport) KHCI->USBCTRL = USB_USBCTRL_PDE_MASK; NVIC_ClearPendingIRQ(USB0_IRQn); - KHCI->INTEN = USB_INTEN_ATTACHEN_MASK; + KHCI->INTEN = USB_INTEN_ATTACHEN_MASK | USB_INTEN_TOKDNEEN_MASK | + USB_INTEN_USBRSTEN_MASK | USB_INTEN_ERROREN_MASK | USB_INTEN_STALLEN_MASK; return true; } @@ -307,9 +325,12 @@ void hcd_int_disable(uint8_t rhport) uint32_t hcd_frame_number(uint8_t rhport) { (void)rhport; + /* The device must be reset at least once after connection + * in order to start the frame counter. */ + if (_hcd.need_reset) hcd_port_reset(rhport); uint32_t frmnum = KHCI->FRMNUML; frmnum |= KHCI->FRMNUMH << 8u; - return frmnum; + return frmnum; } /*--------------------------------------------------------------------+ @@ -318,6 +339,8 @@ uint32_t hcd_frame_number(uint8_t rhport) bool hcd_port_connect_status(uint8_t rhport) { (void)rhport; + if (KHCI->ISTAT & USB_ISTAT_ATTACH_MASK) + return true; return false; } @@ -330,6 +353,7 @@ void hcd_port_reset(uint8_t rhport) while (cnt--) __NOP(); KHCI->CTL &= ~USB_CTL_RESET_MASK; KHCI->CTL |= USB_CTL_USBENSOFEN_MASK; + _hcd.need_reset = false; } tusb_speed_t hcd_port_speed_get(uint8_t rhport) @@ -347,8 +371,8 @@ tusb_speed_t hcd_port_speed_get(uint8_t rhport) void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { (void)rhport; - pipe_state_t *p = _hcd.pipe; - pipe_state_t *end = p + HCD_MAX_XFER; + pipe_state_t *p = &_hcd.pipe[0]; + pipe_state_t *end = &_hcd.pipe[HCD_MAX_XFER]; for (;p != end; ++p) { if (p->dev_addr == dev_addr) tu_memclr(p, sizeof(*p)); @@ -361,10 +385,14 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr) bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) { (void)rhport; + // TU_LOG1("SETUP %u\n", dev_addr); const unsigned rx_odd = _hcd.endpoint[0].odd; const unsigned tx_odd = _hcd.endpoint[1].odd; TU_ASSERT(0 == _hcd.bdt[0][0][tx_odd].own); + int num = find_pipe(dev_addr, 0); + if (num < 0) return false; + const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn); NVIC_DisableIRQ(USB0_IRQn); @@ -377,26 +405,31 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet KHCI->ENDPOINT[0].ENDPT = hostwohub | USB_ENDPT_EPHSHK_MASK | USB_ENDPT_EPRXEN_MASK | USB_ENDPT_EPTXEN_MASK; bool ret = false; - if (prepare_packets(rhport, TUSB_DIR_OUT, (void*)(uintptr_t)setup_packet, 8)) { + if (prepare_packets(num, TUSB_DIR_OUT, (void*)(uintptr_t)setup_packet, 8)) { KHCI->ADDR = (KHCI->ADDR & USB_ADDR_LSEN_MASK) | dev_addr; while (KHCI->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) ; KHCI->TOKEN = (TOK_PID_SETUP << USB_TOKEN_TOKENPID_SHIFT); ret = true; } if (ie) NVIC_EnableIRQ(USB0_IRQn); + return ret; } bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) { (void)rhport; + uint8_t const ep_addr = ep_desc->bEndpointAddress; + // TU_LOG1("O %u %x\n", dev_addr, ep_addr); /* Find a free pipe */ - pipe_state_t *p = _hcd.pipe; - pipe_state_t *end = p + HCD_MAX_XFER; - for (;p < end && p->dev_addr; ++p) ; - if (p == end) return false; + pipe_state_t *p = &_hcd.pipe[0]; + if (dev_addr || ep_addr) { + pipe_state_t *end = &_hcd.pipe[HCD_MAX_XFER]; + for (++p; p < end && (p->dev_addr || p->ep_addr); ++p) ; + if (p == end) return false; + } p->dev_addr = dev_addr; - p->ep_addr = ep_desc->bEndpointAddress; + p->ep_addr = ep_addr; p->max_packet_size = ep_desc->wMaxPacketSize; p->xfer = ep_desc->bmAttributes.xfer; p->data = 0; @@ -406,15 +439,18 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) { (void)rhport; + // TU_LOG1("X %u %x %d\n", dev_addr, ep_addr, buflen); const unsigned dir_in = tu_edpt_dir(ep_addr); const unsigned odd = _hcd.endpoint[dir_in ^ 1].odd; buffer_descriptor_t *bd = _hcd.bdt[0][dir_in ^ 1]; TU_ASSERT(0 == bd[odd].own); + int num = find_pipe(dev_addr, ep_addr); + if (num < 0) return false; + unsigned flags = USB_ENDPT_EPHSHK_MASK | USB_ENDPT_EPRXEN_MASK | USB_ENDPT_EPTXEN_MASK; if (tu_edpt_number(ep_addr)) { - pipe_state_t *p = find_pipe(dev_addr, ep_addr); - if (!p) return false; + pipe_state_t *p = &_hcd.pipe[num]; bd[odd ].data = p->data; bd[odd ^ 1].data = p->data ^ 1; bd[odd ^ 1].own = 0; @@ -425,7 +461,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * } unsigned hostwohub = KHCI->ENDPOINT[0].ENDPT & USB_ENDPT_HOSTWOHUB_MASK; KHCI->ENDPOINT[0].ENDPT = hostwohub | flags; - int num_pkts = prepare_packets(rhport, dir_in, buffer, buflen); + int num_pkts = prepare_packets(num, dir_in, buffer, buflen); if (!num_pkts) return false; KHCI->ADDR = (KHCI->ADDR & USB_ADDR_LSEN_MASK) | dev_addr; const unsigned token = tu_edpt_number(ep_addr) | @@ -435,7 +471,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * do { while (KHCI->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) ; KHCI->TOKEN = token; - } while (--num_pkts); + } while (--num_pkts && !dir_in); if (ie) NVIC_EnableIRQ(USB0_IRQn); return true; } @@ -443,8 +479,9 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) { if (!tu_edpt_number(ep_addr)) return true; - pipe_state_t *p = find_pipe(dev_addr, ep_addr); - if (!p) return false; + int num = find_pipe(dev_addr, ep_addr); + if (num < 0) return false; + pipe_state_t *p = &_hcd.pipe[num]; p->data = 0; /* Reset data toggle */ return true; } @@ -457,13 +494,21 @@ void hcd_int_handler(uint8_t rhport) uint32_t is = KHCI->ISTAT; uint32_t msk = KHCI->INTEN; + // TU_LOG1("S %lx\n", is); + /* clear disabled interrupts */ - KHCI->ISTAT = is & ~msk; + KHCI->ISTAT = is & ~msk & ~USB_ISTAT_TOKDNE_MASK; is &= msk; if (is & USB_ISTAT_ATTACH_MASK) { + KHCI->INTEN = (msk & ~USB_INTEN_ATTACHEN_MASK) | USB_INTEN_USBRSTEN_MASK; + _hcd.need_reset = true; process_attach(rhport); } + if (is & USB_ISTAT_USBRST_MASK) { + KHCI->INTEN = (msk & ~USB_INTEN_USBRSTEN_MASK) | USB_INTEN_ATTACHEN_MASK; + process_bus_reset(rhport); + } if (is & USB_ISTAT_STALL_MASK) { KHCI->ISTAT = USB_ISTAT_STALL_MASK; } From cc06a3585e9f499bd2412f4f88e5d785e8e1a23f Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Mon, 10 Jan 2022 23:50:32 +0900 Subject: [PATCH 137/504] Add handling for NAK response --- src/portable/nxp/khci/hcd_khci.c | 357 ++++++++++++++++++++----------- 1 file changed, 230 insertions(+), 127 deletions(-) diff --git a/src/portable/nxp/khci/hcd_khci.c b/src/portable/nxp/khci/hcd_khci.c index 937d69f9b..ddc6e9992 100644 --- a/src/portable/nxp/khci/hcd_khci.c +++ b/src/portable/nxp/khci/hcd_khci.c @@ -93,12 +93,11 @@ typedef struct TU_ATTR_PACKED uint32_t : 0; }; }; + uint8_t *buffer; uint16_t length; uint16_t remaining; } endpoint_state_t; -TU_VERIFY_STATIC( sizeof(endpoint_state_t) == 8, "size is not correct" ); - typedef struct TU_ATTR_PACKED { uint8_t dev_addr; @@ -112,19 +111,24 @@ typedef struct TU_ATTR_PACKED uint8_t : 0; }; }; + uint8_t *buffer; + uint16_t length; + uint16_t remaining; } pipe_state_t; typedef struct { union { - /* [#EP][OUT,IN][EVEN,ODD] */ - buffer_descriptor_t bdt[16][2][2]; - uint16_t bda[512]; + /* [OUT,IN][EVEN,ODD] */ + buffer_descriptor_t bdt[2][2]; + uint16_t bda[2*2]; }; endpoint_state_t endpoint[2]; - pipe_state_t pipe[HCD_MAX_XFER]; - bool need_reset; /* The device has not been reset after connection. */ + pipe_state_t pipe[HCD_MAX_XFER * 2]; + uint32_t in_progress; /* Bitmap. Each bit indicates that a transfer of the corresponding pipe is in progress */ + uint32_t pending; /* Bitmap. Each bit indicates that a transfer of the corresponding pipe will be resume the next frame */ + bool need_reset; /* The device has not been reset after connection. */ } hcd_data_t; //--------------------------------------------------------------------+ @@ -132,15 +136,13 @@ typedef struct //--------------------------------------------------------------------+ // BDT(Buffer Descriptor Table) must be 256-byte aligned CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(512) static hcd_data_t _hcd; - -TU_VERIFY_STATIC( sizeof(_hcd.bdt) == 512, "size is not correct" ); +//CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(4) static uint8_t _rx_buf[1024]; int find_pipe(uint8_t dev_addr, uint8_t ep_addr) { /* Find the target pipe */ int num; - if (0 == tu_edpt_number(ep_addr)) ep_addr = 0; - for (num = 0; num < HCD_MAX_XFER; ++num) { + for (num = 0; num < HCD_MAX_XFER * 2; ++num) { pipe_state_t *p = &_hcd.pipe[num]; if ((p->dev_addr == dev_addr) && (p->ep_addr == ep_addr)) return num; @@ -148,37 +150,129 @@ int find_pipe(uint8_t dev_addr, uint8_t ep_addr) return -1; } -static int prepare_packets(int pipenum, - uint_fast8_t dir_in, uint8_t* buffer, - uint_fast16_t total_bytes) +static int prepare_packets(int pipenum) { - const unsigned dir_tx = dir_in ? 0 : 1; - endpoint_state_t *ep = &_hcd.endpoint[dir_tx]; - buffer_descriptor_t *bd = &_hcd.bdt[0][dir_tx][ep->odd]; - TU_ASSERT(0 == bd->own, 0); + pipe_state_t *pipe = &_hcd.pipe[pipenum]; + unsigned const dir_tx = tu_edpt_dir(pipe->ep_addr) ? 0 : 1; + endpoint_state_t *ep = &_hcd.endpoint[dir_tx]; + unsigned const odd = ep->odd; + buffer_descriptor_t *bd = _hcd.bdt[dir_tx]; + TU_ASSERT(0 == bd[odd].own, -1); - ep->pipenum = pipenum; - ep->length = total_bytes; - ep->remaining = total_bytes; + // TU_LOG1(" %p dir %d odd %d data %d\n", &bd[odd], dir_tx, odd, pipe->data); - int num_pkts = 0; /* The number of prepared packets */ - const unsigned mps = _hcd.pipe[pipenum].max_packet_size; - if (total_bytes > mps) { - buffer_descriptor_t *next = ep->odd ? bd - 1: bd + 1; + ep->pipenum = pipenum; + + bd[odd ].data = pipe->data; + bd[odd ^ 1].data = pipe->data ^ 1; + bd[odd ^ 1].own = 0; + /* reset values for a next transfer */ + + int num_tokens = 0; /* The number of prepared packets */ + unsigned const mps = pipe->max_packet_size; + unsigned const rem = pipe->remaining; + if (rem > mps) { /* When total_bytes is greater than the max packet size, * it prepares to the next transfer to avoid NAK in advance. */ - next->bc = total_bytes >= 2 * mps ? mps: total_bytes - mps; - next->addr = buffer + mps; - next->own = 1; - ++num_pkts; + bd[odd ^ 1].bc = rem >= 2 * mps ? mps: rem - mps; + bd[odd ^ 1].addr = pipe->buffer + mps; + bd[odd ^ 1].own = 1; + if (dir_tx) ++num_tokens; } - bd->bc = total_bytes >= mps ? mps: total_bytes; - bd->addr = buffer; + bd[odd].bc = rem >= mps ? mps: rem; + bd[odd].addr = pipe->buffer; __DSB(); - bd->own = 1; /* This bit must be set last */ - ++num_pkts; - // TU_LOG1("BD pipe=%d %d %lx %x\n", pipenum, num_pkts, bd->head, (uintptr_t)bd->addr); - return num_pkts; + bd[odd].own = 1; /* This bit must be set last */ + ++num_tokens; + return num_tokens; +} + +static int select_next_pipenum(int pipenum) +{ + unsigned wip = _hcd.in_progress & ~_hcd.pending; + if (!wip) return -1; + unsigned msk = TU_GENMASK(31, pipenum); + int next = __builtin_ctz(wip & msk); + if (next) return next; + msk = TU_GENMASK(pipenum, 0); + next = __builtin_ctz(wip & msk); + return next; +} + +/* When transfer is completed, return true. */ +static bool continue_transfer(int pipenum, buffer_descriptor_t *bd) +{ + pipe_state_t *pipe = &_hcd.pipe[pipenum]; + unsigned const bc = bd->bc; + unsigned const rem = pipe->remaining - bc; + + pipe->remaining = rem; + if (rem && bc == pipe->max_packet_size) { + int const next_rem = rem - pipe->max_packet_size; + if (next_rem > 0) { + /* Prepare to the after next transfer */ + bd->addr += pipe->max_packet_size * 2; + bd->bc = next_rem > pipe->max_packet_size ? pipe->max_packet_size: next_rem; + __DSB(); + bd->own = 1; /* This bit must be set last */ + while (KHCI->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) ; + KHCI->TOKEN = KHCI->TOKEN; /* Queue the same token as the last */ + } else if (TUSB_DIR_IN == tu_edpt_dir(pipe->ep_addr)) { /* IN */ + while (KHCI->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) ; + KHCI->TOKEN = KHCI->TOKEN; + } + return true; + } + pipe->data = bd->data ^ 1; + return false; +} + +static bool resume_transfer(int pipenum) +{ + int num_tokens = prepare_packets(pipenum); + TU_ASSERT(0 <= num_tokens); + + const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn); + NVIC_DisableIRQ(USB0_IRQn); + pipe_state_t *pipe = &_hcd.pipe[pipenum]; + + unsigned flags = KHCI->ENDPOINT[0].ENDPT & USB_ENDPT_HOSTWOHUB_MASK; + flags |= USB_ENDPT_EPRXEN_MASK | USB_ENDPT_EPTXEN_MASK; + switch (pipe->xfer) { + case TUSB_XFER_CONTROL: + flags |= USB_ENDPT_EPHSHK_MASK; + break; + case TUSB_XFER_ISOCHRONOUS: + flags |= USB_ENDPT_EPCTLDIS_MASK | USB_ENDPT_RETRYDIS_MASK; + break; + default: + flags |= USB_ENDPT_EPHSHK_MASK | USB_ENDPT_EPCTLDIS_MASK | USB_ENDPT_RETRYDIS_MASK; + break; + } + // TU_LOG1(" resume pipenum %d flags %x\n", pipenum, flags); + + KHCI->ENDPOINT[0].ENDPT = flags; + KHCI->ADDR = (KHCI->ADDR & USB_ADDR_LSEN_MASK) | pipe->dev_addr; + + unsigned const token = tu_edpt_number(pipe->ep_addr) | + ((tu_edpt_dir(pipe->ep_addr) ? TOK_PID_IN: TOK_PID_OUT) << USB_TOKEN_TOKENPID_SHIFT); + do { + while (KHCI->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) ; + KHCI->TOKEN = token; + } while (--num_tokens); + if (ie) NVIC_EnableIRQ(USB0_IRQn); + return true; +} + +static void suspend_transfer(int pipenum, buffer_descriptor_t *bd) +{ + pipe_state_t *pipe = &_hcd.pipe[pipenum]; + pipe->buffer = bd->addr; + pipe->data = bd->data; + if (TUSB_XFER_INTERRUPT == pipe->xfer) { + _hcd.pending |= TU_BIT(pipenum); + KHCI->INTEN |= USB_ISTAT_SOFTOK_MASK; + } } static void process_tokdne(uint8_t rhport) @@ -186,13 +280,9 @@ static void process_tokdne(uint8_t rhport) (void)rhport; const unsigned s = KHCI->STAT; KHCI->ISTAT = USB_ISTAT_TOKDNE_MASK; /* fetch the next token if received */ - uint8_t const epnum = (s >> USB_STAT_ENDP_SHIFT); - TU_ASSERT(0 == epnum,); uint8_t const dir_in = (s & USB_STAT_TX_MASK) ? TUSB_DIR_OUT: TUSB_DIR_IN; unsigned const odd = (s & USB_STAT_ODD_MASK) ? 1 : 0; - // TU_LOG1("TOKDNE %x\n", s); - buffer_descriptor_t *bd = (buffer_descriptor_t *)&_hcd.bda[s]; endpoint_state_t *ep = &_hcd.endpoint[s >> 3]; @@ -207,48 +297,40 @@ static void process_tokdne(uint8_t rhport) /* Update the odd variable to prepare for the next transfer */ ep->odd = odd ^ 1; - const unsigned bc = bd->bc; - const unsigned remaining = ep->remaining - bc; - pipe_state_t *pipe = &_hcd.pipe[ep->pipenum]; + int pipenum = ep->pipenum; + int next_pipenum; + // TU_LOG1("TOKDNE %x PID %x pipe %d\n", s, pid, pipenum); - // TU_LOG1(" pid %x bc %x remaining %d\n", pid, bc, remaining); - if ((TOK_PID_DATA0 == pid) || (TOK_PID_DATA1 == pid) || (TOK_PID_ACK == pid)) { - /* Go on the next packet transfer */ - if (remaining && bc == pipe->max_packet_size) { - ep->remaining = remaining; - const int next_remaining = remaining - pipe->max_packet_size; - if (next_remaining > 0) { - /* Prepare to the after next transfer */ - bd->addr += pipe->max_packet_size * 2; - bd->bc = next_remaining > pipe->max_packet_size ? pipe->max_packet_size: next_remaining; - __DSB(); - bd->own = 1; /* This bit must be set last */ - while (KHCI->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) ; - KHCI->TOKEN = KHCI->TOKEN; /* Queue the same token as the last */ - } else if (dir_in) { - KHCI->TOKEN = KHCI->TOKEN; - } - return; - } - } - const unsigned length = ep->length; xfer_result_t result; switch (pid) { default: + if (continue_transfer(pipenum, bd)) + return; result = XFER_RESULT_SUCCESS; break; - case TOK_PID_STALL: - result = XFER_RESULT_STALLED; - break; case TOK_PID_NAK: case TOK_PID_ERR: + suspend_transfer(pipenum, bd); + next_pipenum = select_next_pipenum(pipenum); + if (0 <= next_pipenum) + resume_transfer(next_pipenum); + return; + case TOK_PID_STALL: + result = XFER_RESULT_STALLED; + break; case TOK_PID_BUSTO: result = XFER_RESULT_FAILED; break; } + _hcd.in_progress &= ~TU_BIT(pipenum); + pipe_state_t *pipe = &_hcd.pipe[ep->pipenum]; hcd_event_xfer_complete(pipe->dev_addr, tu_edpt_addr(KHCI->TOKEN & USB_TOKEN_TOKENENDPT_MASK, dir_in), - length - remaining, result, true); + pipe->length - pipe->remaining, + result, true); + next_pipenum = select_next_pipenum(pipenum); + if (0 <= next_pipenum) + resume_transfer(next_pipenum); } static void process_attach(uint8_t rhport) @@ -264,6 +346,7 @@ static void process_attach(uint8_t rhport) static void process_bus_reset(uint8_t rhport) { + KHCI->ISTAT = USB_ISTAT_TOKDNE_MASK; KHCI->USBCTRL &= ~USB_USBCTRL_SUSP_MASK; KHCI->CTL &= ~USB_CTL_USBENSOFEN_MASK; KHCI->ADDR = 0; @@ -271,7 +354,9 @@ static void process_bus_reset(uint8_t rhport) hcd_event_device_remove(rhport, true); - buffer_descriptor_t *bd = _hcd.bdt[0][0]; + _hcd.in_progress = 0; + _hcd.pending = 0; + buffer_descriptor_t *bd = &_hcd.bdt[0][0]; for (unsigned i = 0; i < 2; ++i, ++bd) { bd->head = 0; } @@ -301,12 +386,15 @@ bool hcd_init(uint8_t rhport) KHCI->CTL &= ~USB_CTL_ODDRST_MASK; KHCI->SOFTHLD = 74; /* for 64-byte packets */ + // KHCI->SOFTHLD = 144; /* for low speed 8-byte packets */ KHCI->CTL = USB_CTL_HOSTMODEEN_MASK | USB_CTL_SE0_MASK; KHCI->USBCTRL = USB_USBCTRL_PDE_MASK; NVIC_ClearPendingIRQ(USB0_IRQn); KHCI->INTEN = USB_INTEN_ATTACHEN_MASK | USB_INTEN_TOKDNEEN_MASK | USB_INTEN_USBRSTEN_MASK | USB_INTEN_ERROREN_MASK | USB_INTEN_STALLEN_MASK; + KHCI->ERREN = 0xff; + return true; } @@ -371,12 +459,15 @@ tusb_speed_t hcd_port_speed_get(uint8_t rhport) void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { (void)rhport; + const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn); + NVIC_DisableIRQ(USB0_IRQn); pipe_state_t *p = &_hcd.pipe[0]; - pipe_state_t *end = &_hcd.pipe[HCD_MAX_XFER]; + pipe_state_t *end = &_hcd.pipe[HCD_MAX_XFER * 2]; for (;p != end; ++p) { if (p->dev_addr == dev_addr) tu_memclr(p, sizeof(*p)); } + if (ie) NVIC_EnableIRQ(USB0_IRQn); } //--------------------------------------------------------------------+ @@ -386,34 +477,30 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet { (void)rhport; // TU_LOG1("SETUP %u\n", dev_addr); - const unsigned rx_odd = _hcd.endpoint[0].odd; - const unsigned tx_odd = _hcd.endpoint[1].odd; - TU_ASSERT(0 == _hcd.bdt[0][0][tx_odd].own); + TU_ASSERT(0 == (_hcd.in_progress & TU_BIT(0))); - int num = find_pipe(dev_addr, 0); - if (num < 0) return false; + int pipenum = find_pipe(dev_addr, 0); + if (pipenum < 0) return false; - const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn); - NVIC_DisableIRQ(USB0_IRQn); + pipe_state_t *pipe = &_hcd.pipe[pipenum]; + pipe[0].data = 0; + pipe[0].buffer = (uint8_t*)(uintptr_t)setup_packet; + pipe[0].length = 8; + pipe[0].remaining = 8; + pipe[1].data = 1; - _hcd.bdt[0][0][rx_odd ].data = 1; - _hcd.bdt[0][0][rx_odd ^ 1].data = 0; - _hcd.bdt[0][1][tx_odd ].data = 0; - _hcd.bdt[0][1][tx_odd ^ 1].data = 1; + if (1 != prepare_packets(pipenum)) + return false; + + _hcd.in_progress |= TU_BIT(pipenum); unsigned hostwohub = KHCI->ENDPOINT[0].ENDPT & USB_ENDPT_HOSTWOHUB_MASK; KHCI->ENDPOINT[0].ENDPT = hostwohub | USB_ENDPT_EPHSHK_MASK | USB_ENDPT_EPRXEN_MASK | USB_ENDPT_EPTXEN_MASK; - bool ret = false; - if (prepare_packets(num, TUSB_DIR_OUT, (void*)(uintptr_t)setup_packet, 8)) { - KHCI->ADDR = (KHCI->ADDR & USB_ADDR_LSEN_MASK) | dev_addr; - while (KHCI->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) ; - KHCI->TOKEN = (TOK_PID_SETUP << USB_TOKEN_TOKENPID_SHIFT); - ret = true; - } - if (ie) NVIC_EnableIRQ(USB0_IRQn); - - return ret; + KHCI->ADDR = (KHCI->ADDR & USB_ADDR_LSEN_MASK) | dev_addr; + while (KHCI->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) ; + KHCI->TOKEN = (TOK_PID_SETUP << USB_TOKEN_TOKENPID_SHIFT); + return true; } bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) @@ -423,9 +510,10 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const // TU_LOG1("O %u %x\n", dev_addr, ep_addr); /* Find a free pipe */ pipe_state_t *p = &_hcd.pipe[0]; + pipe_state_t *end = &_hcd.pipe[HCD_MAX_XFER * 2]; if (dev_addr || ep_addr) { - pipe_state_t *end = &_hcd.pipe[HCD_MAX_XFER]; - for (++p; p < end && (p->dev_addr || p->ep_addr); ++p) ; + p += 2; + for (; p < end && (p->dev_addr || p->ep_addr); ++p) ; if (p == end) return false; } p->dev_addr = dev_addr; @@ -433,45 +521,39 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const p->max_packet_size = ep_desc->wMaxPacketSize; p->xfer = ep_desc->bmAttributes.xfer; p->data = 0; + if (!ep_addr) { + /* Open one more pipe for Control IN transfer */ + TU_ASSERT(TUSB_XFER_CONTROL == p->xfer); + pipe_state_t *q = p + 1; + TU_ASSERT(!q->dev_addr && !q->ep_addr); + q->dev_addr = dev_addr; + q->ep_addr = tu_edpt_addr(0, TUSB_DIR_IN); + q->max_packet_size = ep_desc->wMaxPacketSize; + q->xfer = ep_desc->bmAttributes.xfer; + q->data = 1; + } return true; } bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) { (void)rhport; - // TU_LOG1("X %u %x %d\n", dev_addr, ep_addr, buflen); - const unsigned dir_in = tu_edpt_dir(ep_addr); - const unsigned odd = _hcd.endpoint[dir_in ^ 1].odd; - buffer_descriptor_t *bd = _hcd.bdt[0][dir_in ^ 1]; - TU_ASSERT(0 == bd[odd].own); + // TU_LOG1("X %u %x %x %d\n", dev_addr, ep_addr, (uintptr_t)buffer, buflen); - int num = find_pipe(dev_addr, ep_addr); - if (num < 0) return false; + int pipenum = find_pipe(dev_addr, ep_addr); + TU_ASSERT(0 <= pipenum); - unsigned flags = USB_ENDPT_EPHSHK_MASK | USB_ENDPT_EPRXEN_MASK | USB_ENDPT_EPTXEN_MASK; - if (tu_edpt_number(ep_addr)) { - pipe_state_t *p = &_hcd.pipe[num]; - bd[odd ].data = p->data; - bd[odd ^ 1].data = p->data ^ 1; - bd[odd ^ 1].own = 0; - flags |= USB_ENDPT_EPCTLDIS_MASK; - /* Disable retry for a interrupt transfer. */ - if (TUSB_XFER_INTERRUPT == p->xfer) - flags |= USB_ENDPT_RETRYDIS_MASK; - } - unsigned hostwohub = KHCI->ENDPOINT[0].ENDPT & USB_ENDPT_HOSTWOHUB_MASK; - KHCI->ENDPOINT[0].ENDPT = hostwohub | flags; - int num_pkts = prepare_packets(num, dir_in, buffer, buflen); - if (!num_pkts) return false; - KHCI->ADDR = (KHCI->ADDR & USB_ADDR_LSEN_MASK) | dev_addr; - const unsigned token = tu_edpt_number(ep_addr) | - ((dir_in ? TOK_PID_IN: TOK_PID_OUT) << USB_TOKEN_TOKENPID_SHIFT); - const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn); + TU_ASSERT(0 == (_hcd.in_progress & TU_BIT(pipenum))); + unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn); + unsigned const wip = _hcd.in_progress; NVIC_DisableIRQ(USB0_IRQn); - do { - while (KHCI->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) ; - KHCI->TOKEN = token; - } while (--num_pkts && !dir_in); + pipe_state_t *pipe = &_hcd.pipe[pipenum]; + pipe->buffer = buffer; + pipe->length = buflen; + pipe->remaining = buflen; + _hcd.in_progress = wip | TU_BIT(pipenum); + if (0 == (wip & ~_hcd.pending)) + resume_transfer(pipenum); if (ie) NVIC_EnableIRQ(USB0_IRQn); return true; } @@ -497,21 +579,42 @@ void hcd_int_handler(uint8_t rhport) // TU_LOG1("S %lx\n", is); /* clear disabled interrupts */ - KHCI->ISTAT = is & ~msk & ~USB_ISTAT_TOKDNE_MASK; + KHCI->ISTAT = (is & ~msk & ~USB_ISTAT_TOKDNE_MASK) | USB_ISTAT_SOFTOK_MASK; is &= msk; + if (is & USB_ISTAT_ERROR_MASK) { + unsigned err = KHCI->ERRSTAT; + if (err) { + TU_LOG1(" ERR %x\n", err); + KHCI->ERRSTAT = err; + } else { + KHCI->INTEN &= ~USB_ISTAT_ERROR_MASK; + } + } + + if (is & USB_ISTAT_USBRST_MASK) { + KHCI->INTEN = (msk & ~USB_INTEN_USBRSTEN_MASK) | USB_INTEN_ATTACHEN_MASK; + process_bus_reset(rhport); + return; + } if (is & USB_ISTAT_ATTACH_MASK) { KHCI->INTEN = (msk & ~USB_INTEN_ATTACHEN_MASK) | USB_INTEN_USBRSTEN_MASK; _hcd.need_reset = true; process_attach(rhport); - } - if (is & USB_ISTAT_USBRST_MASK) { - KHCI->INTEN = (msk & ~USB_INTEN_USBRSTEN_MASK) | USB_INTEN_ATTACHEN_MASK; - process_bus_reset(rhport); + return; } if (is & USB_ISTAT_STALL_MASK) { KHCI->ISTAT = USB_ISTAT_STALL_MASK; } + if (is & USB_ISTAT_SOFTOK_MASK) { + msk &= ~USB_ISTAT_SOFTOK_MASK; + KHCI->INTEN = msk; + if (_hcd.pending) { + int pipenum = __builtin_ctz(_hcd.pending); + _hcd.pending = 0; + resume_transfer(pipenum); + } + } if (is & USB_ISTAT_TOKDNE_MASK) { process_tokdne(rhport); } From 60a0be82da93b653d55b9a62b0d80cd58f47a869 Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Thu, 27 Jan 2022 22:25:36 +0900 Subject: [PATCH 138/504] Change hcd_edpt_xfer to send at the next SOF --- src/portable/nxp/khci/hcd_khci.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/portable/nxp/khci/hcd_khci.c b/src/portable/nxp/khci/hcd_khci.c index ddc6e9992..133d65a66 100644 --- a/src/portable/nxp/khci/hcd_khci.c +++ b/src/portable/nxp/khci/hcd_khci.c @@ -268,7 +268,7 @@ static void suspend_transfer(int pipenum, buffer_descriptor_t *bd) { pipe_state_t *pipe = &_hcd.pipe[pipenum]; pipe->buffer = bd->addr; - pipe->data = bd->data; + pipe->data = bd->data ^ 1; if (TUSB_XFER_INTERRUPT == pipe->xfer) { _hcd.pending |= TU_BIT(pipenum); KHCI->INTEN |= USB_ISTAT_SOFTOK_MASK; @@ -309,7 +309,6 @@ static void process_tokdne(uint8_t rhport) result = XFER_RESULT_SUCCESS; break; case TOK_PID_NAK: - case TOK_PID_ERR: suspend_transfer(pipenum, bd); next_pipenum = select_next_pipenum(pipenum); if (0 <= next_pipenum) @@ -318,6 +317,7 @@ static void process_tokdne(uint8_t rhport) case TOK_PID_STALL: result = XFER_RESULT_STALLED; break; + case TOK_PID_ERR: /* mismatch toggle bit */ case TOK_PID_BUSTO: result = XFER_RESULT_FAILED; break; @@ -535,6 +535,8 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const return true; } +/* The address of buffer must be aligned to 4 byte boundary. And it must be at least 4 bytes long. + * DMA writes data in 4 byte unit */ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) { (void)rhport; @@ -545,15 +547,14 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * TU_ASSERT(0 == (_hcd.in_progress & TU_BIT(pipenum))); unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn); - unsigned const wip = _hcd.in_progress; NVIC_DisableIRQ(USB0_IRQn); pipe_state_t *pipe = &_hcd.pipe[pipenum]; pipe->buffer = buffer; pipe->length = buflen; pipe->remaining = buflen; - _hcd.in_progress = wip | TU_BIT(pipenum); - if (0 == (wip & ~_hcd.pending)) - resume_transfer(pipenum); + _hcd.in_progress |= TU_BIT(pipenum); + _hcd.pending |= TU_BIT(pipenum); /* Send at the next Frame */ + KHCI->INTEN |= USB_ISTAT_SOFTOK_MASK; if (ie) NVIC_EnableIRQ(USB0_IRQn); return true; } From d7cbfaaa0a83570c5094ae84262ee9ce83856aae Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Thu, 27 Jan 2022 22:26:51 +0900 Subject: [PATCH 139/504] Add hcd into source list --- hw/bsp/frdm_kl25z/board.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/bsp/frdm_kl25z/board.mk b/hw/bsp/frdm_kl25z/board.mk index 15bd50eda..3585b8b03 100644 --- a/hw/bsp/frdm_kl25z/board.mk +++ b/hw/bsp/frdm_kl25z/board.mk @@ -23,6 +23,7 @@ LD_FILE = $(MCU_DIR)/gcc/MKL25Z128xxx4_flash.ld SRC_C += \ src/portable/nxp/khci/dcd_khci.c \ + src/portable/nxp/khci/hcd_khci.c \ $(MCU_DIR)/system_MKL25Z4.c \ $(MCU_DIR)/project_template/clock_config.c \ $(MCU_DIR)/drivers/fsl_clock.c \ From 03d2e32dc15adf9ee28772dfaecc52fac940f0d9 Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Thu, 27 Jan 2022 23:38:19 +0900 Subject: [PATCH 140/504] Fix handling for pending transfers --- src/portable/nxp/khci/hcd_khci.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/portable/nxp/khci/hcd_khci.c b/src/portable/nxp/khci/hcd_khci.c index 133d65a66..92ec04d4a 100644 --- a/src/portable/nxp/khci/hcd_khci.c +++ b/src/portable/nxp/khci/hcd_khci.c @@ -269,7 +269,8 @@ static void suspend_transfer(int pipenum, buffer_descriptor_t *bd) pipe_state_t *pipe = &_hcd.pipe[pipenum]; pipe->buffer = bd->addr; pipe->data = bd->data ^ 1; - if (TUSB_XFER_INTERRUPT == pipe->xfer) { + if ((TUSB_XFER_INTERRUPT == pipe->xfer) || + (TUSB_XFER_BULK == pipe->xfer)) { _hcd.pending |= TU_BIT(pipenum); KHCI->INTEN |= USB_ISTAT_SOFTOK_MASK; } @@ -613,7 +614,8 @@ void hcd_int_handler(uint8_t rhport) if (_hcd.pending) { int pipenum = __builtin_ctz(_hcd.pending); _hcd.pending = 0; - resume_transfer(pipenum); + if (!(is & USB_ISTAT_TOKDNE_MASK)) + resume_transfer(pipenum); } } if (is & USB_ISTAT_TOKDNE_MASK) { From ce7a8fed36dc61ef488f1c75a9c810681c7dcde9 Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Fri, 28 Jan 2022 01:18:44 +0900 Subject: [PATCH 141/504] Add a partial support mark to KL25 --- docs/reference/supported.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index 445643733..7c5402d93 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -42,7 +42,7 @@ Supported MCUs +--------------+---------+-------------+--------+------+-----------+-------------------+--------------+ | NXP | iMXRT | RT10xx | ✔ | ✔ | ✔ | ci_hs | | | +---------+-------------+--------+------+-----------+-------------------+--------------+ -| | Kinetis | KL25 | ✔ | | ✖ | | | +| | Kinetis | KL25 | ✔ | ⚠ | ✖ | | | | | +-------------+--------+------+-----------+-------------------+--------------+ | | | K32L2 | ✔ | | ✖ | | | | +---------+-------------+--------+------+-----------+-------------------+--------------+ From 453ba529a6db41ad9e0e8cbfdedfcb48b059693e Mon Sep 17 00:00:00 2001 From: Ryzee119 Date: Fri, 28 Jan 2022 14:02:34 +1030 Subject: [PATCH 142/504] OHCI: Fix array out of bounds issue If using a USB hub, a request outside the array size can occur Original line: https://github.com/hathach/tinyusb/blob/ffb257ac17f162bc5a4c26596d7a1e954db98aa5/src/portable/ohci/ohci.h#L162 It can happen in a few places but one such example is here: https://github.com/hathach/tinyusb/blob/ffb257ac17f162bc5a4c26596d7a1e954db98aa5/src/portable/ohci/ohci.c#L460 ie. if HUB address is 5, this would be an array index out of bounds on control endpoints as `CFG_TUH_DEVICE_MAX+1` is only 5. This fix just includes num of hubs in the reserve array size. Fixing locally fixed this issue. --- src/portable/ohci/ohci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/portable/ohci/ohci.h b/src/portable/ohci/ohci.h index cd90aa45a..8db097b06 100644 --- a/src/portable/ohci/ohci.h +++ b/src/portable/ohci/ohci.h @@ -159,7 +159,7 @@ typedef struct TU_ATTR_ALIGNED(256) struct { ohci_ed_t ed; ohci_gtd_t gtd; - }control[CFG_TUH_DEVICE_MAX+1]; + }control[CFG_TUH_DEVICE_MAX+CFG_TUH_HUB+1]; // ochi_itd_t itd[OHCI_MAX_ITD]; // itd requires alignment of 32 ohci_ed_t ed_pool[HCD_MAX_ENDPOINT]; From e1f0c484c628fd9f2b66ef517a2fda9ace75dce0 Mon Sep 17 00:00:00 2001 From: Roland Date: Tue, 1 Feb 2022 23:45:52 +0100 Subject: [PATCH 143/504] Modifications for CCRX toolchain --- src/common/tusb_compiler.h | 6 +++++- src/portable/renesas/usba/dcd_usba.c | 8 ++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h index 38e6a16d0..8f1de7162 100644 --- a/src/common/tusb_compiler.h +++ b/src/common/tusb_compiler.h @@ -75,7 +75,11 @@ * Nth position is the same as the number of arguments * - ##__VA_ARGS__ is used to deal with 0 paramerter (swallows comma) *------------------------------------------------------------------*/ -#define TU_ARGS_NUM(...) _TU_NARG(_0, ##__VA_ARGS__,_RSEQ_N()) +#if !defined(__CCRX__) +#define TU_ARGS_NUM(...) _TU_NARG(_0, ##__VA_ARGS__,_RSEQ_N()) +#else +#define TU_ARGS_NUM(...) _TU_NARG(_0, __VA_ARGS__,_RSEQ_N()) +#endif #define _TU_NARG(...) _GET_NTH_ARG(__VA_ARGS__) #define _GET_NTH_ARG( \ diff --git a/src/portable/renesas/usba/dcd_usba.c b/src/portable/renesas/usba/dcd_usba.c index ae7d2fd0c..70a9f41e6 100644 --- a/src/portable/renesas/usba/dcd_usba.c +++ b/src/portable/renesas/usba/dcd_usba.c @@ -494,7 +494,11 @@ static bool process_pipe_xfer(int buffer_type, uint8_t ep_addr, void* buffer, ui while (USB0.D0FIFOSEL.BIT.CURPIPE) ; /* if CURPIPE bits changes, check written value */ } } else { +#if defined(__CCRX__) + __evenaccess volatile reg_pipetre_t *pt = get_pipetre(num); +#else volatile reg_pipetre_t *pt = get_pipetre(num); +#endif if (pt) { const unsigned mps = edpt_max_packet_size(num); volatile uint16_t *ctr = get_pipectr(num); @@ -715,11 +719,11 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) *ctr = 0; unsigned cfg = (dir << 4) | epn; if (xfer == TUSB_XFER_BULK) { - cfg |= USB_PIPECFG_BULK | USB_PIPECFG_SHTNAK | USB_PIPECFG_DBLB; + cfg |= (USB_PIPECFG_BULK | USB_PIPECFG_SHTNAK | USB_PIPECFG_DBLB); } else if (xfer == TUSB_XFER_INTERRUPT) { cfg |= USB_PIPECFG_INT; } else { - cfg |= USB_PIPECFG_ISO | USB_PIPECFG_DBLB; + cfg |= (USB_PIPECFG_ISO | USB_PIPECFG_DBLB); } USB0.PIPECFG.WORD = cfg; USB0.BRDYSTS.WORD = 0x1FFu ^ TU_BIT(num); From 2df57d2be0ad5e42ab0fbdb132d1921ca190632c Mon Sep 17 00:00:00 2001 From: Jay Beavers Date: Wed, 9 Feb 2022 08:19:01 -0800 Subject: [PATCH 144/504] Nit spelling correction --- hw/bsp/family_support.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index a8cc1f363..ee29caba7 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -2,7 +2,7 @@ if (NOT TARGET _family_support_marker) add_library(_family_support_marker INTERFACE) if (NOT FAMILY) - message(FATAL_ERROR "You must set a FAMILY variable for the build (e.g. rp2040, eps32s2, esp32s3). You can do this via -DFAMILY=xxx on the camke command line") + message(FATAL_ERROR "You must set a FAMILY variable for the build (e.g. rp2040, eps32s2, esp32s3). You can do this via -DFAMILY=xxx on the cmake command line") endif() if (NOT EXISTS ${CMAKE_CURRENT_LIST_DIR}/${FAMILY}/family.cmake) From 678c415beab60adff9ff2f125ad6b7f418bbcaaf Mon Sep 17 00:00:00 2001 From: Zenithal Date: Thu, 10 Feb 2022 22:30:31 +0800 Subject: [PATCH 145/504] readme: fix typo --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 8cf4a98da..5b994c357 100644 --- a/README.rst +++ b/README.rst @@ -65,7 +65,7 @@ Supports multiple device configurations by dynamically changing USB descriptors, - Audio Class 2.0 (UAC2) - Bluetooth Host Controller Interface (BTH HCI) - Communication Device Class (CDC) -- Device Firmware Update (DFU): DFU mode (WIP) and Runtinme +- Device Firmware Update (DFU): DFU mode (WIP) and Runtime - Human Interface Device (HID): Generic (In & Out), Keyboard, Mouse, Gamepad etc ... - Mass Storage Class (MSC): with multiple LUNs - Musical Instrument Digital Interface (MIDI) From 456c06aa5ee2440cd2c96800be41e7c63c34ae58 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 14 Feb 2022 18:17:49 +0700 Subject: [PATCH 146/504] add tud_msc_request_sense_cb() as weak callback set default error sense to NOT READY, Medium not present --- src/class/msc/msc_device.c | 59 ++++++++++++++++++++++---------------- src/class/msc/msc_device.h | 3 ++ 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 97837b114..8f4fc9356 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -239,6 +239,12 @@ bool tud_msc_set_sense(uint8_t lun, uint8_t sense_key, uint8_t add_sense_code, u return true; } +static inline void set_default_error_sense(uint8_t lun) +{ + // default sense is NOT READY, MEDIUM NOT PRESENT + tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3A, 0x00); +} + //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ @@ -406,7 +412,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t return false; } - TU_LOG(MSC_DEBUG, " SCSI Command: %s\r\n", tu_lookup_find(&_msc_scsi_cmd_table, p_cbw->command[0])); + TU_LOG(MSC_DEBUG, " SCSI Command [Lun%u]: %s\r\n", p_cbw->lun, tu_lookup_find(&_msc_scsi_cmd_table, p_cbw->command[0])); //TU_LOG_MEM(MSC_DEBUG, p_cbw, xferred_bytes, 2); p_csw->signature = MSC_CSW_SIGNATURE; @@ -473,7 +479,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t if ( resplen < 0 ) { // unsupported command - TU_LOG(MSC_DEBUG, " SCSI unsupported command\r\n"); + TU_LOG(MSC_DEBUG, " SCSI unsupported or failed command\r\n"); fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); } else if (resplen == 0) @@ -508,7 +514,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t break; case MSC_STAGE_DATA: - TU_LOG(MSC_DEBUG, " SCSI Data\r\n"); + TU_LOG(MSC_DEBUG, " SCSI Data [Lun%u]\r\n", p_cbw->lun); //TU_LOG_MEM(MSC_DEBUG, _mscd_buf, xferred_bytes, 2); if (SCSI_CMD_READ_10 == p_cbw->command[0]) @@ -569,7 +575,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t // Wait for the Status phase to complete if( (ep_addr == p_msc->ep_in) && (xferred_bytes == sizeof(msc_csw_t)) ) { - TU_LOG(MSC_DEBUG, " SCSI Status = %u\r\n", p_csw->status); + TU_LOG(MSC_DEBUG, " SCSI Status [Lun%u] = %u\r\n", p_cbw->lun, p_csw->status); // TU_LOG_MEM(MSC_DEBUG, p_csw, xferred_bytes, 2); // Invoke complete callback if defined @@ -654,8 +660,8 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ // Failed status response resplen = - 1; - // If sense key is not set by callback, default to Logical Unit Not Ready, Cause Not Reportable - if ( p_msc->sense_key == 0 ) tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x04, 0x00); + // set default sense if not set by callback + if ( p_msc->sense_key == 0 ) set_default_error_sense(lun); } break; @@ -670,8 +676,8 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ // Failed status response resplen = - 1; - // If sense key is not set by callback, default to Logical Unit Not Ready, Cause Not Reportable - if ( p_msc->sense_key == 0 ) tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x04, 0x00); + // set default sense if not set by callback + if ( p_msc->sense_key == 0 ) set_default_error_sense(lun); } } break; @@ -691,13 +697,13 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ { resplen = -1; - // If sense key is not set by callback, default to Logical Unit Not Ready, Cause Not Reportable - if ( p_msc->sense_key == 0 ) tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x04, 0x00); + // set default sense if not set by callback + if ( p_msc->sense_key == 0 ) set_default_error_sense(lun); }else { scsi_read_capacity10_resp_t read_capa10; - read_capa10.last_lba = tu_htonl(block_count-1); + read_capa10.last_lba = tu_htonl(block_count-1); read_capa10.block_size = tu_htonl(block_size); resplen = sizeof(read_capa10); @@ -727,8 +733,8 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ { resplen = -1; - // If sense key is not set by callback, default to Logical Unit Not Ready, Cause Not Reportable - if ( p_msc->sense_key == 0 ) tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x04, 0x00); + // set default sense if not set by callback + if ( p_msc->sense_key == 0 ) set_default_error_sense(lun); }else { read_fmt_capa.block_num = tu_htonl(block_count); @@ -765,10 +771,10 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ { scsi_mode_sense6_resp_t mode_resp = { - .data_len = 3, - .medium_type = 0, - .write_protected = false, - .reserved = 0, + .data_len = 3, + .medium_type = 0, + .write_protected = false, + .reserved = 0, .block_descriptor_len = 0 // no block descriptor are included }; @@ -789,12 +795,11 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ { scsi_sense_fixed_resp_t sense_rsp = { - .response_code = 0x70, + .response_code = 0x70, // current, fixed format .valid = 1 }; - sense_rsp.add_sense_len = sizeof(scsi_sense_fixed_resp_t) - 8; - + sense_rsp.add_sense_len = sizeof(scsi_sense_fixed_resp_t) - 8; sense_rsp.sense_key = p_msc->sense_key; sense_rsp.add_sense_code = p_msc->add_sense_code; sense_rsp.add_sense_qualifier = p_msc->add_sense_qualifier; @@ -802,6 +807,12 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ resplen = sizeof(sense_rsp); memcpy(buffer, &sense_rsp, resplen); + // request sense callback could overwrite the sense data + if (tud_msc_request_sense_cb) + { + resplen = tud_msc_request_sense_cb(lun, buffer, bufsize); + } + // Clear sense data after copy tud_msc_set_sense(lun, 0, 0, 0); } @@ -835,8 +846,8 @@ static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc) // negative means error -> endpoint is stalled & status in CSW set to failed TU_LOG(MSC_DEBUG, " tud_msc_read10_cb() return -1\r\n"); - // Sense = Flash not ready for access - tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_MEDIUM_ERROR, 0x33, 0x00); + // set sense + set_default_error_sense(p_cbw->lun); fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); } @@ -900,8 +911,8 @@ static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint3 // update actual byte before failed p_msc->xferred_len += xferred_bytes; - // Sense = Flash not ready for access - tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_MEDIUM_ERROR, 0x33, 0x00); + // Set sense + set_default_error_sense(p_cbw->lun); fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); }else diff --git a/src/class/msc/msc_device.h b/src/class/msc/msc_device.h index d32694340..5839b168d 100644 --- a/src/class/msc/msc_device.h +++ b/src/class/msc/msc_device.h @@ -131,6 +131,9 @@ TU_ATTR_WEAK uint8_t tud_msc_get_maxlun_cb(void); // - Start = 1 : active mode, if load_eject = 1 : load disk storage TU_ATTR_WEAK bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject); +// Invoked when received REQUEST_SENSE +TU_ATTR_WEAK int32_t tud_msc_request_sense_cb(uint8_t lun, void* buffer, uint16_t bufsize); + // Invoked when Read10 command is complete TU_ATTR_WEAK void tud_msc_read10_complete_cb(uint8_t lun); From 391edc7afb06359c7064752b1374550d1b526901 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 15 Feb 2022 22:40:08 +0700 Subject: [PATCH 147/504] msc example response PREVENT_ALLOW_MEDIUM_REMOVAL command as unsupported command LUN1 of msc_disk_dual will be set to not ready to simulate medium not present (e.g SD card removed) --- examples/device/cdc_msc/src/msc_disk.c | 5 ----- .../device/cdc_msc_freertos/src/msc_disk.c | 5 ----- .../dynamic_configuration/src/msc_disk.c | 5 ----- .../device/msc_dual_lun/src/msc_disk_dual.c | 22 ++++--------------- src/class/msc/msc_device.c | 2 +- 5 files changed, 5 insertions(+), 34 deletions(-) diff --git a/examples/device/cdc_msc/src/msc_disk.c b/examples/device/cdc_msc/src/msc_disk.c index 3076192af..e67e381ce 100644 --- a/examples/device/cdc_msc/src/msc_disk.c +++ b/examples/device/cdc_msc/src/msc_disk.c @@ -243,11 +243,6 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, switch (scsi_cmd[0]) { - case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: - // Host is about to read/write etc ... better not to disconnect disk - resplen = 0; - break; - default: // Set Sense = Invalid Command Operation 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 b9205f0c2..a895f4738 100644 --- a/examples/device/cdc_msc_freertos/src/msc_disk.c +++ b/examples/device/cdc_msc_freertos/src/msc_disk.c @@ -221,11 +221,6 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, switch (scsi_cmd[0]) { - case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: - // Host is about to read/write etc ... better not to disconnect disk - resplen = 0; - break; - default: // Set Sense = Invalid Command Operation tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); diff --git a/examples/device/dynamic_configuration/src/msc_disk.c b/examples/device/dynamic_configuration/src/msc_disk.c index b9205f0c2..a895f4738 100644 --- a/examples/device/dynamic_configuration/src/msc_disk.c +++ b/examples/device/dynamic_configuration/src/msc_disk.c @@ -221,11 +221,6 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, switch (scsi_cmd[0]) { - case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: - // Host is about to read/write etc ... better not to disconnect disk - resplen = 0; - break; - default: // Set Sense = Invalid Command Operation tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); diff --git a/examples/device/msc_dual_lun/src/msc_disk_dual.c b/examples/device/msc_dual_lun/src/msc_disk_dual.c index 18d3ca0d7..37446ebc3 100644 --- a/examples/device/msc_dual_lun/src/msc_disk_dual.c +++ b/examples/device/msc_dual_lun/src/msc_disk_dual.c @@ -28,6 +28,9 @@ #if CFG_TUD_MSC +// When button is pressed, LUN1 will be set to not ready to simulate +// medium not present (e.g SD card removed) + // Some MCU doesn't have enough 8KB SRAM to store the whole disk // We will use Flash as read-only disk with board that has // CFG_EXAMPLE_MSC_READONLY defined @@ -227,7 +230,7 @@ void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16 // return true allowing host to read/write this LUN e.g SD card inserted bool tud_msc_test_unit_ready_cb(uint8_t lun) { - (void) lun; + if ( lun == 1 && board_button_read() ) return false; return true; // RAM disk is always ready } @@ -320,23 +323,6 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, switch (scsi_cmd[0]) { - case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: - // Host is about to read/write etc ... better not to disconnect disk - resplen = 0; - break; - - case SCSI_CMD_START_STOP_UNIT: - // Host try to eject/safe remove/poweroff us. We could safely disconnect with disk storage, or go into lower power - /* scsi_start_stop_unit_t const * start_stop = (scsi_start_stop_unit_t const *) scsi_cmd; - // Start bit = 0 : low power mode, if load_eject = 1 : unmount disk storage as well - // Start bit = 1 : Ready mode, if load_eject = 1 : mount disk storage - start_stop->start; - start_stop->load_eject; - */ - resplen = 0; - break; - - default: // Set Sense = Invalid Command Operation tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 8f4fc9356..70ce1d352 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -209,7 +209,7 @@ TU_ATTR_UNUSED static tu_lookup_entry_t const _msc_scsi_cmd_lookup[] = { .key = SCSI_CMD_MODE_SELECT_6 , .data = "Mode_Select 6" }, { .key = SCSI_CMD_MODE_SENSE_6 , .data = "Mode_Sense 6" }, { .key = SCSI_CMD_START_STOP_UNIT , .data = "Start Stop Unit" }, - { .key = SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL , .data = "Prevent Allow Medium Removal" }, + { .key = SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL , .data = "Prevent/Allow Medium Removal" }, { .key = SCSI_CMD_READ_CAPACITY_10 , .data = "Read Capacity10" }, { .key = SCSI_CMD_REQUEST_SENSE , .data = "Request Sense" }, { .key = SCSI_CMD_READ_FORMAT_CAPACITY , .data = "Read Format Capacity" }, From 46f4f7ff491e5a45229f9d35653fd29578b9e7db Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 15 Feb 2022 22:53:23 +0700 Subject: [PATCH 148/504] minor rename set sense function --- src/class/msc/msc_device.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 70ce1d352..e09a2b11a 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -239,7 +239,7 @@ bool tud_msc_set_sense(uint8_t lun, uint8_t sense_key, uint8_t add_sense_code, u return true; } -static inline void set_default_error_sense(uint8_t lun) +static inline void set_sense_medium_not_present(uint8_t lun) { // default sense is NOT READY, MEDIUM NOT PRESENT tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3A, 0x00); @@ -661,7 +661,7 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ resplen = - 1; // set default sense if not set by callback - if ( p_msc->sense_key == 0 ) set_default_error_sense(lun); + if ( p_msc->sense_key == 0 ) set_sense_medium_not_present(lun); } break; @@ -677,7 +677,7 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ resplen = - 1; // set default sense if not set by callback - if ( p_msc->sense_key == 0 ) set_default_error_sense(lun); + if ( p_msc->sense_key == 0 ) set_sense_medium_not_present(lun); } } break; @@ -698,7 +698,7 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ resplen = -1; // set default sense if not set by callback - if ( p_msc->sense_key == 0 ) set_default_error_sense(lun); + if ( p_msc->sense_key == 0 ) set_sense_medium_not_present(lun); }else { scsi_read_capacity10_resp_t read_capa10; @@ -734,7 +734,7 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ resplen = -1; // set default sense if not set by callback - if ( p_msc->sense_key == 0 ) set_default_error_sense(lun); + if ( p_msc->sense_key == 0 ) set_sense_medium_not_present(lun); }else { read_fmt_capa.block_num = tu_htonl(block_count); @@ -847,7 +847,7 @@ static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc) TU_LOG(MSC_DEBUG, " tud_msc_read10_cb() return -1\r\n"); // set sense - set_default_error_sense(p_cbw->lun); + set_sense_medium_not_present(p_cbw->lun); fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); } @@ -912,7 +912,7 @@ static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint3 p_msc->xferred_len += xferred_bytes; // Set sense - set_default_error_sense(p_cbw->lun); + set_sense_medium_not_present(p_cbw->lun); fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); }else From a72d0245fa33e05a4b3fc44efd5e6bf2560722c6 Mon Sep 17 00:00:00 2001 From: NexusXe Date: Wed, 16 Feb 2022 08:29:20 -0600 Subject: [PATCH 149/504] Fix link to supported boards It used to point to `boards.md`, which doesn't exist. --- docs/reference/getting_started.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/getting_started.rst b/docs/reference/getting_started.rst index 875372c81..77155cd67 100644 --- a/docs/reference/getting_started.rst +++ b/docs/reference/getting_started.rst @@ -37,7 +37,7 @@ It is relatively simple to incorporate tinyusb to your (existing) project Examples -------- -For your convenience, TinyUSB contains a handful of examples for both host and device with/without RTOS to quickly test the functionality as well as demonstrate how API() should be used. Most examples will work on most of `the supported Boards `_. Firstly we need to ``git clone`` if not already +For your convenience, TinyUSB contains a handful of examples for both host and device with/without RTOS to quickly test the functionality as well as demonstrate how API() should be used. Most examples will work on most of `the supported Boards `_. Firstly we need to ``git clone`` if not already .. code-block:: From ada7a23ddc7d429b447d34785ffec2c230d75b1d Mon Sep 17 00:00:00 2001 From: NexusXe Date: Wed, 16 Feb 2022 08:33:06 -0600 Subject: [PATCH 150/504] Fix capitalization --- docs/reference/getting_started.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/getting_started.rst b/docs/reference/getting_started.rst index 77155cd67..4a53626cd 100644 --- a/docs/reference/getting_started.rst +++ b/docs/reference/getting_started.rst @@ -37,7 +37,7 @@ It is relatively simple to incorporate tinyusb to your (existing) project Examples -------- -For your convenience, TinyUSB contains a handful of examples for both host and device with/without RTOS to quickly test the functionality as well as demonstrate how API() should be used. Most examples will work on most of `the supported Boards `_. Firstly we need to ``git clone`` if not already +For your convenience, TinyUSB contains a handful of examples for both host and device with/without RTOS to quickly test the functionality as well as demonstrate how API() should be used. Most examples will work on most of `the supported boards `_. Firstly we need to ``git clone`` if not already .. code-block:: From a53e83665eb3d5aa70794e1648e45f644a35b994 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 17 Feb 2022 12:12:42 +0700 Subject: [PATCH 151/504] fix HID_REPORT_ID_N() --- src/class/hid/hid.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/class/hid/hid.h b/src/class/hid/hid.h index 9265a2ede..20a5dd7f9 100644 --- a/src/class/hid/hid.h +++ b/src/class/hid/hid.h @@ -645,7 +645,7 @@ enum { #define HID_REPORT_SIZE_N(x, n) HID_REPORT_ITEM(x, RI_GLOBAL_REPORT_SIZE, RI_TYPE_GLOBAL, n) #define HID_REPORT_ID(x) HID_REPORT_ITEM(x, RI_GLOBAL_REPORT_ID, RI_TYPE_GLOBAL, 1), -#define HID_REPORT_ID_N(x) HID_REPORT_ITEM(x, RI_GLOBAL_REPORT_ID, RI_TYPE_GLOBAL, n), +#define HID_REPORT_ID_N(x, n) HID_REPORT_ITEM(x, RI_GLOBAL_REPORT_ID, RI_TYPE_GLOBAL, n), #define HID_REPORT_COUNT(x) HID_REPORT_ITEM(x, RI_GLOBAL_REPORT_COUNT, RI_TYPE_GLOBAL, 1) #define HID_REPORT_COUNT_N(x, n) HID_REPORT_ITEM(x, RI_GLOBAL_REPORT_COUNT, RI_TYPE_GLOBAL, n) From 52645fcc1b6f00d4bf6b211a5425addf7d3a1e8c Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 18 Feb 2022 13:07:21 +0700 Subject: [PATCH 152/504] fix build with latest esp idf --- examples/device/cdc_msc_freertos/src/CMakeLists.txt | 4 ++++ examples/device/hid_composite_freertos/src/CMakeLists.txt | 4 ++++ hw/bsp/esp32s2/boards/esp32s2.c | 2 +- hw/bsp/esp32s2/family.mk | 1 + hw/bsp/esp32s3/boards/esp32s3.c | 2 +- src/osal/osal_freertos.h | 4 +++- src/osal/osal_rtx4.h | 2 +- 7 files changed, 15 insertions(+), 4 deletions(-) diff --git a/examples/device/cdc_msc_freertos/src/CMakeLists.txt b/examples/device/cdc_msc_freertos/src/CMakeLists.txt index 93ae0686a..9216e2b49 100644 --- a/examples/device/cdc_msc_freertos/src/CMakeLists.txt +++ b/examples/device/cdc_msc_freertos/src/CMakeLists.txt @@ -13,6 +13,10 @@ target_include_directories(${COMPONENT_TARGET} PUBLIC "${TOP}/src" ) +target_compile_definitions(${COMPONENT_TARGET} PUBLIC + ESP_PLATFORM +) + target_sources(${COMPONENT_TARGET} PUBLIC "${TOP}/src/tusb.c" "${TOP}/src/common/tusb_fifo.c" diff --git a/examples/device/hid_composite_freertos/src/CMakeLists.txt b/examples/device/hid_composite_freertos/src/CMakeLists.txt index 6f156379f..5d9fc74d3 100644 --- a/examples/device/hid_composite_freertos/src/CMakeLists.txt +++ b/examples/device/hid_composite_freertos/src/CMakeLists.txt @@ -13,6 +13,10 @@ target_include_directories(${COMPONENT_TARGET} PUBLIC "${TOP}/src" ) +target_compile_definitions(${COMPONENT_TARGET} PUBLIC + ESP_PLATFORM +) + target_sources(${COMPONENT_TARGET} PUBLIC "${TOP}/src/tusb.c" "${TOP}/src/common/tusb_fifo.c" diff --git a/hw/bsp/esp32s2/boards/esp32s2.c b/hw/bsp/esp32s2/boards/esp32s2.c index a81181672..03ae9e366 100644 --- a/hw/bsp/esp32s2/boards/esp32s2.c +++ b/hw/bsp/esp32s2/boards/esp32s2.c @@ -32,8 +32,8 @@ #include "hal/usb_hal.h" #include "soc/usb_periph.h" -#include "driver/periph_ctrl.h" #include "driver/rmt.h" +#include "esp_private/periph_ctrl.h" #ifdef NEOPIXEL_PIN #include "led_strip.h" diff --git a/hw/bsp/esp32s2/family.mk b/hw/bsp/esp32s2/family.mk index 4b9000a6a..b95098e15 100644 --- a/hw/bsp/esp32s2/family.mk +++ b/hw/bsp/esp32s2/family.mk @@ -10,6 +10,7 @@ build: all fullclean: if test -f sdkconfig; then $(RM) -f sdkconfig ; fi if test -d $(BUILD); then $(RM) -rf $(BUILD) ; fi + idf.py -B$(BUILD) -DFAMILY=$(FAMILY) -DBOARD=$(BOARD) $(CMAKE_DEFSYM) $@ clean flash bootloader-flash app-flash erase monitor dfu-flash dfu size size-components size-files: idf.py -B$(BUILD) -DFAMILY=$(FAMILY) -DBOARD=$(BOARD) $(CMAKE_DEFSYM) $@ diff --git a/hw/bsp/esp32s3/boards/esp32s3.c b/hw/bsp/esp32s3/boards/esp32s3.c index a81181672..03ae9e366 100644 --- a/hw/bsp/esp32s3/boards/esp32s3.c +++ b/hw/bsp/esp32s3/boards/esp32s3.c @@ -32,8 +32,8 @@ #include "hal/usb_hal.h" #include "soc/usb_periph.h" -#include "driver/periph_ctrl.h" #include "driver/rmt.h" +#include "esp_private/periph_ctrl.h" #ifdef NEOPIXEL_PIN #include "led_strip.h" diff --git a/src/osal/osal_freertos.h b/src/osal/osal_freertos.h index 4573e01f5..aa102b15c 100644 --- a/src/osal/osal_freertos.h +++ b/src/osal/osal_freertos.h @@ -68,6 +68,7 @@ static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) BaseType_t res = xSemaphoreGiveFromISR(sem_hdl, &xHigherPriorityTaskWoken); #if CFG_TUSB_MCU == OPT_MCU_ESP32S2 || CFG_TUSB_MCU == OPT_MCU_ESP32S3 + // not needed after https://github.com/espressif/esp-idf/commit/c5fd79547ac9b7bae06fa660e9f814d18d3390b7 if ( xHigherPriorityTaskWoken ) portYIELD_FROM_ISR(); #else portYIELD_FROM_ISR(xHigherPriorityTaskWoken); @@ -151,6 +152,7 @@ static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in BaseType_t res = xQueueSendToBackFromISR(qhdl, data, &xHigherPriorityTaskWoken); #if CFG_TUSB_MCU == OPT_MCU_ESP32S2 || CFG_TUSB_MCU == OPT_MCU_ESP32S3 + // not needed after https://github.com/espressif/esp-idf/commit/c5fd79547ac9b7bae06fa660e9f814d18d3390b7 if ( xHigherPriorityTaskWoken ) portYIELD_FROM_ISR(); #else portYIELD_FROM_ISR(xHigherPriorityTaskWoken); @@ -169,4 +171,4 @@ static inline bool osal_queue_empty(osal_queue_t qhdl) } #endif -#endif /* _TUSB_OSAL_FREERTOS_H_ */ +#endif diff --git a/src/osal/osal_rtx4.h b/src/osal/osal_rtx4.h index 32d7782d9..f7e88e322 100644 --- a/src/osal/osal_rtx4.h +++ b/src/osal/osal_rtx4.h @@ -167,4 +167,4 @@ static inline bool osal_queue_empty(osal_queue_t qhdl) } #endif -#endif /* _TUSB_OSAL_FREERTOS_H_ */ +#endif From e188117823f0406cfd8fa65e1e0e3a35019c96f2 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 18 Feb 2022 16:30:21 +0700 Subject: [PATCH 153/504] more esp build fix --- hw/bsp/esp32s2/boards/esp32s2.c | 7 ++++++- hw/bsp/esp32s3/boards/esp32s3.c | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/hw/bsp/esp32s2/boards/esp32s2.c b/hw/bsp/esp32s2/boards/esp32s2.c index 03ae9e366..a7ca82deb 100644 --- a/hw/bsp/esp32s2/boards/esp32s2.c +++ b/hw/bsp/esp32s2/boards/esp32s2.c @@ -33,7 +33,12 @@ #include "soc/usb_periph.h" #include "driver/rmt.h" -#include "esp_private/periph_ctrl.h" + +#if ESP_IDF_VERSION_MAJOR > 4 + #include "esp_private/periph_ctrl.h" +#else + #include "driver/periph_ctrl.h" +#endif #ifdef NEOPIXEL_PIN #include "led_strip.h" diff --git a/hw/bsp/esp32s3/boards/esp32s3.c b/hw/bsp/esp32s3/boards/esp32s3.c index 03ae9e366..a7ca82deb 100644 --- a/hw/bsp/esp32s3/boards/esp32s3.c +++ b/hw/bsp/esp32s3/boards/esp32s3.c @@ -33,7 +33,12 @@ #include "soc/usb_periph.h" #include "driver/rmt.h" -#include "esp_private/periph_ctrl.h" + +#if ESP_IDF_VERSION_MAJOR > 4 + #include "esp_private/periph_ctrl.h" +#else + #include "driver/periph_ctrl.h" +#endif #ifdef NEOPIXEL_PIN #include "led_strip.h" From d7495975914645d147b7b9752df9e3bab7bdcfb6 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 22 Feb 2022 18:10:09 -0800 Subject: [PATCH 154/504] Add dual role (concurrent) example This reads HID devices over host and then translates that to ASCII and sends it over CDC device. --- examples/host/hid_to_cdc/CMakeLists.txt | 28 ++ examples/host/hid_to_cdc/Makefile | 20 ++ examples/host/hid_to_cdc/only.txt | 1 + examples/host/hid_to_cdc/src/main.c | 291 ++++++++++++++++++ examples/host/hid_to_cdc/src/tusb_config.h | 163 ++++++++++ .../host/hid_to_cdc/src/usb_descriptors.c | 266 ++++++++++++++++ hw/bsp/imxrt/boards/mimxrt1060_evk/board.mk | 3 + hw/bsp/imxrt/family.c | 23 +- hw/bsp/imxrt/family.mk | 7 + 9 files changed, 799 insertions(+), 3 deletions(-) create mode 100644 examples/host/hid_to_cdc/CMakeLists.txt create mode 100644 examples/host/hid_to_cdc/Makefile create mode 100644 examples/host/hid_to_cdc/only.txt create mode 100644 examples/host/hid_to_cdc/src/main.c create mode 100644 examples/host/hid_to_cdc/src/tusb_config.h create mode 100644 examples/host/hid_to_cdc/src/usb_descriptors.c diff --git a/examples/host/hid_to_cdc/CMakeLists.txt b/examples/host/hid_to_cdc/CMakeLists.txt new file mode 100644 index 000000000..abc4d91da --- /dev/null +++ b/examples/host/hid_to_cdc/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.5) + +include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) + +# gets PROJECT name for the example (e.g. -) +family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR}) + +project(${PROJECT}) + +# Checks this example is valid for the family and initializes the project +family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}) + +add_executable(${PROJECT}) + +# Example source +target_sources(${PROJECT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c + ) + +# Example include +target_include_directories(${PROJECT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src + ) + +# Configure compilation flags and libraries for the example... see the corresponding function +# in hw/bsp/FAMILY/family.cmake for details. +family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/host/hid_to_cdc/Makefile b/examples/host/hid_to_cdc/Makefile new file mode 100644 index 000000000..b62a383eb --- /dev/null +++ b/examples/host/hid_to_cdc/Makefile @@ -0,0 +1,20 @@ +include ../../../tools/top.mk +include ../../make.mk + +INC += \ + src \ + $(TOP)/hw \ + +# Example source +EXAMPLE_SOURCE += $(wildcard src/*.c) +SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) + +CFLAGS += -Wno-error=cast-align -Wno-error=null-dereference + +SRC_C += \ + src/class/hid/hid_host.c \ + src/host/hub.c \ + src/host/usbh.c \ + src/host/usbh_control.c + +include ../../rules.mk diff --git a/examples/host/hid_to_cdc/only.txt b/examples/host/hid_to_cdc/only.txt new file mode 100644 index 000000000..87bf09f24 --- /dev/null +++ b/examples/host/hid_to_cdc/only.txt @@ -0,0 +1 @@ +board:mimxrt1060_evk diff --git a/examples/host/hid_to_cdc/src/main.c b/examples/host/hid_to_cdc/src/main.c new file mode 100644 index 000000000..e11f34cc2 --- /dev/null +++ b/examples/host/hid_to_cdc/src/main.c @@ -0,0 +1,291 @@ +/* + * 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 example runs both host and device concurrently. The USB host looks for +// any HID device with reports that are 8 bytes long and then assumes they are +// keyboard reports. It translates the keypresses of the reports to ASCII and +// transmits it over CDC to the device's host. + +#include +#include +#include + +#include "bsp/board.h" +#include "tusb.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF PROTYPES +//--------------------------------------------------------------------+ + +/* Blink pattern + * - 250 ms : device not mounted + * - 1000 ms : device mounted + * - 2500 ms : device is suspended + */ +enum { + BLINK_NOT_MOUNTED = 250, + BLINK_MOUNTED = 1000, + BLINK_SUSPENDED = 2500, +}; + +static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; + +void led_blinking_task(void); +void cdc_task(void); + +/*------------- MAIN -------------*/ +int main(void) +{ + board_init(); + tusb_init(); + + while (1) + { + tud_task(); // tinyusb device task + tuh_task(); // tinyusb host task + led_blinking_task(); + + cdc_task(); + } + + return 0; +} + +//--------------------------------------------------------------------+ +// Device callbacks +//--------------------------------------------------------------------+ + +// Invoked when device is mounted +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 = BLINK_MOUNTED; +} + +//--------------------------------------------------------------------+ +// Host callbacks +//--------------------------------------------------------------------+ + +// Invoked when device with hid interface is mounted +// Report descriptor is also available for use. tuh_hid_parse_report_descriptor() +// can be used to parse common/simple enough descriptor. +// Note: if report descriptor length > CFG_TUH_ENUMERATION_BUFSIZE, it will be skipped +// therefore report_desc = NULL, desc_len = 0 +void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len) +{ + (void)desc_report; + (void)desc_len; + uint16_t vid, pid; + tuh_vid_pid_get(dev_addr, &vid, &pid); + + printf("HID device address = %d, instance = %d is mounted\r\n", dev_addr, instance); + printf("VID = %04x, PID = %04x\r\n", vid, pid); + + // Receive any report and treat it like a keyboard. + // tuh_hid_report_received_cb() will be invoked when report is available + if ( !tuh_hid_receive_report(dev_addr, instance) ) + { + printf("Error: cannot request to receive report\r\n"); + } +} + +// Invoked when device with hid interface is un-mounted +void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) +{ + printf("HID device address = %d, instance = %d is unmounted\r\n", dev_addr, instance); +} + +const char* numbers = "0123456789"; + +// Uncomment if you use colemak and need to remap keys (like @tannewt.) +// const uint8_t colemak[77] = { +// 0, 0, 0, 0, 0, 0, 0, 22, +// 9, 23, 7, 0, 24, 17, 8, 12, +// 0, 14, 28, 51, 0, 19, 21, 10, +// 15, 0, 0, 0, 13, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 18, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0 +// }; + +// This is the reverse mapping of the US key layout in Adafruit_CircuitPython_HID. +const char* ascii = "\0\0\0\0abcdefghijklmnopqrstuvwxyz1234567890\n\x1b\x08\t -=[]\\\x00;\'`,./\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x7f"; +const char* shifted = "\0\0\0\0ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()\0\0\0\0\0_+{}|\0:\"~<>?\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; +// Bitmask of pressed keys. We use the current modifier state. +uint32_t last_state[8]; + +// Invoked when received report from device via interrupt endpoint +void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len) +{ + if (len != 8 && len < 10) { + tud_cdc_write("report len: ", 12); + tud_cdc_write(numbers + len, 1); + tud_cdc_write("\r\n", 2); + tud_cdc_write_flush(); + } + if (len != 8) { + // Don't request a new report for a wrong sized endpoint. + return; + } + uint8_t modifiers = report[0]; + bool flush = false; + for (int i = 2; i < 8; i++) { + if (report[i] == 0) { + continue; + } + uint8_t down = report[i]; + uint32_t mask = 1 << (down % 32); + bool was_down = (last_state[down / 32] & mask) != 0; + // Only map keycodes 0 - 76. + if (!was_down && down < 77) { + const char* layer = ascii; + // Check shift bits + if ((modifiers & 0x22) != 0) { + layer = shifted; + } + // Map the key code for Colemak layout so @tannewt can type. + // uint8_t colemak_key_code = colemak[down]; + // if (colemak_key_code != 0) { + // down = colemak_key_code; + // } + char c = layer[down]; + if (c == '\0') { + continue; + } + if (c == '\n') { + tud_cdc_write("\r", 1); + } + tud_cdc_write(&c, 1); + flush = true; + } + } + if (flush) { + tud_cdc_write_flush(); + } + // Now update last_state + memset(last_state, 0, 8 * sizeof(uint32_t)); + for (int i = 2; i < 8; i++) { + if (report[i] == 0) { + continue; + } + uint8_t down = report[i]; + last_state[down / 32] |= 1 << (down % 32); + } + // continue to request to receive report + if ( !tuh_hid_receive_report(dev_addr, instance) ) + { + printf("Error: cannot request to receive report\r\n"); + } +} + + + +//--------------------------------------------------------------------+ +// USB CDC +//--------------------------------------------------------------------+ +void cdc_task(void) +{ + // connected() check for DTR bit + // Most but not all terminal client set this when making connection + // if ( tud_cdc_connected() ) + { + // connected and there are data available + if ( tud_cdc_available() ) + { + // read datas + char buf[64]; + uint32_t count = tud_cdc_read(buf, sizeof(buf)); + (void) count; + + // Echo back + // Note: Skip echo by commenting out write() and write_flush() + // for throughput test e.g + // $ dd if=/dev/zero of=/dev/ttyACM0 count=10000 + tud_cdc_write(buf, count); + tud_cdc_write_flush(); + } + } +} + +// Invoked when cdc when line state changed e.g connected/disconnected +void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) +{ + (void) itf; + (void) rts; + + // TODO set some indicator + if ( dtr ) + { + // Terminal connected + }else + { + // Terminal disconnected + } +} + +// Invoked when CDC interface received data from host +void tud_cdc_rx_cb(uint8_t itf) +{ + (void) itf; +} + +//--------------------------------------------------------------------+ +// BLINKING TASK +//--------------------------------------------------------------------+ +void led_blinking_task(void) +{ + static uint32_t start_ms = 0; + static bool led_state = false; + + // Blink every interval ms + if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time + start_ms += blink_interval_ms; + + board_led_write(led_state); + led_state = 1 - led_state; // toggle +} diff --git a/examples/host/hid_to_cdc/src/tusb_config.h b/examples/host/hid_to_cdc/src/tusb_config.h new file mode 100644 index 000000000..9a35ffc30 --- /dev/null +++ b/examples/host/hid_to_cdc/src/tusb_config.h @@ -0,0 +1,163 @@ +/* + * 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 _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +//-------------------------------------------------------------------- +// COMMON CONFIGURATION +//-------------------------------------------------------------------- + +// defined by board.mk +#ifndef CFG_TUSB_MCU + #error CFG_TUSB_MCU must be defined +#endif + +// RHPort number used for device can be defined by board.mk, default to port 0 +#ifndef BOARD_DEVICE_RHPORT_NUM + #define BOARD_DEVICE_RHPORT_NUM 0 +#endif + +// RHPort number used for device can be defined by board.mk, default to port 1 +#ifndef BOARD_HOST_RHPORT_NUM + #define BOARD_HOST_RHPORT_NUM 1 +#endif + +// RHPort max operational speed can defined by board.mk +// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed +#ifndef BOARD_DEVICE_RHPORT_SPEED + #if TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX, OPT_MCU_MIMXRT10XX, OPT_MCU_NUC505) ||\ + TU_CHECK_MCU(OPT_MCU_CXD56, OPT_MCU_SAMX7X, OPT_MCU_BCM2711) ||\ + TU_CHECK_MCU(OPT_MCU_FT90X, OPT_MCU_FT93X) + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED + #else + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED + #endif +#endif + +// RHPort max operational speed can defined by board.mk +// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed +#ifndef BOARD_HOST_RHPORT_SPEED + #if TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX, OPT_MCU_MIMXRT10XX, OPT_MCU_NUC505) ||\ + TU_CHECK_MCU(OPT_MCU_CXD56, OPT_MCU_SAMX7X, OPT_MCU_BCM2711) ||\ + TU_CHECK_MCU(OPT_MCU_FT90X, OPT_MCU_FT93X) + #define BOARD_HOST_RHPORT_SPEED OPT_MODE_HIGH_SPEED + #else + #define BOARD_HOST_RHPORT_SPEED OPT_MODE_FULL_SPEED + #endif +#endif + +// Device mode with rhport and speed defined by board.mk +#if BOARD_DEVICE_RHPORT_NUM == 0 + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#elif BOARD_DEVICE_RHPORT_NUM == 1 + #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#else + #error "Incorrect RHPort configuration" +#endif + +// Device mode with rhport and speed defined by board.mk +#if BOARD_HOST_RHPORT_NUM == 0 + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | BOARD_HOST_RHPORT_SPEED) +#elif BOARD_HOST_RHPORT_NUM == 1 + #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_HOST | BOARD_HOST_RHPORT_SPEED) +#else + #error "Incorrect RHPort configuration" +#endif + +// This example doesn't use an RTOS +#ifndef CFG_TUSB_OS +#define CFG_TUSB_OS OPT_OS_NONE +#endif + +// CFG_TUSB_DEBUG is defined by compiler in DEBUG build +// #define CFG_TUSB_DEBUG 0 + +/* 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_CDC 1 +#define CFG_TUD_MSC 0 +#define CFG_TUD_HID 0 +#define CFG_TUD_MIDI 0 +#define CFG_TUD_VENDOR 0 + +// 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, more is faster +#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) + +//-------------------------------------------------------------------- +// HOST CONFIGURATION +//-------------------------------------------------------------------- + +// Size of buffer to hold descriptors and other data used for enumeration +#define CFG_TUH_ENUMERATION_BUFSIZE 256 + +#define CFG_TUH_HUB 1 +#define CFG_TUH_CDC 0 +#define CFG_TUH_MSC 0 +#define CFG_TUH_VENDOR 0 + +// max device support (excluding hub device) +#define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB ? 4 : 1) // hub typically has 4 ports + +//------------- HID -------------// +#define CFG_TUH_HID 4 +#define CFG_TUH_HID_EPIN_BUFSIZE 64 +#define CFG_TUH_HID_EPOUT_BUFSIZE 64 + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_CONFIG_H_ */ diff --git a/examples/host/hid_to_cdc/src/usb_descriptors.c b/examples/host/hid_to_cdc/src/usb_descriptors.c new file mode 100644 index 000000000..7dd73937c --- /dev/null +++ b/examples/host/hid_to_cdc/src/usb_descriptors.c @@ -0,0 +1,266 @@ +/* + * 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 "tusb.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) << (n) ) +#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 +//--------------------------------------------------------------------+ +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 +}; + +// 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; +} + +//--------------------------------------------------------------------+ +// Configuration Descriptor +//--------------------------------------------------------------------+ + +enum +{ + ITF_NUM_CDC = 0, + ITF_NUM_CDC_DATA, + ITF_NUM_MSC, + ITF_NUM_TOTAL +}; + +#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX + // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number + // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In, 5 Bulk etc ... + #define EPNUM_CDC_NOTIF 0x81 + #define EPNUM_CDC_OUT 0x02 + #define EPNUM_CDC_IN 0x82 + +#elif CFG_TUSB_MCU == OPT_MCU_SAMG || CFG_TUSB_MCU == OPT_MCU_SAMX7X + // SAMG & SAME70 don't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_CDC_NOTIF 0x81 + #define EPNUM_CDC_OUT 0x02 + #define EPNUM_CDC_IN 0x83 + +#elif CFG_TUSB_MCU == OPT_MCU_CXD56 + // CXD56 doesn't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + // CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number + // 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN) + #define EPNUM_CDC_NOTIF 0x83 + #define EPNUM_CDC_OUT 0x02 + #define EPNUM_CDC_IN 0x81 + +#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X + // FT9XX doesn't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_CDC_NOTIF 0x81 + #define EPNUM_CDC_OUT 0x02 + #define EPNUM_CDC_IN 0x83 + +#else + #define EPNUM_CDC_NOTIF 0x81 + #define EPNUM_CDC_OUT 0x02 + #define EPNUM_CDC_IN 0x82 + +#endif + +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN) + +// full speed configuration +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, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64), +}; + +#if TUD_OPT_HIGH_SPEED +// Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration + +// high speed configuration +uint8_t const desc_hs_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, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 512), +}; + +// other speed configuration +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 +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 +}; + +// 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 + + // if link speed is high return fullspeed config, and vice versa + // Note: the descriptor type is OHER_SPEED_CONFIG instead of CONFIG + 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 // 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 + +#if TUD_OPT_HIGH_SPEED + // Although we are highspeed, host may be fullspeed. + return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration; +#else + return desc_fs_configuration; +#endif +} + +//--------------------------------------------------------------------+ +// String Descriptors +//--------------------------------------------------------------------+ + +// array of pointer to string descriptors +char const* string_desc_arr [] = +{ + (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) + "TinyUSB", // 1: Manufacturer + "TinyUSB Device", // 2: Product + "123456789012", // 3: Serials, should use chip ID + "TinyUSB CDC", // 4: CDC Interface +}; + +static uint16_t _desc_str[32]; + +// 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; + + uint8_t chr_count; + + if ( index == 0) + { + memcpy(&_desc_str[1], string_desc_arr[0], 2); + chr_count = 1; + }else + { + // 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 = (uint8_t) strlen(str); + if ( chr_count > 31 ) chr_count = 31; + + // Convert ASCII string into UTF-16 + for(uint8_t i=0; iTX = phytx; + + // RT105x RT106x have dual USB controller. +#ifdef USBPHY2 + usb_phy = USBPHY2; + + // Enable PHY support for Low speed device + LS via FS Hub + usb_phy->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK | USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; + + // Enable all power for normal operation + usb_phy->PWD = 0; + + // TX Timing + phytx = usb_phy->TX; + phytx &= ~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK); + phytx |= USBPHY_TX_D_CAL(0x0C) | USBPHY_TX_TXCAL45DP(0x06) | USBPHY_TX_TXCAL45DM(0x06); + usb_phy->TX = phytx; +#endif } //--------------------------------------------------------------------+ diff --git a/hw/bsp/imxrt/family.mk b/hw/bsp/imxrt/family.mk index d086d503f..0bf4a0d15 100644 --- a/hw/bsp/imxrt/family.mk +++ b/hw/bsp/imxrt/family.mk @@ -15,6 +15,13 @@ CFLAGS += \ -DXIP_BOOT_HEADER_ENABLE=1 \ -DCFG_TUSB_MCU=OPT_MCU_MIMXRT10XX +ifdef BOARD_DEVICE_RHPORT_NUM +CFLAGS += -DBOARD_DEVICE_RHPORT_NUM=$(BOARD_DEVICE_RHPORT_NUM) +endif +ifdef BOARD_HOST_RHPORT_NUM +CFLAGS += -DBOARD_HOST_RHPORT_NUM=$(BOARD_HOST_RHPORT_NUM) +endif + # mcu driver cause following warnings CFLAGS += -Wno-error=unused-parameter -Wno-error=implicit-fallthrough= From 9ba1ba8fa13dc63a3075f41c4944f22ea12021e6 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 22 Feb 2022 18:39:02 -0800 Subject: [PATCH 155/504] Guard clock setup for USB2 --- hw/bsp/imxrt/family.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/bsp/imxrt/family.c b/hw/bsp/imxrt/family.c index 03be3b3dc..a811a7e40 100644 --- a/hw/bsp/imxrt/family.c +++ b/hw/bsp/imxrt/family.c @@ -98,10 +98,6 @@ void board_init(void) CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, 480000000U); CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, 480000000U); - // USB1 - CLOCK_EnableUsbhs1PhyPllClock(kCLOCK_Usbphy480M, 480000000U); - CLOCK_EnableUsbhs1Clock(kCLOCK_Usb480M, 480000000U); - USBPHY_Type* usb_phy; // RT105x RT106x have dual USB controller. @@ -125,6 +121,10 @@ void board_init(void) // RT105x RT106x have dual USB controller. #ifdef USBPHY2 + // USB1 + CLOCK_EnableUsbhs1PhyPllClock(kCLOCK_Usbphy480M, 480000000U); + CLOCK_EnableUsbhs1Clock(kCLOCK_Usb480M, 480000000U); + usb_phy = USBPHY2; // Enable PHY support for Low speed device + LS via FS Hub From 566e3abcea0b987a832116d0a48bde5890bdee3d Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 23 Feb 2022 11:55:57 +0700 Subject: [PATCH 156/504] increase version, update doc for release --- CONTRIBUTORS.rst | 13 ++++++++++--- docs/info/changelog.rst | 40 ++++++++++++++++++++++++++++++++++++++++ src/tusb_option.h | 2 +- 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst index 05d088ee7..5726169f8 100644 --- a/CONTRIBUTORS.rst +++ b/CONTRIBUTORS.rst @@ -18,6 +18,12 @@ Notable contributors - Design the project logo +`Gordon McNab `__ +--------------------------------------------- + +- Add new DCD port for Bridgetek FT90x and FT93x + + `Ha Thach `__ ----------------------------------------- @@ -53,6 +59,7 @@ Notable contributors ----------------------------------------------- - Add new DCD port for Dialog DA1469x +- Add new DCD port for PIC32MZ - Add new class driver for Bluetooth HCI - Add ISO transfer for STM32 Synopsys, Nordic nRF, Dialog DA1469x - Improve Audio driver and add uac2\_headset example @@ -81,11 +88,11 @@ Notable contributors `Koji KITAYAMA `__ ----------------------------------------------- -- Add new DCD port for NXP Kinetis KL25 -- Add new DCD port for Renesas RX family (RX600, RX700 ..) with GR-CITRUS, RX65n target board +- Add new DCD and HCD port for NXP Kinetis KL25 +- Add new DCD and HCD port for Renesas RX family (RX600, RX700 ..) with GR-CITRUS, RX65n target board +- Add new DCD and HCD port for Mentor musb with MSP432E4 - Add new class driver for USB Video Class (UVC 1.5) - `Nathan Conrad `__ --------------------------------------------- diff --git a/docs/info/changelog.rst b/docs/info/changelog.rst index 8eec729d6..bd6712b93 100644 --- a/docs/info/changelog.rst +++ b/docs/info/changelog.rst @@ -2,6 +2,46 @@ Changelog ********* +0.13.0 +====== + +- [tu_fifo] Fix locked mutex when full, and return type in peek_n() + +Controller Driver (DCD & HCD) +----------------------------- + +- [DWC2] Generalize synopsys dwc2 with synopsys/dwc2 which support both FS and HS phy (UTMI and ULPI) for various MCUs. + - Broadcom 28/27xx on raspberrypi SBC + - Silicon Labs EFM32 + - Espressif ESP32 Sx + - GigaDevice GD32 + - ST STM32 + - Infineon XMC +- [KL25] Add new HCD for NXP KL25 +- [MUSB] Add new DCD and HCD for Mentor musb with TI MSP432E4 +- [F1C100s] Add new DCD for Allwinner F1C100s family +- [PIC32MZ] Add new DCD for PIC32MZ +- [nRF] Fix/Enhance varous race condtion with: EASY DMA, request HFXO, EPOUT +- [ChipIdea] rename Transdimension to more popular ChipIdea Highspeed, +- [RP2040] various update/fix for hcd/dcd +- [FT9XX] new DCD port for Bridgetek FT90x and FT93x devices +- [DA1469X] Fix resume +- [OHCI] Fix device array out of bound + +Note: legacy drivers such as st/synopsys, nxp/transdimension are still present in this release but won't recieve more update and could be removed in the future. + +Device Stack +------------ + +- [Audio] Support disabling feedback format correction (16.16 <-> 10.14 format) +- [MSC] Add tud_msc_request_sense_cb() callback, change most default sense error to medium not present (0x02, 0x3A, 0x00) +- [Video] Fix video_capture example fails enumeration when 8FPS + +Host Stack +---------- + +No notable changes + 0.12.0 ====== diff --git a/src/tusb_option.h b/src/tusb_option.h index c78fc471e..cb49c85ce 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -30,7 +30,7 @@ #include "common/tusb_compiler.h" #define TUSB_VERSION_MAJOR 0 -#define TUSB_VERSION_MINOR 12 +#define TUSB_VERSION_MINOR 13 #define TUSB_VERSION_REVISION 0 #define TUSB_VERSION_STRING TU_STRING(TUSB_VERSION_MAJOR) "." TU_STRING(TUSB_VERSION_MINOR) "." TU_STRING(TUSB_VERSION_REVISION) From c0a65ba0f62287cb7b5091a263656fdb26a140e9 Mon Sep 17 00:00:00 2001 From: Charlie Birks Date: Wed, 23 Feb 2022 12:25:01 +0000 Subject: [PATCH 157/504] Support interrupt OUT in RP2040 HCD --- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 3e80dd872..4ffad75a0 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -328,9 +328,11 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t // endpoint number / direction // preamble uint32_t reg = dev_addr | (num << USB_ADDR_ENDP1_ENDPOINT_LSB); - // Assert the interrupt endpoint is IN_TO_HOST - // TODO Interrupt can also be OUT - assert(dir == TUSB_DIR_IN); + + if (dir == TUSB_DIR_OUT) + { + reg |= USB_ADDR_ENDP1_INTEP_DIR_BITS; + } if (need_pre(dev_addr)) { From 83b638f2305c50945670d2e1dd5eb91eeff7c3c8 Mon Sep 17 00:00:00 2001 From: Charlie Birks Date: Wed, 23 Feb 2022 13:03:20 +0000 Subject: [PATCH 158/504] Open OUT endpoint for HID host --- src/class/hid/hid_host.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index f19f1ba81..1e13ccc7c 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -286,28 +286,35 @@ bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *de hidh_device_t* hid_dev = get_dev(dev_addr); TU_ASSERT(hid_dev->inst_count < CFG_TUH_HID, 0); - //------------- Endpoint Descriptor -------------// + hidh_interface_t* hid_itf = get_instance(dev_addr, hid_dev->inst_count); + + //------------- Endpoint Descriptors -------------// p_desc = tu_desc_next(p_desc); tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc; - TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType); - // first endpoint may be OUT, skip to IN endpoint - // TODO also open endpoint OUT - if(tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_OUT) + for(int i = 0; i < desc_itf->bNumEndpoints; i++) { + TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType); + TU_ASSERT( usbh_edpt_open(rhport, dev_addr, desc_ep) ); + + if(tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) + { + hid_itf->ep_in = desc_ep->bEndpointAddress; + hid_itf->epin_size = tu_edpt_packet_size(desc_ep); + } + else + { + hid_itf->ep_out = desc_ep->bEndpointAddress; + hid_itf->epout_size = tu_edpt_packet_size(desc_ep); + } + p_desc = tu_desc_next(p_desc); desc_ep = (tusb_desc_endpoint_t const *) p_desc; - TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType); } - TU_ASSERT( usbh_edpt_open(rhport, dev_addr, desc_ep) ); - - hidh_interface_t* hid_itf = get_instance(dev_addr, hid_dev->inst_count); hid_dev->inst_count++; hid_itf->itf_num = desc_itf->bInterfaceNumber; - hid_itf->ep_in = desc_ep->bEndpointAddress; - hid_itf->epin_size = tu_edpt_packet_size(desc_ep); // Assume bNumDescriptors = 1 hid_itf->report_desc_type = desc_hid->bReportType; From 81e33477ea2d2a4f056d8d9c4cacfbbd7a4bc8e8 Mon Sep 17 00:00:00 2001 From: Alexandre Perrin Date: Wed, 23 Feb 2022 18:27:52 +0100 Subject: [PATCH 159/504] Fix CPP compilation with IAR IAR defines __STDC_VERSION__ in cpp as well. Which causes TU_VERIFY_STATIC to be defined as _Static_assert instead of cpp's static_assert. This reorders __cplusplus__ to be first, then to fallback to __STDC_VERSION__ if not CPP. --- src/common/tusb_compiler.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h index 38e6a16d0..93af44115 100644 --- a/src/common/tusb_compiler.h +++ b/src/common/tusb_compiler.h @@ -51,10 +51,10 @@ #endif // Compile-time Assert -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L - #define TU_VERIFY_STATIC _Static_assert -#elif defined (__cplusplus) && __cplusplus >= 201103L +#if defined (__cplusplus) && __cplusplus >= 201103L #define TU_VERIFY_STATIC static_assert +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L + #define TU_VERIFY_STATIC _Static_assert #elif defined(__CCRX__) #define TU_VERIFY_STATIC(const_expr, _mess) typedef char TU_XSTRCAT(Line, __LINE__)[(const_expr) ? 1 : 0]; #else From a8d6e823951a758829b53199de25a4ff2ce14494 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 25 Feb 2022 17:36:05 +0700 Subject: [PATCH 160/504] enhance dual role examples --- examples/host/hid_to_cdc/only.txt | 1 + examples/host/hid_to_cdc/src/main.c | 154 +++++++++++--------- hw/bsp/imxrt/boards/mimxrt1064_evk/board.mk | 3 + src/class/hid/hid.h | 5 +- 4 files changed, 97 insertions(+), 66 deletions(-) diff --git a/examples/host/hid_to_cdc/only.txt b/examples/host/hid_to_cdc/only.txt index 87bf09f24..78d94e3ce 100644 --- a/examples/host/hid_to_cdc/only.txt +++ b/examples/host/hid_to_cdc/only.txt @@ -1 +1,2 @@ board:mimxrt1060_evk +board:mimxrt1064_evk diff --git a/examples/host/hid_to_cdc/src/main.c b/examples/host/hid_to_cdc/src/main.c index e11f34cc2..cdf5d264e 100644 --- a/examples/host/hid_to_cdc/src/main.c +++ b/examples/host/hid_to_cdc/src/main.c @@ -39,6 +39,26 @@ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ +// uncomment if you are using colemak layout +// #define KEYBOARD_COLEMAK + +#ifdef KEYBOARD_COLEMAK +const uint8_t colemak[128] = { + 0 , 0, 0, 0, 0, 0, 0, 22, + 9 , 23, 7, 0, 24, 17, 8, 12, + 0 , 14, 28, 51, 0, 19, 21, 10, + 15 , 0, 0, 0, 13, 0, 0, 0, + 0 , 0, 0, 0, 0, 0, 0, 0, + 0 , 0, 0, 0, 0, 0, 0, 0, + 0 , 0, 0, 18, 0, 0, 0, 0, + 0 , 0, 0, 0, 0, 0, 0, 0, + 0 , 0, 0, 0, 0, 0, 0, 0, + 0 , 0, 0, 0, 0, 0, 0, 0 +}; +#endif + +static uint8_t const keycode2ascii[128][2] = { HID_KEYCODE_TO_ASCII }; + /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted @@ -137,85 +157,89 @@ void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) printf("HID device address = %d, instance = %d is unmounted\r\n", dev_addr, instance); } -const char* numbers = "0123456789"; +// keycodes from last report to check if key is holding or newly pressed +uint8_t last_keycodes[6] = {0}; -// Uncomment if you use colemak and need to remap keys (like @tannewt.) -// const uint8_t colemak[77] = { -// 0, 0, 0, 0, 0, 0, 0, 22, -// 9, 23, 7, 0, 24, 17, 8, 12, -// 0, 14, 28, 51, 0, 19, 21, 10, -// 15, 0, 0, 0, 13, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 18, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0 -// }; +// look up new key in previous keys +static inline bool key_in_last_report(const uint8_t key_arr[6], uint8_t keycode) +{ + for(uint8_t i=0; i<6; i++) + { + if (key_arr[i] == keycode) return true; + } -// This is the reverse mapping of the US key layout in Adafruit_CircuitPython_HID. -const char* ascii = "\0\0\0\0abcdefghijklmnopqrstuvwxyz1234567890\n\x1b\x08\t -=[]\\\x00;\'`,./\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x7f"; -const char* shifted = "\0\0\0\0ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()\0\0\0\0\0_+{}|\0:\"~<>?\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; -// Bitmask of pressed keys. We use the current modifier state. -uint32_t last_state[8]; + return false; +} // Invoked when received report from device via interrupt endpoint void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len) { - if (len != 8 && len < 10) { - tud_cdc_write("report len: ", 12); - tud_cdc_write(numbers + len, 1); - tud_cdc_write("\r\n", 2); + if (len != 8) + { + char ch_num; + + tud_cdc_write_str("incorrect report len: "); + + if ( len > 10 ) + { + ch_num = '0' + (len / 10); + tud_cdc_write(&ch_num, 1); + len = len % 10; + } + + ch_num = '0' + len; + tud_cdc_write(&ch_num, 1); + + tud_cdc_write_str("\r\n"); tud_cdc_write_flush(); - } - if (len != 8) { + // Don't request a new report for a wrong sized endpoint. return; } - uint8_t modifiers = report[0]; + + uint8_t const modifiers = report[0]; bool flush = false; - for (int i = 2; i < 8; i++) { - if (report[i] == 0) { - continue; - } - uint8_t down = report[i]; - uint32_t mask = 1 << (down % 32); - bool was_down = (last_state[down / 32] & mask) != 0; - // Only map keycodes 0 - 76. - if (!was_down && down < 77) { - const char* layer = ascii; - // Check shift bits - if ((modifiers & 0x22) != 0) { - layer = shifted; + + for (int i = 2; i < 8; i++) + { + uint8_t keycode = report[i]; + + if (keycode) + { + if ( key_in_last_report(last_keycodes, keycode) ) + { + // exist in previous report means the current key is holding + // do nothing + }else + { + // not existed in previous report means the current key is pressed + // Only print keycodes 0 - 128. + if (keycode < 128) + { + // remap the key code for Colemak layout so @tannewt can type. + #ifdef KEYBOARD_COLEMAK + uint8_t colemak_key_code = colemak[keycode]; + if (colemak_key_code != 0) keycode = colemak_key_code; + #endif + + bool const is_shift = modifiers & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT); + char c = keycode2ascii[keycode][is_shift ? 1 : 0]; + if (c) + { + if (c == '\n') tud_cdc_write("\r", 1); + tud_cdc_write(&c, 1); + flush = true; + } + } } - // Map the key code for Colemak layout so @tannewt can type. - // uint8_t colemak_key_code = colemak[down]; - // if (colemak_key_code != 0) { - // down = colemak_key_code; - // } - char c = layer[down]; - if (c == '\0') { - continue; - } - if (c == '\n') { - tud_cdc_write("\r", 1); - } - tud_cdc_write(&c, 1); - flush = true; } } - if (flush) { - tud_cdc_write_flush(); - } - // Now update last_state - memset(last_state, 0, 8 * sizeof(uint32_t)); - for (int i = 2; i < 8; i++) { - if (report[i] == 0) { - continue; - } - uint8_t down = report[i]; - last_state[down / 32] |= 1 << (down % 32); - } + + if (flush) tud_cdc_write_flush(); + + // save current report + memcpy(last_keycodes, report+2, 6); + // continue to request to receive report if ( !tuh_hid_receive_report(dev_addr, instance) ) { diff --git a/hw/bsp/imxrt/boards/mimxrt1064_evk/board.mk b/hw/bsp/imxrt/boards/mimxrt1064_evk/board.mk index 586d74fe5..2b479719f 100644 --- a/hw/bsp/imxrt/boards/mimxrt1064_evk/board.mk +++ b/hw/bsp/imxrt/boards/mimxrt1064_evk/board.mk @@ -7,5 +7,8 @@ JLINK_DEVICE = MIMXRT1064xxx6A # For flash-pyocd target PYOCD_TARGET = mimxrt1064 +BOARD_DEVICE_RHPORT_NUM = 1 +BOARD_HOST_RHPORT_NUM = 0 + # flash using pyocd flash: flash-pyocd diff --git a/src/class/hid/hid.h b/src/class/hid/hid.h index 20a5dd7f9..940454bd9 100644 --- a/src/class/hid/hid.h +++ b/src/class/hid/hid.h @@ -1106,7 +1106,10 @@ enum {'8' , 0 }, /* 0x60 */ \ {'9' , 0 }, /* 0x61 */ \ {'0' , 0 }, /* 0x62 */ \ - {'0' , 0 }, /* 0x63 */ \ + {'.' , 0 }, /* 0x63 */ \ + {0 , 0 }, /* 0x64 */ \ + {0 , 0 }, /* 0x65 */ \ + {0 , 0 }, /* 0x66 */ \ {'=' , '=' }, /* 0x67 */ \ From 4a5a53b3b88fcd2f5ec7f1f94eb07c27cb1e9bec Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 23 Feb 2022 18:42:32 +0700 Subject: [PATCH 161/504] improve rphort management for usbd --- src/class/cdc/cdc_rndis_host.c | 10 ++++++ src/device/usbd.c | 28 ++++++++++----- src/device/usbd_pvt.h | 2 ++ src/host/usbh.c | 14 +++++++- src/host/usbh_classdriver.h | 2 ++ src/osal/osal.h | 56 +++++++++-------------------- src/osal/osal_freertos.h | 2 +- src/osal/osal_mynewt.h | 2 +- src/osal/osal_none.h | 41 +++++---------------- src/osal/osal_pico.h | 2 +- src/osal/osal_rtthread.h | 2 +- src/osal/osal_rtx4.h | 2 +- src/portable/sony/cxd56/dcd_cxd56.c | 3 +- 13 files changed, 78 insertions(+), 88 deletions(-) diff --git a/src/class/cdc/cdc_rndis_host.c b/src/class/cdc/cdc_rndis_host.c index cc4ffd1cf..d41cf91ac 100644 --- a/src/class/cdc/cdc_rndis_host.c +++ b/src/class/cdc/cdc_rndis_host.c @@ -35,6 +35,16 @@ #include "cdc_host.h" #include "cdc_rndis_host.h" +#if 0 // TODO remove subtask related macros later +// Sub Task +#define OSAL_SUBTASK_BEGIN +#define OSAL_SUBTASK_END return TUSB_ERROR_NONE; + +#define STASK_RETURN(_error) return _error; +#define STASK_INVOKE(_subtask, _status) (_status) = _subtask +#define STASK_ASSERT(_cond) TU_VERIFY(_cond, TUSB_ERROR_OSAL_TASK_FAILED) +#endif + //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ diff --git a/src/device/usbd.c b/src/device/usbd.c index 448114303..37ca9822f 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -269,11 +269,12 @@ static inline usbd_class_driver_t const * get_driver(uint8_t drvid) // DCD Event //--------------------------------------------------------------------+ -static bool _usbd_initialized = false; +enum { RHPORT_INVALID = 0xFFu }; +static uint8_t _usbd_rhport = RHPORT_INVALID; // Event queue // OPT_MODE_DEVICE is used by OS NONE for mutex (disable usb isr) -OSAL_QUEUE_DEF(OPT_MODE_DEVICE, _usbd_qdef, CFG_TUD_TASK_QUEUE_SZ, dcd_event_t); +OSAL_QUEUE_DEF(usbd_int_set, _usbd_qdef, CFG_TUD_TASK_QUEUE_SZ, dcd_event_t); static osal_queue_t _usbd_q; // Mutex for claiming endpoint, only needed when using with preempted RTOS @@ -376,21 +377,21 @@ bool tud_remote_wakeup(void) { // only wake up host if this feature is supported and enabled and we are suspended TU_VERIFY (_usbd_dev.suspended && _usbd_dev.remote_wakeup_support && _usbd_dev.remote_wakeup_en ); - dcd_remote_wakeup(TUD_OPT_RHPORT); + dcd_remote_wakeup(_usbd_rhport); return true; } bool tud_disconnect(void) { TU_VERIFY(dcd_disconnect); - dcd_disconnect(TUD_OPT_RHPORT); + dcd_disconnect(_usbd_rhport); return true; } bool tud_connect(void) { TU_VERIFY(dcd_connect); - dcd_connect(TUD_OPT_RHPORT); + dcd_connect(_usbd_rhport); return true; } @@ -399,13 +400,13 @@ bool tud_connect(void) //--------------------------------------------------------------------+ bool tud_inited(void) { - return _usbd_initialized; + return _usbd_rhport != RHPORT_INVALID; } bool tud_init (uint8_t rhport) { // skip if already initialized - if (_usbd_initialized) return _usbd_initialized; + if ( tud_inited() ) return true; TU_LOG2("USBD init\r\n"); @@ -439,7 +440,7 @@ bool tud_init (uint8_t rhport) dcd_init(rhport); dcd_int_enable(rhport); - _usbd_initialized = true; + _usbd_rhport = rhport; return true; } @@ -1173,6 +1174,17 @@ void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_ // USBD API For Class Driver //--------------------------------------------------------------------+ +void usbd_int_set(bool enabled) +{ + if (enabled) + { + dcd_int_enable(_usbd_rhport); + }else + { + dcd_int_disable(_usbd_rhport); + } +} + // Parse consecutive endpoint descriptors (IN & OUT) bool usbd_open_edpt_pair(uint8_t rhport, uint8_t const* p_desc, uint8_t ep_count, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in) { diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index 7607b9895..dae95cebb 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -58,6 +58,8 @@ usbd_class_driver_t const* usbd_app_driver_get_cb(uint8_t* driver_count) TU_ATTR typedef bool (*usbd_control_xfer_cb_t)(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); +void usbd_int_set(bool enabled); + //--------------------------------------------------------------------+ // USBD Endpoint API //--------------------------------------------------------------------+ diff --git a/src/host/usbh.c b/src/host/usbh.c index b8439addc..9854b75a3 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -215,7 +215,7 @@ CFG_TUSB_MEM_SECTION usbh_device_t _usbh_devices[CFG_TUH_DEVICE_MAX + CFG_TUH_HU // Event queue // role device/host is used by OS NONE for mutex (disable usb isr) -OSAL_QUEUE_DEF(OPT_MODE_HOST, _usbh_qdef, CFG_TUH_TASK_QUEUE_SZ, hcd_event_t); +OSAL_QUEUE_DEF(usbh_int_set, _usbh_qdef, CFG_TUH_TASK_QUEUE_SZ, hcd_event_t); static osal_queue_t _usbh_q; CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t _usbh_ctrl_buf[CFG_TUH_ENUMERATION_BUFSIZE]; @@ -434,6 +434,18 @@ uint8_t* usbh_get_enum_buf(void) return _usbh_ctrl_buf; } +void usbh_int_set(bool enabled) +{ + // TODO all host controller + if (enabled) + { + hcd_int_enable(TUH_OPT_RHPORT); + }else + { + hcd_int_disable(TUH_OPT_RHPORT); + } +} + //--------------------------------------------------------------------+ // HCD Event Handler //--------------------------------------------------------------------+ diff --git a/src/host/usbh_classdriver.h b/src/host/usbh_classdriver.h index 8bc2622aa..2f9957cc6 100644 --- a/src/host/usbh_classdriver.h +++ b/src/host/usbh_classdriver.h @@ -57,6 +57,8 @@ uint8_t usbh_get_rhport(uint8_t dev_addr); uint8_t* usbh_get_enum_buf(void); +void usbh_int_set(bool enabled); + //--------------------------------------------------------------------+ // USBH Endpoint API //--------------------------------------------------------------------+ diff --git a/src/osal/osal.h b/src/osal/osal.h index b2943cc79..7111bbdb2 100644 --- a/src/osal/osal.h +++ b/src/osal/osal.h @@ -31,9 +31,6 @@ extern "C" { #endif -/** \addtogroup group_osal - * @{ */ - #include "common/tusb_common.h" // Return immediately @@ -67,47 +64,26 @@ typedef void (*osal_task_func_t)( void * ); //--------------------------------------------------------------------+ // OSAL Porting API +// Should be implemented as static inline function in osal_port.h header +/* + static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef); + static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr); + static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec); + static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl); // TODO removed + + static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef); + static inline bool osal_mutex_lock (osal_mutex_t sem_hdl, uint32_t msec); + static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl); + + static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef); + static inline bool osal_queue_receive(osal_queue_t qhdl, void* data); + static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr); + static inline bool osal_queue_empty(osal_queue_t qhdl); +*/ //--------------------------------------------------------------------+ -#if __GNUC__ && !defined(__ARMCC_VERSION) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wredundant-decls" -#endif -//------------- Semaphore -------------// -static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef); -static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr); -static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec); - -static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl); // TODO removed - -//------------- Mutex -------------// -static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef); -static inline bool osal_mutex_lock (osal_mutex_t sem_hdl, uint32_t msec); -static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl); - -//------------- Queue -------------// -static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef); -static inline bool osal_queue_receive(osal_queue_t qhdl, void* data); -static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr); -static inline bool osal_queue_empty(osal_queue_t qhdl); -#if __GNUC__ && !defined(__ARMCC_VERSION) -#pragma GCC diagnostic pop -#endif - -#if 0 // TODO remove subtask related macros later -// Sub Task -#define OSAL_SUBTASK_BEGIN -#define OSAL_SUBTASK_END return TUSB_ERROR_NONE; - -#define STASK_RETURN(_error) return _error; -#define STASK_INVOKE(_subtask, _status) (_status) = _subtask -#define STASK_ASSERT(_cond) TU_VERIFY(_cond, TUSB_ERROR_OSAL_TASK_FAILED) -#endif - #ifdef __cplusplus } #endif -/** @} */ - #endif /* _TUSB_OSAL_H_ */ diff --git a/src/osal/osal_freertos.h b/src/osal/osal_freertos.h index aa102b15c..69a026df5 100644 --- a/src/osal/osal_freertos.h +++ b/src/osal/osal_freertos.h @@ -115,7 +115,7 @@ static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) //--------------------------------------------------------------------+ // role device/host is used by OS NONE for mutex (disable usb isr) only -#define OSAL_QUEUE_DEF(_role, _name, _depth, _type) \ +#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ static _type _name##_##buf[_depth];\ osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf }; diff --git a/src/osal/osal_mynewt.h b/src/osal/osal_mynewt.h index 6882329c1..78a257cd6 100644 --- a/src/osal/osal_mynewt.h +++ b/src/osal/osal_mynewt.h @@ -96,7 +96,7 @@ static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) //--------------------------------------------------------------------+ // role device/host is used by OS NONE for mutex (disable usb isr) only -#define OSAL_QUEUE_DEF(_role, _name, _depth, _type) \ +#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ static _type _name##_##buf[_depth];\ static struct os_event _name##_##evbuf[_depth];\ osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf, .evbuf = _name##_##evbuf};\ diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index a1f997cf2..e1dd95c34 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -103,59 +103,34 @@ static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) //--------------------------------------------------------------------+ #include "common/tusb_fifo.h" -// extern to avoid including dcd.h and hcd.h -#if TUSB_OPT_DEVICE_ENABLED -extern void dcd_int_disable(uint8_t rhport); -extern void dcd_int_enable(uint8_t rhport); -#endif - -#if TUSB_OPT_HOST_ENABLED -extern void hcd_int_disable(uint8_t rhport); -extern void hcd_int_enable(uint8_t rhport); -#endif - typedef struct { - uint8_t role; // device or host - tu_fifo_t ff; + void (*interrupt_set)(bool); + tu_fifo_t ff; }osal_queue_def_t; typedef osal_queue_def_t* osal_queue_t; // role device/host is used by OS NONE for mutex (disable usb isr) only -#define OSAL_QUEUE_DEF(_role, _name, _depth, _type) \ +#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ uint8_t _name##_buf[_depth*sizeof(_type)]; \ osal_queue_def_t _name = { \ - .role = _role, \ + .interrupt_set = _int_set, \ .ff = TU_FIFO_INIT(_name##_buf, _depth, _type, false) \ } // lock queue by disable USB interrupt static inline void _osal_q_lock(osal_queue_t qhdl) { - (void) qhdl; - -#if TUSB_OPT_DEVICE_ENABLED - if (qhdl->role == OPT_MODE_DEVICE) dcd_int_disable(TUD_OPT_RHPORT); -#endif - -#if TUSB_OPT_HOST_ENABLED - if (qhdl->role == OPT_MODE_HOST) hcd_int_disable(TUH_OPT_RHPORT); -#endif + // disable dcd/hcd interrupt + qhdl->interrupt_set(false); } // unlock queue static inline void _osal_q_unlock(osal_queue_t qhdl) { - (void) qhdl; - -#if TUSB_OPT_DEVICE_ENABLED - if (qhdl->role == OPT_MODE_DEVICE) dcd_int_enable(TUD_OPT_RHPORT); -#endif - -#if TUSB_OPT_HOST_ENABLED - if (qhdl->role == OPT_MODE_HOST) hcd_int_enable(TUH_OPT_RHPORT); -#endif + // enable dcd/hcd interrupt + qhdl->interrupt_set(true); } static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) diff --git a/src/osal/osal_pico.h b/src/osal/osal_pico.h index 1c3366e01..4843d6450 100644 --- a/src/osal/osal_pico.h +++ b/src/osal/osal_pico.h @@ -114,7 +114,7 @@ typedef struct typedef osal_queue_def_t* osal_queue_t; // role device/host is used by OS NONE for mutex (disable usb isr) only -#define OSAL_QUEUE_DEF(_role, _name, _depth, _type) \ +#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ uint8_t _name##_buf[_depth*sizeof(_type)]; \ osal_queue_def_t _name = { \ .ff = TU_FIFO_INIT(_name##_buf, _depth, _type, false) \ diff --git a/src/osal/osal_rtthread.h b/src/osal/osal_rtthread.h index d5c062ac1..0845175b8 100644 --- a/src/osal/osal_rtthread.h +++ b/src/osal/osal_rtthread.h @@ -90,7 +90,7 @@ static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { //--------------------------------------------------------------------+ // role device/host is used by OS NONE for mutex (disable usb isr) only -#define OSAL_QUEUE_DEF(_role, _name, _depth, _type) \ +#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ static _type _name##_##buf[_depth]; \ osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf }; diff --git a/src/osal/osal_rtx4.h b/src/osal/osal_rtx4.h index f7e88e322..1856a5d9a 100644 --- a/src/osal/osal_rtx4.h +++ b/src/osal/osal_rtx4.h @@ -111,7 +111,7 @@ static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) //--------------------------------------------------------------------+ // role device/host is used by OS NONE for mutex (disable usb isr) only -#define OSAL_QUEUE_DEF(_role, _name, _depth, _type) \ +#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ os_mbx_declare(_name##__mbox, _depth); \ _declare_box(_name##__pool, sizeof(_type), _depth); \ osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .pool = _name##__pool, .mbox = _name##__mbox }; diff --git a/src/portable/sony/cxd56/dcd_cxd56.c b/src/portable/sony/cxd56/dcd_cxd56.c index dfe409383..f2a20accb 100644 --- a/src/portable/sony/cxd56/dcd_cxd56.c +++ b/src/portable/sony/cxd56/dcd_cxd56.c @@ -33,12 +33,13 @@ #include #include "device/dcd.h" +#include "device/usbd_pvt.h" #define CXD56_EPNUM (7) #define CXD56_SETUP_QUEUE_DEPTH (4) #define CXD56_MAX_DATA_OUT_SIZE (64) -OSAL_QUEUE_DEF(OPT_MODE_DEVICE, _setup_queue_def, CXD56_SETUP_QUEUE_DEPTH, struct usb_ctrlreq_s); +OSAL_QUEUE_DEF(usbd_int_set, _setup_queue_def, CXD56_SETUP_QUEUE_DEPTH, struct usb_ctrlreq_s); struct usbdcd_driver_s { From d10326cb4e0f48a05bc39c6f51b7b0fb29427cc9 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 23 Feb 2022 21:46:40 +0700 Subject: [PATCH 162/504] rename TUSB_OPT_DEVICE_ENABLED to CFG_TUD_ENABLED TUSB_OPT_DEVICE_ENABLED still usable for backward compatible --- hw/bsp/board.h | 2 +- hw/bsp/brtmm90x/family.c | 6 +++--- hw/bsp/d5035_01/d5035_01.c | 2 +- hw/bsp/da14695_dk_usb/da14695_dk_usb.c | 2 +- hw/bsp/da1469x_dk_pro/da1469x-dk-pro.c | 4 ++-- hw/bsp/frdm_kl25z/frdm_kl25z.c | 2 +- hw/bsp/lpcxpresso1769/lpcxpresso1769.c | 2 +- hw/bsp/mbed1768/mbed1768.c | 2 +- hw/bsp/msp432e4/family.c | 4 ++-- hw/bsp/nrf/family.c | 2 +- hw/bsp/rp2040/family.c | 2 +- hw/bsp/rx/boards/rx65n_target/rx65n_target.c | 2 +- hw/bsp/same54xplainedpro/same54xplainedpro.c | 2 +- hw/bsp/tm4c123/family.c | 2 +- src/class/audio/audio_device.c | 4 ++-- src/class/bth/bth_device.c | 2 +- src/class/cdc/cdc_device.c | 2 +- src/class/dfu/dfu_device.c | 2 +- src/class/dfu/dfu_rt_device.c | 2 +- src/class/hid/hid_device.c | 2 +- src/class/midi/midi_device.c | 2 +- src/class/msc/msc_device.c | 2 +- src/class/net/ecm_rndis_device.c | 2 +- src/class/net/ncm_device.c | 2 +- src/class/usbtmc/usbtmc_device.c | 2 +- src/class/vendor/vendor_device.c | 2 +- src/class/video/video_device.c | 2 +- src/device/usbd.c | 2 +- src/device/usbd_control.c | 2 +- src/portable/bridgetek/ft9xx/dcd_ft9xx.c | 2 +- src/portable/broadcom/synopsys/dcd_synopsys.c | 2 +- src/portable/chipidea/ci_hs/dcd_ci_hs.c | 2 +- src/portable/dialog/da146xx/dcd_da146xx.c | 2 +- src/portable/espressif/esp32sx/dcd_esp32sx.c | 2 +- src/portable/mentor/musb/dcd_musb.c | 2 +- src/portable/microchip/pic32mz/dcd_pic32mz.c | 2 +- src/portable/microchip/samd/dcd_samd.c | 2 +- src/portable/microchip/samx7x/dcd_samx7x.c | 2 +- src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c | 2 +- src/portable/nordic/nrf5x/dcd_nrf5x.c | 2 +- src/portable/nuvoton/nuc120/dcd_nuc120.c | 2 +- src/portable/nuvoton/nuc121/dcd_nuc121.c | 2 +- src/portable/nuvoton/nuc505/dcd_nuc505.c | 2 +- src/portable/nxp/khci/dcd_khci.c | 2 +- src/portable/nxp/lpc17_40/dcd_lpc17_40.c | 2 +- src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c | 2 +- src/portable/nxp/transdimension/dcd_transdimension.c | 2 +- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 2 +- src/portable/renesas/usba/dcd_usba.c | 2 +- src/portable/sony/cxd56/dcd_cxd56.c | 2 +- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 2 +- src/portable/st/synopsys/dcd_synopsys.c | 2 +- src/portable/sunxi/dcd_sunxi_musb.c | 2 +- src/portable/synopsys/dwc2/dcd_dwc2.c | 2 +- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 2 +- src/portable/valentyusb/eptri/dcd_eptri.c | 2 +- src/tusb.c | 8 ++++---- src/tusb.h | 2 +- src/tusb_option.h | 5 ++++- 59 files changed, 70 insertions(+), 67 deletions(-) diff --git a/hw/bsp/board.h b/hw/bsp/board.h index 782e0939c..b4e0cb298 100644 --- a/hw/bsp/board.h +++ b/hw/bsp/board.h @@ -120,7 +120,7 @@ static inline void board_delay(uint32_t ms) uint32_t start_ms = board_millis(); while (board_millis() - start_ms < ms) { - #if TUSB_OPT_DEVICE_ENABLED + #if CFG_TUD_ENABLED // take chance to run usb background tud_task(); #endif diff --git a/hw/bsp/brtmm90x/family.c b/hw/bsp/brtmm90x/family.c index 803a62a95..6b3c1f56c 100644 --- a/hw/bsp/brtmm90x/family.c +++ b/hw/bsp/brtmm90x/family.c @@ -30,7 +30,7 @@ #include #include -#if TUSB_OPT_DEVICE_ENABLED +#if CFG_TUD_ENABLED int8_t board_ft90x_vbus(void); // Board specific implementation of VBUS detection for USB device. extern void ft90x_usbd_pm_ISR(uint16_t pmcfg); // Interrupt handler for USB device power management #endif @@ -152,14 +152,14 @@ void board_pm_ISR(void) MASK_SYS_PMCFG_HOST_RESUME_DEV) ) { -#if TUSB_OPT_DEVICE_ENABLED +#if CFG_TUD_ENABLED ft90x_usbd_pm_ISR(pmcfg); #endif } #endif } -#if TUSB_OPT_DEVICE_ENABLED +#if CFG_TUD_ENABLED int8_t board_ft90x_vbus(void) { return gpio_read(USBD_VBUS_DTC_PIN); diff --git a/hw/bsp/d5035_01/d5035_01.c b/hw/bsp/d5035_01/d5035_01.c index 5685ff16f..f356851f7 100644 --- a/hw/bsp/d5035_01/d5035_01.c +++ b/hw/bsp/d5035_01/d5035_01.c @@ -270,7 +270,7 @@ void board_init(void) #endif -#if TUSB_OPT_DEVICE_ENABLED +#if CFG_TUD_ENABLED #if CFG_TUSB_DEBUG >= 2 uart_send_str(BOARD_NAME " USB device enabled\n"); #endif diff --git a/hw/bsp/da14695_dk_usb/da14695_dk_usb.c b/hw/bsp/da14695_dk_usb/da14695_dk_usb.c index 95fe70d01..a4d996810 100644 --- a/hw/bsp/da14695_dk_usb/da14695_dk_usb.c +++ b/hw/bsp/da14695_dk_usb/da14695_dk_usb.c @@ -73,7 +73,7 @@ void board_init(void) // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); -#if TUSB_OPT_DEVICE_ENABLED +#if CFG_TUD_ENABLED // This board is USB powered there is no need to monitor // VBUS line. Notify driver that VBUS is present. tusb_vbus_changed(true); diff --git a/hw/bsp/da1469x_dk_pro/da1469x-dk-pro.c b/hw/bsp/da1469x_dk_pro/da1469x-dk-pro.c index 0441c000c..13113fb95 100644 --- a/hw/bsp/da1469x_dk_pro/da1469x-dk-pro.c +++ b/hw/bsp/da1469x_dk_pro/da1469x-dk-pro.c @@ -36,7 +36,7 @@ void USB_IRQHandler(void) tud_int_handler(0); } -#if TUSB_OPT_DEVICE_ENABLED +#if CFG_TUD_ENABLED // DA146xx driver function that must be called whenever VBUS changes extern void tusb_vbus_changed(bool present); @@ -85,7 +85,7 @@ void board_init(void) // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); -#if TUSB_OPT_DEVICE_ENABLED +#if CFG_TUD_ENABLED // Setup interrupt for both connect and disconnect CRG_TOP->VBUS_IRQ_MASK_REG = CRG_TOP_VBUS_IRQ_MASK_REG_VBUS_IRQ_EN_FALL_Msk | CRG_TOP_VBUS_IRQ_MASK_REG_VBUS_IRQ_EN_RISE_Msk; diff --git a/hw/bsp/frdm_kl25z/frdm_kl25z.c b/hw/bsp/frdm_kl25z/frdm_kl25z.c index 2930ed56e..5f2a5b23d 100644 --- a/hw/bsp/frdm_kl25z/frdm_kl25z.c +++ b/hw/bsp/frdm_kl25z/frdm_kl25z.c @@ -42,7 +42,7 @@ void USB0_IRQHandler(void) #if TUSB_OPT_HOST_ENABLED tuh_int_handler(0); #endif -#if TUSB_OPT_DEVICE_ENABLED +#if CFG_TUD_ENABLED tud_int_handler(0); #endif } diff --git a/hw/bsp/lpcxpresso1769/lpcxpresso1769.c b/hw/bsp/lpcxpresso1769/lpcxpresso1769.c index 101cc8a4c..e62544390 100644 --- a/hw/bsp/lpcxpresso1769/lpcxpresso1769.c +++ b/hw/bsp/lpcxpresso1769/lpcxpresso1769.c @@ -156,7 +156,7 @@ void board_init(void) // 0x1B // Host + Device + OTG + AHB }; - uint32_t const clk_en = TUSB_OPT_DEVICE_ENABLED ? USBCLK_DEVCIE : USBCLK_HOST; + uint32_t const clk_en = CFG_TUD_ENABLED ? USBCLK_DEVCIE : USBCLK_HOST; LPC_USB->OTGClkCtrl = clk_en; while ( (LPC_USB->OTGClkSt & clk_en) != clk_en ); diff --git a/hw/bsp/mbed1768/mbed1768.c b/hw/bsp/mbed1768/mbed1768.c index 5495ed166..85dffde77 100644 --- a/hw/bsp/mbed1768/mbed1768.c +++ b/hw/bsp/mbed1768/mbed1768.c @@ -130,7 +130,7 @@ void board_init(void) // 0x1B // Host + Device + OTG + AHB }; - uint32_t const clk_en = TUSB_OPT_DEVICE_ENABLED ? USBCLK_DEVCIE : USBCLK_HOST; + uint32_t const clk_en = CFG_TUD_ENABLED ? USBCLK_DEVCIE : USBCLK_HOST; LPC_USB->OTGClkCtrl = clk_en; while ( (LPC_USB->OTGClkSt & clk_en) != clk_en ); diff --git a/hw/bsp/msp432e4/family.c b/hw/bsp/msp432e4/family.c index 262dc1d30..d553b362e 100644 --- a/hw/bsp/msp432e4/family.c +++ b/hw/bsp/msp432e4/family.c @@ -36,7 +36,7 @@ void USB0_IRQHandler(void) #if TUSB_OPT_HOST_ENABLED tuh_int_handler(0); #endif -#if TUSB_OPT_DEVICE_ENABLED +#if CFG_TUD_ENABLED tud_int_handler(0); #endif } @@ -148,7 +148,7 @@ void board_init(void) USB0->GPCS = USB_GPCS_DEVMOD_OTG; USB0->EPC = USB_EPC_EPENDE | USB_EPC_EPEN_HIGH; #endif -#if TUSB_OPT_DEVICE_ENABLED +#if CFG_TUD_ENABLED USB0->GPCS = USB_GPCS_DEVMOD_DEVVBUS; #endif } diff --git a/hw/bsp/nrf/family.c b/hw/bsp/nrf/family.c index ed742daaf..a07332d4c 100644 --- a/hw/bsp/nrf/family.c +++ b/hw/bsp/nrf/family.c @@ -100,7 +100,7 @@ void board_init(void) nrfx_uarte_init(&_uart_id, &uart_cfg, NULL); //uart_handler); //------------- USB -------------// -#if TUSB_OPT_DEVICE_ENABLED +#if CFG_TUD_ENABLED // Priorities 0, 1, 4 (nRF52) are reserved for SoftDevice // 2 is highest for application NVIC_SetPriority(USBD_IRQn, 2); diff --git a/hw/bsp/rp2040/family.c b/hw/bsp/rp2040/family.c index 10ead2776..6d0f7ed38 100644 --- a/hw/bsp/rp2040/family.c +++ b/hw/bsp/rp2040/family.c @@ -138,7 +138,7 @@ void board_init(void) #endif // todo probably set up device mode? -#if TUSB_OPT_DEVICE_ENABLED +#if CFG_TUD_ENABLED #endif diff --git a/hw/bsp/rx/boards/rx65n_target/rx65n_target.c b/hw/bsp/rx/boards/rx65n_target/rx65n_target.c index d658ee5dd..56bf575b2 100644 --- a/hw/bsp/rx/boards/rx65n_target/rx65n_target.c +++ b/hw/bsp/rx/boards/rx65n_target/rx65n_target.c @@ -179,7 +179,7 @@ void INT_Excep_USB0_USBI0(void) #if TUSB_OPT_HOST_ENABLED tuh_int_handler(0); #endif -#if TUSB_OPT_DEVICE_ENABLED +#if CFG_TUD_ENABLED tud_int_handler(0); #endif } diff --git a/hw/bsp/same54xplainedpro/same54xplainedpro.c b/hw/bsp/same54xplainedpro/same54xplainedpro.c index 4c38fc6eb..ba1eec38b 100644 --- a/hw/bsp/same54xplainedpro/same54xplainedpro.c +++ b/hw/bsp/same54xplainedpro/same54xplainedpro.c @@ -223,7 +223,7 @@ void board_init(void) #endif -#if TUSB_OPT_DEVICE_ENABLED +#if CFG_TUD_ENABLED #if CFG_TUSB_DEBUG >= 2 uart_send_str(BOARD_NAME " USB device enabled\n"); #endif diff --git a/hw/bsp/tm4c123/family.c b/hw/bsp/tm4c123/family.c index 449781ce1..1e19e7f43 100644 --- a/hw/bsp/tm4c123/family.c +++ b/hw/bsp/tm4c123/family.c @@ -11,7 +11,7 @@ void USB0_Handler(void) tuh_int_handler(0); #endif -#if TUSB_OPT_DEVICE_ENABLED +#if CFG_TUD_ENABLED tud_int_handler(0); #endif } diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index d21980060..06979b09e 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -50,7 +50,7 @@ #include "tusb_option.h" -#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_AUDIO) +#if (CFG_TUD_ENABLED && CFG_TUD_AUDIO) //--------------------------------------------------------------------+ // INCLUDE @@ -2291,4 +2291,4 @@ uint8_t audiod_get_audio_fct_idx(audiod_function_t * audio) return 0; } -#endif //TUSB_OPT_DEVICE_ENABLED && CFG_TUD_AUDIO +#endif //CFG_TUD_ENABLED && CFG_TUD_AUDIO diff --git a/src/class/bth/bth_device.c b/src/class/bth/bth_device.c index 8ef609622..f40bfbd0d 100755 --- a/src/class/bth/bth_device.c +++ b/src/class/bth/bth_device.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_BTH) +#if (CFG_TUD_ENABLED && CFG_TUD_BTH) //--------------------------------------------------------------------+ // INCLUDE diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 08f2af253..2b9b84e7a 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_CDC) +#if (CFG_TUD_ENABLED && CFG_TUD_CDC) #include "device/usbd.h" #include "device/usbd_pvt.h" diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index ddfa608e4..8d859d2ee 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_DFU) +#if (CFG_TUD_ENABLED && CFG_TUD_DFU) #include "device/usbd.h" #include "device/usbd_pvt.h" diff --git a/src/class/dfu/dfu_rt_device.c b/src/class/dfu/dfu_rt_device.c index afee2aa1f..b9cd6096b 100644 --- a/src/class/dfu/dfu_rt_device.c +++ b/src/class/dfu/dfu_rt_device.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_DFU_RUNTIME) +#if (CFG_TUD_ENABLED && CFG_TUD_DFU_RUNTIME) #include "device/usbd.h" #include "device/usbd_pvt.h" diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 588b61254..562ca7f36 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_HID) +#if (CFG_TUD_ENABLED && CFG_TUD_HID) //--------------------------------------------------------------------+ // INCLUDE diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index b08b362f9..2ce1376bd 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_MIDI) +#if (CFG_TUD_ENABLED && CFG_TUD_MIDI) //--------------------------------------------------------------------+ // INCLUDE diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index e09a2b11a..318947a67 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_MSC) +#if (CFG_TUD_ENABLED && CFG_TUD_MSC) #include "device/usbd.h" #include "device/usbd_pvt.h" diff --git a/src/class/net/ecm_rndis_device.c b/src/class/net/ecm_rndis_device.c index c6cd388e3..f6b318058 100644 --- a/src/class/net/ecm_rndis_device.c +++ b/src/class/net/ecm_rndis_device.c @@ -27,7 +27,7 @@ #include "tusb_option.h" -#if ( TUSB_OPT_DEVICE_ENABLED && CFG_TUD_ECM_RNDIS ) +#if ( CFG_TUD_ENABLED && CFG_TUD_ECM_RNDIS ) #include "device/usbd.h" #include "device/usbd_pvt.h" diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 3e131a85c..1987337f8 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -28,7 +28,7 @@ #include "tusb_option.h" -#if ( TUSB_OPT_DEVICE_ENABLED && CFG_TUD_NCM ) +#if ( CFG_TUD_ENABLED && CFG_TUD_NCM ) #include "device/usbd.h" #include "device/usbd_pvt.h" diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 26be987cf..b02b07575 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -68,7 +68,7 @@ #include "tusb_option.h" -#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_USBTMC) +#if (CFG_TUD_ENABLED && CFG_TUD_USBTMC) #include "device/usbd.h" #include "device/usbd_pvt.h" diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index 8a4ca1d2e..394b39b27 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_VENDOR) +#if (CFG_TUD_ENABLED && CFG_TUD_VENDOR) #include "device/usbd.h" #include "device/usbd_pvt.h" diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index eeb068197..91718f205 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -27,7 +27,7 @@ #include "tusb_option.h" -#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_VIDEO && CFG_TUD_VIDEO_STREAMING) +#if (CFG_TUD_ENABLED && CFG_TUD_VIDEO && CFG_TUD_VIDEO_STREAMING) #include "device/usbd.h" #include "device/usbd_pvt.h" diff --git a/src/device/usbd.c b/src/device/usbd.c index 37ca9822f..e6861ee0a 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if TUSB_OPT_DEVICE_ENABLED +#if CFG_TUD_ENABLED #include "tusb.h" #include "device/usbd.h" diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index 7a8244699..4f4108090 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if TUSB_OPT_DEVICE_ENABLED +#if CFG_TUD_ENABLED #include "tusb.h" #include "device/usbd_pvt.h" diff --git a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c index d46723caa..791f6cf60 100644 --- a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c +++ b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c @@ -31,7 +31,7 @@ #include "tusb_option.h" -#if TUSB_OPT_DEVICE_ENABLED && \ +#if CFG_TUD_ENABLED && \ (CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X) #include diff --git a/src/portable/broadcom/synopsys/dcd_synopsys.c b/src/portable/broadcom/synopsys/dcd_synopsys.c index 494bb70ee..c4881ee50 100644 --- a/src/portable/broadcom/synopsys/dcd_synopsys.c +++ b/src/portable/broadcom/synopsys/dcd_synopsys.c @@ -29,7 +29,7 @@ #include "tusb_option.h" -#if TUSB_OPT_DEVICE_ENABLED && \ +#if CFG_TUD_ENABLED && \ (CFG_TUSB_MCU == OPT_MCU_BCM2711 ) \ diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c index c943396fc..ffb2ebd16 100644 --- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c @@ -27,7 +27,7 @@ #include "tusb_option.h" #include "device/dcd_attr.h" -#if TUSB_OPT_DEVICE_ENABLED && defined(DCD_ATTR_CONTROLLER_CHIPIDEA_HS) +#if CFG_TUD_ENABLED && defined(DCD_ATTR_CONTROLLER_CHIPIDEA_HS) //--------------------------------------------------------------------+ // INCLUDE diff --git a/src/portable/dialog/da146xx/dcd_da146xx.c b/src/portable/dialog/da146xx/dcd_da146xx.c index 02fad8165..919249a09 100644 --- a/src/portable/dialog/da146xx/dcd_da146xx.c +++ b/src/portable/dialog/da146xx/dcd_da146xx.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if TUSB_OPT_DEVICE_ENABLED && CFG_TUSB_MCU == OPT_MCU_DA1469X +#if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_DA1469X #include "mcu/mcu.h" diff --git a/src/portable/espressif/esp32sx/dcd_esp32sx.c b/src/portable/espressif/esp32sx/dcd_esp32sx.c index a9c311324..99cd08e4d 100644 --- a/src/portable/espressif/esp32sx/dcd_esp32sx.c +++ b/src/portable/espressif/esp32sx/dcd_esp32sx.c @@ -28,7 +28,7 @@ #include "tusb_option.h" -#if (((CFG_TUSB_MCU == OPT_MCU_ESP32S2) || (CFG_TUSB_MCU == OPT_MCU_ESP32S3)) && TUSB_OPT_DEVICE_ENABLED) +#if (((CFG_TUSB_MCU == OPT_MCU_ESP32S2) || (CFG_TUSB_MCU == OPT_MCU_ESP32S3)) && CFG_TUD_ENABLED) // Espressif #include "freertos/xtensa_api.h" diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index f6e05e134..71414e737 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if TUSB_OPT_DEVICE_ENABLED && \ +#if CFG_TUD_ENABLED && \ TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) #if __GNUC__ > 8 && defined(__ARM_FEATURE_UNALIGNED) diff --git a/src/portable/microchip/pic32mz/dcd_pic32mz.c b/src/portable/microchip/pic32mz/dcd_pic32mz.c index 740e5edbb..7d48f755b 100644 --- a/src/portable/microchip/pic32mz/dcd_pic32mz.c +++ b/src/portable/microchip/pic32mz/dcd_pic32mz.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if TUSB_OPT_DEVICE_ENABLED && CFG_TUSB_MCU == OPT_MCU_PIC32MZ +#if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_PIC32MZ #include #include diff --git a/src/portable/microchip/samd/dcd_samd.c b/src/portable/microchip/samd/dcd_samd.c index 46aabc5aa..c4ee6f2f5 100644 --- a/src/portable/microchip/samd/dcd_samd.c +++ b/src/portable/microchip/samd/dcd_samd.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if TUSB_OPT_DEVICE_ENABLED && \ +#if CFG_TUD_ENABLED && \ (CFG_TUSB_MCU == OPT_MCU_SAMD11 || CFG_TUSB_MCU == OPT_MCU_SAMD21 || \ CFG_TUSB_MCU == OPT_MCU_SAMD51 || CFG_TUSB_MCU == OPT_MCU_SAME5X || \ CFG_TUSB_MCU == OPT_MCU_SAML22 || CFG_TUSB_MCU == OPT_MCU_SAML21) diff --git a/src/portable/microchip/samx7x/dcd_samx7x.c b/src/portable/microchip/samx7x/dcd_samx7x.c index 9e3b43840..a82f29a88 100644 --- a/src/portable/microchip/samx7x/dcd_samx7x.c +++ b/src/portable/microchip/samx7x/dcd_samx7x.c @@ -27,7 +27,7 @@ #include "tusb_option.h" -#if TUSB_OPT_DEVICE_ENABLED && CFG_TUSB_MCU == OPT_MCU_SAMX7X +#if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_SAMX7X #include "device/dcd.h" #include "sam.h" diff --git a/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c b/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c index a3b69b987..1edcd8458 100644 --- a/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c +++ b/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if TUSB_OPT_DEVICE_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_MM32F327X ) +#if CFG_TUD_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_MM32F327X ) #include "reg_usb_otg_fs.h" #include "mm32_device.h" diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 024ea0d90..bc145eaa4 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if TUSB_OPT_DEVICE_ENABLED && CFG_TUSB_MCU == OPT_MCU_NRF5X +#if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_NRF5X #include "nrf.h" #include "nrf_clock.h" diff --git a/src/portable/nuvoton/nuc120/dcd_nuc120.c b/src/portable/nuvoton/nuc120/dcd_nuc120.c index 0d45090d1..694766613 100644 --- a/src/portable/nuvoton/nuc120/dcd_nuc120.c +++ b/src/portable/nuvoton/nuc120/dcd_nuc120.c @@ -35,7 +35,7 @@ #include "tusb_option.h" -#if TUSB_OPT_DEVICE_ENABLED && (CFG_TUSB_MCU == OPT_MCU_NUC120) +#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_NUC120) #include "device/dcd.h" #include "NUC100Series.h" diff --git a/src/portable/nuvoton/nuc121/dcd_nuc121.c b/src/portable/nuvoton/nuc121/dcd_nuc121.c index fc7150508..88d514bce 100644 --- a/src/portable/nuvoton/nuc121/dcd_nuc121.c +++ b/src/portable/nuvoton/nuc121/dcd_nuc121.c @@ -35,7 +35,7 @@ #include "tusb_option.h" -#if TUSB_OPT_DEVICE_ENABLED && ( (CFG_TUSB_MCU == OPT_MCU_NUC121) || (CFG_TUSB_MCU == OPT_MCU_NUC126) ) +#if CFG_TUD_ENABLED && ( (CFG_TUSB_MCU == OPT_MCU_NUC121) || (CFG_TUSB_MCU == OPT_MCU_NUC126) ) #include "device/dcd.h" #include "NuMicro.h" diff --git a/src/portable/nuvoton/nuc505/dcd_nuc505.c b/src/portable/nuvoton/nuc505/dcd_nuc505.c index aefb09f4e..498977561 100644 --- a/src/portable/nuvoton/nuc505/dcd_nuc505.c +++ b/src/portable/nuvoton/nuc505/dcd_nuc505.c @@ -35,7 +35,7 @@ #include "tusb_option.h" -#if TUSB_OPT_DEVICE_ENABLED && (CFG_TUSB_MCU == OPT_MCU_NUC505) +#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_NUC505) #include "device/dcd.h" #include "NUC505Series.h" diff --git a/src/portable/nxp/khci/dcd_khci.c b/src/portable/nxp/khci/dcd_khci.c index 8de924f90..4c7737103 100644 --- a/src/portable/nxp/khci/dcd_khci.c +++ b/src/portable/nxp/khci/dcd_khci.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if TUSB_OPT_DEVICE_ENABLED && ( \ +#if CFG_TUD_ENABLED && ( \ ( CFG_TUSB_MCU == OPT_MCU_MKL25ZXX ) || ( CFG_TUSB_MCU == OPT_MCU_K32L2BXX ) \ ) diff --git a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c index 0f500a88f..d2cce2db3 100644 --- a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c +++ b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if TUSB_OPT_DEVICE_ENABLED && \ +#if CFG_TUD_ENABLED && \ (CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX) #include "device/dcd.h" diff --git a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c index 1bdf72d6d..55d872dc0 100644 --- a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c +++ b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c @@ -34,7 +34,7 @@ * - LPC54114 * - LPC55s69 */ -#if TUSB_OPT_DEVICE_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_LPC11UXX || \ +#if CFG_TUD_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_LPC11UXX || \ CFG_TUSB_MCU == OPT_MCU_LPC13XX || \ CFG_TUSB_MCU == OPT_MCU_LPC15XX || \ CFG_TUSB_MCU == OPT_MCU_LPC51UXX || \ diff --git a/src/portable/nxp/transdimension/dcd_transdimension.c b/src/portable/nxp/transdimension/dcd_transdimension.c index f6433293d..9f5979ab4 100644 --- a/src/portable/nxp/transdimension/dcd_transdimension.c +++ b/src/portable/nxp/transdimension/dcd_transdimension.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if TUSB_OPT_DEVICE_ENABLED && \ +#if CFG_TUD_ENABLED && \ (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX) #warning "transdimenion is renamed to chipidea (portable/chipidea/ci_hs) to match other opensource naming convention such as linux. This file will be removed in the future, please update your makefile accordingly" diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index 42add3167..915822798 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if TUSB_OPT_DEVICE_ENABLED && CFG_TUSB_MCU == OPT_MCU_RP2040 +#if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_RP2040 #include "pico.h" #include "rp2040_usb.h" diff --git a/src/portable/renesas/usba/dcd_usba.c b/src/portable/renesas/usba/dcd_usba.c index ae7d2fd0c..eb3541af4 100644 --- a/src/portable/renesas/usba/dcd_usba.c +++ b/src/portable/renesas/usba/dcd_usba.c @@ -31,7 +31,7 @@ // We disable SOF for now until needed later on #define USE_SOF 0 -#if TUSB_OPT_DEVICE_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_RX63X || \ +#if CFG_TUD_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_RX63X || \ CFG_TUSB_MCU == OPT_MCU_RX65X || \ CFG_TUSB_MCU == OPT_MCU_RX72N ) #include "device/dcd.h" diff --git a/src/portable/sony/cxd56/dcd_cxd56.c b/src/portable/sony/cxd56/dcd_cxd56.c index f2a20accb..fbea03b1d 100644 --- a/src/portable/sony/cxd56/dcd_cxd56.c +++ b/src/portable/sony/cxd56/dcd_cxd56.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if TUSB_OPT_DEVICE_ENABLED && CFG_TUSB_MCU == OPT_MCU_CXD56 +#if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_CXD56 #include #include diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 177a7ad2a..f201a02cf 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -109,7 +109,7 @@ #define STM32F1_FSDEV #endif -#if TUSB_OPT_DEVICE_ENABLED && \ +#if CFG_TUD_ENABLED && \ ( TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32F3, OPT_MCU_STM32L0, OPT_MCU_STM32L1, OPT_MCU_STM32G4) || \ (TU_CHECK_MCU(OPT_MCU_STM32F1) && defined(STM32F1_FSDEV)) \ ) diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index 4782ead8c..d7f659340 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -45,7 +45,7 @@ #define STM32L4_SYNOPSYS #endif -#if TUSB_OPT_DEVICE_ENABLED && \ +#if CFG_TUD_ENABLED && \ ( (CFG_TUSB_MCU == OPT_MCU_STM32F1 && defined(STM32F1_SYNOPSYS)) || \ CFG_TUSB_MCU == OPT_MCU_STM32F2 || \ CFG_TUSB_MCU == OPT_MCU_STM32F4 || \ diff --git a/src/portable/sunxi/dcd_sunxi_musb.c b/src/portable/sunxi/dcd_sunxi_musb.c index cf93c9bc4..447069f88 100644 --- a/src/portable/sunxi/dcd_sunxi_musb.c +++ b/src/portable/sunxi/dcd_sunxi_musb.c @@ -29,7 +29,7 @@ #include #include "tusb_option.h" -#if TUSB_OPT_DEVICE_ENABLED && CFG_TUSB_MCU == OPT_MCU_F1C100S +#if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_F1C100S #include "osal/osal.h" #include diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 188611743..86dc760c8 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -30,7 +30,7 @@ #include "tusb_option.h" #include "device/dcd_attr.h" -#if TUSB_OPT_DEVICE_ENABLED && \ +#if CFG_TUD_ENABLED && \ ( defined(DCD_ATTR_DWC2_STM32) || \ TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3, OPT_MCU_GD32VF103) || \ TU_CHECK_MCU(OPT_MCU_EFM32GG, OPT_MCU_BCM2711, OPT_MCU_BCM2835) || \ diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 3b91f2798..c3b3b2403 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -27,7 +27,7 @@ #include "tusb_option.h" -#if TUSB_OPT_DEVICE_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_MSP430x5xx ) +#if CFG_TUD_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_MSP430x5xx ) #include "msp430.h" #include "device/dcd.h" diff --git a/src/portable/valentyusb/eptri/dcd_eptri.c b/src/portable/valentyusb/eptri/dcd_eptri.c index 51fb8b401..dfadfdcb3 100644 --- a/src/portable/valentyusb/eptri/dcd_eptri.c +++ b/src/portable/valentyusb/eptri/dcd_eptri.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if TUSB_OPT_DEVICE_ENABLED && (CFG_TUSB_MCU == OPT_MCU_VALENTYUSB_EPTRI) +#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_VALENTYUSB_EPTRI) #ifndef DEBUG #define DEBUG 0 diff --git a/src/tusb.c b/src/tusb.c index 9583f509d..cad434a92 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -26,18 +26,18 @@ #include "tusb_option.h" -#if TUSB_OPT_HOST_ENABLED || TUSB_OPT_DEVICE_ENABLED +#if TUSB_OPT_HOST_ENABLED || CFG_TUD_ENABLED #include "tusb.h" // TODO clean up -#if TUSB_OPT_DEVICE_ENABLED +#if CFG_TUD_ENABLED #include "device/usbd_pvt.h" #endif bool tusb_init(void) { -#if TUSB_OPT_DEVICE_ENABLED +#if CFG_TUD_ENABLED TU_ASSERT ( tud_init(TUD_OPT_RHPORT) ); // init device stack #endif @@ -52,7 +52,7 @@ bool tusb_inited(void) { bool ret = false; -#if TUSB_OPT_DEVICE_ENABLED +#if CFG_TUD_ENABLED ret = ret || tud_inited(); #endif diff --git a/src/tusb.h b/src/tusb.h index 0d29e106c..2ffc1f681 100644 --- a/src/tusb.h +++ b/src/tusb.h @@ -61,7 +61,7 @@ #endif //------------- DEVICE -------------// -#if TUSB_OPT_DEVICE_ENABLED +#if CFG_TUD_ENABLED #include "device/usbd.h" #if CFG_TUD_HID diff --git a/src/tusb_option.h b/src/tusb_option.h index cb49c85ce..0e88c1507 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -215,7 +215,10 @@ #define TUD_OPT_HIGH_SPEED ( (CFG_TUSB_RHPORT1_MODE) & OPT_MODE_HIGH_SPEED ) #endif -#define TUSB_OPT_DEVICE_ENABLED ( TUD_OPT_RHPORT >= 0 ) +#define CFG_TUD_ENABLED ( TUD_OPT_RHPORT >= 0 ) + +// For backward compatible +#define TUSB_OPT_DEVICE_ENABLED CFG_TUD_ENABLED //--------------------------------------------------------------------+ // COMMON OPTIONS From 31aa077cb0b345464548b9cb2e2913227348a969 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 23 Feb 2022 21:49:11 +0700 Subject: [PATCH 163/504] rename TUSB_OPT_HOST_ENABLED to CFG_TUH_ENABLED --- hw/bsp/frdm_kl25z/frdm_kl25z.c | 2 +- hw/bsp/lpcxpresso1769/lpcxpresso1769.c | 2 +- hw/bsp/mbed1768/mbed1768.c | 2 +- hw/bsp/msp432e4/family.c | 6 +++--- hw/bsp/rp2040/family.c | 2 +- hw/bsp/rx/boards/rx65n_target/rx65n_target.c | 2 +- hw/bsp/tm4c123/family.c | 2 +- src/class/cdc/cdc_host.c | 2 +- src/class/cdc/cdc_rndis_host.c | 2 +- src/class/hid/hid_host.c | 2 +- src/class/msc/msc_host.c | 2 +- src/class/vendor/vendor_host.c | 2 +- src/host/hcd.h | 2 +- src/host/hub.c | 2 +- src/host/usbh.c | 2 +- src/host/usbh_control.c | 2 +- src/osal/osal_pico.h | 2 +- src/portable/chipidea/ci_hs/hcd_ci_hs.c | 2 +- src/portable/ehci/ehci.c | 2 +- src/portable/mentor/musb/hcd_musb.c | 2 +- src/portable/nxp/khci/hcd_khci.c | 2 +- src/portable/nxp/lpc17_40/hcd_lpc17_40.c | 2 +- .../nxp/transdimension/hcd_transdimension.c | 2 +- src/portable/ohci/ohci.c | 2 +- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 2 +- src/portable/raspberrypi/rp2040/rp2040_usb.c | 2 +- src/portable/raspberrypi/rp2040/rp2040_usb.h | 2 +- src/portable/renesas/usba/hcd_usba.c | 2 +- src/tusb.c | 6 +++--- src/tusb.h | 2 +- src/tusb_option.h | 17 ++++++++--------- 31 files changed, 42 insertions(+), 43 deletions(-) diff --git a/hw/bsp/frdm_kl25z/frdm_kl25z.c b/hw/bsp/frdm_kl25z/frdm_kl25z.c index 5f2a5b23d..8d93fdbaa 100644 --- a/hw/bsp/frdm_kl25z/frdm_kl25z.c +++ b/hw/bsp/frdm_kl25z/frdm_kl25z.c @@ -39,7 +39,7 @@ //--------------------------------------------------------------------+ void USB0_IRQHandler(void) { -#if TUSB_OPT_HOST_ENABLED +#if CFG_TUH_ENABLED tuh_int_handler(0); #endif #if CFG_TUD_ENABLED diff --git a/hw/bsp/lpcxpresso1769/lpcxpresso1769.c b/hw/bsp/lpcxpresso1769/lpcxpresso1769.c index e62544390..b82e5ffe0 100644 --- a/hw/bsp/lpcxpresso1769/lpcxpresso1769.c +++ b/hw/bsp/lpcxpresso1769/lpcxpresso1769.c @@ -161,7 +161,7 @@ void board_init(void) LPC_USB->OTGClkCtrl = clk_en; while ( (LPC_USB->OTGClkSt & clk_en) != clk_en ); -#if TUSB_OPT_HOST_ENABLED +#if CFG_TUH_ENABLED // set portfunc to host !!! LPC_USB->StCtrl = 0x3; // should be 1 #endif diff --git a/hw/bsp/mbed1768/mbed1768.c b/hw/bsp/mbed1768/mbed1768.c index 85dffde77..7c2b37016 100644 --- a/hw/bsp/mbed1768/mbed1768.c +++ b/hw/bsp/mbed1768/mbed1768.c @@ -135,7 +135,7 @@ void board_init(void) LPC_USB->OTGClkCtrl = clk_en; while ( (LPC_USB->OTGClkSt & clk_en) != clk_en ); -#if TUSB_OPT_HOST_ENABLED +#if CFG_TUH_ENABLED // set portfunc to host !!! LPC_USB->StCtrl = 0x3; // should be 1 #endif diff --git a/hw/bsp/msp432e4/family.c b/hw/bsp/msp432e4/family.c index d553b362e..3d2d4085e 100644 --- a/hw/bsp/msp432e4/family.c +++ b/hw/bsp/msp432e4/family.c @@ -33,7 +33,7 @@ //--------------------------------------------------------------------+ void USB0_IRQHandler(void) { -#if TUSB_OPT_HOST_ENABLED +#if CFG_TUH_ENABLED tuh_int_handler(0); #endif #if CFG_TUD_ENABLED @@ -123,7 +123,7 @@ void board_init(void) GPIOB->AMSEL = TU_BIT(0) | TU_BIT(1); GPIOL->AMSEL = TU_BIT(6) | TU_BIT(7); -#if TUSB_OPT_HOST_ENABLED +#if CFG_TUH_ENABLED /* USB PD6(EPEN) */ bits = TU_BIT(3); SYSCTL->RCGCGPIO |= bits; @@ -144,7 +144,7 @@ void board_init(void) USB0->CC = USB_CC_CLKEN | (3u << USB_CC_CLKDIV_S); /* 60MHz = 240MHz / 4 */ __DMB(); /* Wait for completion of opening of the clock gate */ -#if TUSB_OPT_HOST_ENABLED +#if CFG_TUH_ENABLED USB0->GPCS = USB_GPCS_DEVMOD_OTG; USB0->EPC = USB_EPC_EPENDE | USB_EPC_EPEN_HIGH; #endif diff --git a/hw/bsp/rp2040/family.c b/hw/bsp/rp2040/family.c index 6d0f7ed38..fa63dadf5 100644 --- a/hw/bsp/rp2040/family.c +++ b/hw/bsp/rp2040/family.c @@ -142,7 +142,7 @@ void board_init(void) #endif -#if TUSB_OPT_HOST_ENABLED +#if CFG_TUH_ENABLED // set portfunc to host !!! #endif } diff --git a/hw/bsp/rx/boards/rx65n_target/rx65n_target.c b/hw/bsp/rx/boards/rx65n_target/rx65n_target.c index 56bf575b2..f189e40e4 100644 --- a/hw/bsp/rx/boards/rx65n_target/rx65n_target.c +++ b/hw/bsp/rx/boards/rx65n_target/rx65n_target.c @@ -176,7 +176,7 @@ void INT_Excep_SCI5_RXI5(void) //--------------------------------------------------------------------+ void INT_Excep_USB0_USBI0(void) { -#if TUSB_OPT_HOST_ENABLED +#if CFG_TUH_ENABLED tuh_int_handler(0); #endif #if CFG_TUD_ENABLED diff --git a/hw/bsp/tm4c123/family.c b/hw/bsp/tm4c123/family.c index 1e19e7f43..b0947d6c4 100644 --- a/hw/bsp/tm4c123/family.c +++ b/hw/bsp/tm4c123/family.c @@ -7,7 +7,7 @@ //--------------------------------------------------------------------+ void USB0_Handler(void) { -#if TUSB_OPT_HOST_ENABLED +#if CFG_TUH_ENABLED tuh_int_handler(0); #endif diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index f4fb6c1d6..c18234db4 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if (TUSB_OPT_HOST_ENABLED && CFG_TUH_CDC) +#if (CFG_TUH_ENABLED && CFG_TUH_CDC) #include "host/usbh.h" #include "host/usbh_classdriver.h" diff --git a/src/class/cdc/cdc_rndis_host.c b/src/class/cdc/cdc_rndis_host.c index d41cf91ac..8f28f51ac 100644 --- a/src/class/cdc/cdc_rndis_host.c +++ b/src/class/cdc/cdc_rndis_host.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if (TUSB_OPT_HOST_ENABLED && CFG_TUH_CDC && CFG_TUH_CDC_RNDIS) +#if (CFG_TUH_ENABLED && CFG_TUH_CDC && CFG_TUH_CDC_RNDIS) //--------------------------------------------------------------------+ // INCLUDE diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index f19f1ba81..542ed5772 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if (TUSB_OPT_HOST_ENABLED && CFG_TUH_HID) +#if (CFG_TUH_ENABLED && CFG_TUH_HID) #include "host/usbh.h" #include "host/usbh_classdriver.h" diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index fa6519956..a49a10522 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if TUSB_OPT_HOST_ENABLED & CFG_TUH_MSC +#if CFG_TUH_ENABLED & CFG_TUH_MSC #include "host/usbh.h" #include "host/usbh_classdriver.h" diff --git a/src/class/vendor/vendor_host.c b/src/class/vendor/vendor_host.c index 1e28e9af4..dbea1228d 100644 --- a/src/class/vendor/vendor_host.c +++ b/src/class/vendor/vendor_host.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if (TUSB_OPT_HOST_ENABLED && CFG_TUH_VENDOR) +#if (CFG_TUH_ENABLED && CFG_TUH_VENDOR) //--------------------------------------------------------------------+ // INCLUDE diff --git a/src/host/hcd.h b/src/host/hcd.h index eb53d2e80..054fd9647 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -82,7 +82,7 @@ typedef struct } hcd_event_t; -#if TUSB_OPT_HOST_ENABLED +#if CFG_TUH_ENABLED // Max number of endpoints per device enum { // TODO better computation diff --git a/src/host/hub.c b/src/host/hub.c index fd4dbd04a..53eb1d521 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if (TUSB_OPT_HOST_ENABLED && CFG_TUH_HUB) +#if (CFG_TUH_ENABLED && CFG_TUH_HUB) #include "usbh.h" #include "usbh_classdriver.h" diff --git a/src/host/usbh.c b/src/host/usbh.c index 9854b75a3..e29ce1e54 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if TUSB_OPT_HOST_ENABLED +#if CFG_TUH_ENABLED #include "tusb.h" #include "host/usbh.h" diff --git a/src/host/usbh_control.c b/src/host/usbh_control.c index 9204576ac..d034eec7f 100644 --- a/src/host/usbh_control.c +++ b/src/host/usbh_control.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if TUSB_OPT_HOST_ENABLED +#if CFG_TUH_ENABLED #include "tusb.h" #include "usbh_classdriver.h" diff --git a/src/osal/osal_pico.h b/src/osal/osal_pico.h index 4843d6450..70432d22b 100644 --- a/src/osal/osal_pico.h +++ b/src/osal/osal_pico.h @@ -100,7 +100,7 @@ static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) //--------------------------------------------------------------------+ #include "common/tusb_fifo.h" -#if TUSB_OPT_HOST_ENABLED +#if CFG_TUH_ENABLED extern void hcd_int_disable(uint8_t rhport); extern void hcd_int_enable(uint8_t rhport); #endif diff --git a/src/portable/chipidea/ci_hs/hcd_ci_hs.c b/src/portable/chipidea/ci_hs/hcd_ci_hs.c index 3d028bf32..0754b477e 100644 --- a/src/portable/chipidea/ci_hs/hcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/hcd_ci_hs.c @@ -28,7 +28,7 @@ // Chipidea Highspeed USB IP implement EHCI for host functionality -#if TUSB_OPT_HOST_ENABLED && \ +#if CFG_TUH_ENABLED && \ (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX) //--------------------------------------------------------------------+ diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index e92f8a951..6b86cb2b2 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -26,7 +26,7 @@ #include "host/hcd_attr.h" -#if TUSB_OPT_HOST_ENABLED && defined(HCD_ATTR_EHCI_TRANSDIMENSION) +#if CFG_TUH_ENABLED && defined(HCD_ATTR_EHCI_TRANSDIMENSION) //--------------------------------------------------------------------+ // INCLUDE diff --git a/src/portable/mentor/musb/hcd_musb.c b/src/portable/mentor/musb/hcd_musb.c index acccb7674..3bfd65b45 100644 --- a/src/portable/mentor/musb/hcd_musb.c +++ b/src/portable/mentor/musb/hcd_musb.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if TUSB_OPT_HOST_ENABLED && \ +#if CFG_TUH_ENABLED && \ TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) #if __GNUC__ > 8 && defined(__ARM_FEATURE_UNALIGNED) diff --git a/src/portable/nxp/khci/hcd_khci.c b/src/portable/nxp/khci/hcd_khci.c index 92ec04d4a..fc0875cfe 100644 --- a/src/portable/nxp/khci/hcd_khci.c +++ b/src/portable/nxp/khci/hcd_khci.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if TUSB_OPT_HOST_ENABLED && ( \ +#if CFG_TUH_ENABLED && ( \ ( CFG_TUSB_MCU == OPT_MCU_MKL25ZXX ) || ( CFG_TUSB_MCU == OPT_MCU_K32L2BXX ) \ ) diff --git a/src/portable/nxp/lpc17_40/hcd_lpc17_40.c b/src/portable/nxp/lpc17_40/hcd_lpc17_40.c index 1c1faed94..ad9ed59b4 100644 --- a/src/portable/nxp/lpc17_40/hcd_lpc17_40.c +++ b/src/portable/nxp/lpc17_40/hcd_lpc17_40.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if TUSB_OPT_HOST_ENABLED && \ +#if CFG_TUH_ENABLED && \ (CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX) #include "chip.h" diff --git a/src/portable/nxp/transdimension/hcd_transdimension.c b/src/portable/nxp/transdimension/hcd_transdimension.c index 81ad3152d..2d0830981 100644 --- a/src/portable/nxp/transdimension/hcd_transdimension.c +++ b/src/portable/nxp/transdimension/hcd_transdimension.c @@ -28,7 +28,7 @@ // NXP Trans-Dimension USB IP implement EHCI for host functionality -#if TUSB_OPT_HOST_ENABLED && \ +#if CFG_TUH_ENABLED && \ (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX) #warning "transdimenion is renamed to chipidea (portable/chipidea/ci_hs) to match other opensource naming convention such as linux. This file will be removed in the future, please update your makefile accordingly" diff --git a/src/portable/ohci/ohci.c b/src/portable/ohci/ohci.c index daa8075b7..8860f27a2 100644 --- a/src/portable/ohci/ohci.c +++ b/src/portable/ohci/ohci.c @@ -26,7 +26,7 @@ #include "host/hcd_attr.h" -#if TUSB_OPT_HOST_ENABLED && defined(HCD_ATTR_OHCI) +#if CFG_TUH_ENABLED && defined(HCD_ATTR_OHCI) //--------------------------------------------------------------------+ // INCLUDE diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 3e80dd872..b6fbdb200 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -27,7 +27,7 @@ #include "tusb_option.h" -#if TUSB_OPT_HOST_ENABLED && CFG_TUSB_MCU == OPT_MCU_RP2040 +#if CFG_TUH_ENABLED && CFG_TUSB_MCU == OPT_MCU_RP2040 #include "pico.h" #include "rp2040_usb.h" diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index 9d833e65f..293cefaf6 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -87,7 +87,7 @@ void _hw_endpoint_buffer_control_update32(struct hw_endpoint *ep, uint32_t and_m *ep->buffer_control = value & ~USB_BUF_CTRL_AVAIL; // 12 cycle delay.. (should be good for 48*12Mhz = 576Mhz) // Don't need delay in host mode as host is in charge -#if !TUSB_OPT_HOST_ENABLED +#if !CFG_TUH_ENABLED __asm volatile ( "b 1f\n" "1: b 1f\n" diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.h b/src/portable/raspberrypi/rp2040/rp2040_usb.h index a9cf1dd07..da1933ddd 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.h +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.h @@ -56,7 +56,7 @@ typedef struct hw_endpoint // Interrupt, bulk, etc uint8_t transfer_type; -#if TUSB_OPT_HOST_ENABLED +#if CFG_TUH_ENABLED // Only needed for host uint8_t dev_addr; diff --git a/src/portable/renesas/usba/hcd_usba.c b/src/portable/renesas/usba/hcd_usba.c index 35eb060cd..ebb682342 100644 --- a/src/portable/renesas/usba/hcd_usba.c +++ b/src/portable/renesas/usba/hcd_usba.c @@ -27,7 +27,7 @@ #include "tusb_option.h" -#if TUSB_OPT_HOST_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_RX63X || \ +#if CFG_TUH_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_RX63X || \ CFG_TUSB_MCU == OPT_MCU_RX65X || \ CFG_TUSB_MCU == OPT_MCU_RX72N ) #include "host/hcd.h" diff --git a/src/tusb.c b/src/tusb.c index cad434a92..03fe43104 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if TUSB_OPT_HOST_ENABLED || CFG_TUD_ENABLED +#if CFG_TUH_ENABLED || CFG_TUD_ENABLED #include "tusb.h" @@ -41,7 +41,7 @@ bool tusb_init(void) TU_ASSERT ( tud_init(TUD_OPT_RHPORT) ); // init device stack #endif -#if TUSB_OPT_HOST_ENABLED +#if CFG_TUH_ENABLED TU_ASSERT( tuh_init(TUH_OPT_RHPORT) ); // init host stack #endif @@ -56,7 +56,7 @@ bool tusb_inited(void) ret = ret || tud_inited(); #endif -#if TUSB_OPT_HOST_ENABLED +#if CFG_TUH_ENABLED ret = ret || tuh_inited(); #endif diff --git a/src/tusb.h b/src/tusb.h index 2ffc1f681..549f00b43 100644 --- a/src/tusb.h +++ b/src/tusb.h @@ -39,7 +39,7 @@ #include "common/tusb_fifo.h" //------------- HOST -------------// -#if TUSB_OPT_HOST_ENABLED +#if CFG_TUH_ENABLED #include "host/usbh.h" #if CFG_TUH_HID diff --git a/src/tusb_option.h b/src/tusb_option.h index 0e88c1507..714c6ed9e 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -187,12 +187,10 @@ #define OPT_MODE_LOW_SPEED 0x10 ///< Max Low Speed #define OPT_MODE_HIGH_SPEED 0x20 ///< Max High Speed - #ifndef CFG_TUSB_RHPORT0_MODE #define CFG_TUSB_RHPORT0_MODE OPT_MODE_NONE #endif - #ifndef CFG_TUSB_RHPORT1_MODE #define CFG_TUSB_RHPORT1_MODE OPT_MODE_NONE #endif @@ -203,22 +201,23 @@ #endif // Which roothub port is configured as host -#define TUH_OPT_RHPORT ( ((CFG_TUSB_RHPORT0_MODE) & OPT_MODE_HOST) ? 0 : (((CFG_TUSB_RHPORT1_MODE) & OPT_MODE_HOST) ? 1 : -1) ) -#define TUSB_OPT_HOST_ENABLED ( TUH_OPT_RHPORT >= 0 ) +#define TUH_OPT_RHPORT ( ((CFG_TUSB_RHPORT0_MODE) & OPT_MODE_HOST) ? 0 : (((CFG_TUSB_RHPORT1_MODE) & OPT_MODE_HOST) ? 1 : -1) ) +#define CFG_TUH_ENABLED ( TUH_OPT_RHPORT >= 0 ) // Which roothub port is configured as device -#define TUD_OPT_RHPORT ( ((CFG_TUSB_RHPORT0_MODE) & OPT_MODE_DEVICE) ? 0 : (((CFG_TUSB_RHPORT1_MODE) & OPT_MODE_DEVICE) ? 1 : -1) ) +#define TUD_OPT_RHPORT ( ((CFG_TUSB_RHPORT0_MODE) & OPT_MODE_DEVICE) ? 0 : (((CFG_TUSB_RHPORT1_MODE) & OPT_MODE_DEVICE) ? 1 : -1) ) #if TUD_OPT_RHPORT == 0 -#define TUD_OPT_HIGH_SPEED ( (CFG_TUSB_RHPORT0_MODE) & OPT_MODE_HIGH_SPEED ) +#define TUD_OPT_HIGH_SPEED ( (CFG_TUSB_RHPORT0_MODE) & OPT_MODE_HIGH_SPEED ) #else -#define TUD_OPT_HIGH_SPEED ( (CFG_TUSB_RHPORT1_MODE) & OPT_MODE_HIGH_SPEED ) +#define TUD_OPT_HIGH_SPEED ( (CFG_TUSB_RHPORT1_MODE) & OPT_MODE_HIGH_SPEED ) #endif #define CFG_TUD_ENABLED ( TUD_OPT_RHPORT >= 0 ) // For backward compatible #define TUSB_OPT_DEVICE_ENABLED CFG_TUD_ENABLED +#define TUSB_OPT_HOST_ENABLED CFG_TUH_ENABLED //--------------------------------------------------------------------+ // COMMON OPTIONS @@ -316,7 +315,7 @@ //-------------------------------------------------------------------- // HOST OPTIONS //-------------------------------------------------------------------- -#if TUSB_OPT_HOST_ENABLED +#if CFG_TUH_ENABLED #ifndef CFG_TUH_DEVICE_MAX #define CFG_TUH_DEVICE_MAX 1 #endif @@ -324,7 +323,7 @@ #ifndef CFG_TUH_ENUMERATION_BUFSIZE #define CFG_TUH_ENUMERATION_BUFSIZE 256 #endif -#endif // TUSB_OPT_HOST_ENABLED +#endif // CFG_TUH_ENABLED //------------- CLASS -------------// From a8af609dfef0f82ce22e6f0bf48146b4b2433633 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 25 Feb 2022 13:00:05 +0700 Subject: [PATCH 164/504] auto detect max rhport speed based on mcu --- .../audio_4_channel_mic/src/tusb_config.h | 4 -- examples/device/audio_test/src/tusb_config.h | 4 -- .../device/cdc_dual_ports/src/tusb_config.h | 9 +--- examples/device/cdc_msc/src/tusb_config.h | 10 +--- examples/device/dfu/src/tusb_config.h | 9 +--- examples/device/dfu_runtime/src/tusb_config.h | 9 +--- .../dynamic_configuration/src/tusb_config.h | 9 +--- .../hid_boot_interface/src/tusb_config.h | 10 +--- .../device/hid_composite/src/tusb_config.h | 10 +--- .../hid_composite_freertos/src/tusb_config.h | 9 +--- .../hid_generic_inout/src/tusb_config.h | 9 +--- .../hid_multiple_interface/src/tusb_config.h | 10 +--- examples/device/midi_test/src/tusb_config.h | 10 +--- .../device/msc_dual_lun/src/tusb_config.h | 9 +--- .../net_lwip_webserver/src/tusb_config.h | 9 +--- .../device/uac2_headset/src/tusb_config.h | 8 ++-- examples/device/usbtmc/src/tusb_config.h | 9 +--- .../device/video_capture/src/tusb_config.h | 9 +--- .../device/webusb_serial/src/tusb_config.h | 9 +--- src/device/dcd_attr.h | 33 ++++++++----- src/device/usbd.h | 8 ++-- src/tusb_option.h | 47 ++++++++++++------- 22 files changed, 90 insertions(+), 163 deletions(-) diff --git a/examples/device/audio_4_channel_mic/src/tusb_config.h b/examples/device/audio_4_channel_mic/src/tusb_config.h index 44be5a0d7..023faa7e2 100644 --- a/examples/device/audio_4_channel_mic/src/tusb_config.h +++ b/examples/device/audio_4_channel_mic/src/tusb_config.h @@ -39,11 +39,7 @@ extern "C" { #error CFG_TUSB_MCU must be defined #endif -#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX -#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) -#else #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE -#endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE diff --git a/examples/device/audio_test/src/tusb_config.h b/examples/device/audio_test/src/tusb_config.h index 683a1a567..9b8514265 100644 --- a/examples/device/audio_test/src/tusb_config.h +++ b/examples/device/audio_test/src/tusb_config.h @@ -39,11 +39,7 @@ extern "C" { #error CFG_TUSB_MCU must be defined #endif -#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX -#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) -#else #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE -#endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE diff --git a/examples/device/cdc_dual_ports/src/tusb_config.h b/examples/device/cdc_dual_ports/src/tusb_config.h index ff8535d1a..f93606092 100644 --- a/examples/device/cdc_dual_ports/src/tusb_config.h +++ b/examples/device/cdc_dual_ports/src/tusb_config.h @@ -45,14 +45,9 @@ #endif // RHPort max operational speed can defined by board.mk -// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed +// Default to max (auto) speed for MCU with internal HighSpeed PHY #ifndef BOARD_DEVICE_RHPORT_SPEED - #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ - CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56 || CFG_TUSB_MCU == OPT_MCU_SAMX7X) - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED - #else - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED - #endif + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk diff --git a/examples/device/cdc_msc/src/tusb_config.h b/examples/device/cdc_msc/src/tusb_config.h index e74e80541..6507cef19 100644 --- a/examples/device/cdc_msc/src/tusb_config.h +++ b/examples/device/cdc_msc/src/tusb_config.h @@ -45,15 +45,9 @@ #endif // RHPort max operational speed can defined by board.mk -// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed +// Default to max (auto) speed for MCU with internal HighSpeed PHY #ifndef BOARD_DEVICE_RHPORT_SPEED - #if TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX, OPT_MCU_MIMXRT10XX, OPT_MCU_NUC505) ||\ - TU_CHECK_MCU(OPT_MCU_CXD56, OPT_MCU_SAMX7X, OPT_MCU_BCM2711) ||\ - TU_CHECK_MCU(OPT_MCU_FT90X, OPT_MCU_FT93X) - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED - #else - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED - #endif + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk diff --git a/examples/device/dfu/src/tusb_config.h b/examples/device/dfu/src/tusb_config.h index 012d50019..d4779b2e1 100644 --- a/examples/device/dfu/src/tusb_config.h +++ b/examples/device/dfu/src/tusb_config.h @@ -27,14 +27,9 @@ #endif // RHPort max operational speed can defined by board.mk -// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed +// Default to max (auto) speed for MCU with internal HighSpeed PHY #ifndef BOARD_DEVICE_RHPORT_SPEED - #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ - CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56) - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED - #else - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED - #endif + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk diff --git a/examples/device/dfu_runtime/src/tusb_config.h b/examples/device/dfu_runtime/src/tusb_config.h index bdae1d2e9..e15ae7997 100644 --- a/examples/device/dfu_runtime/src/tusb_config.h +++ b/examples/device/dfu_runtime/src/tusb_config.h @@ -27,14 +27,9 @@ #endif // RHPort max operational speed can defined by board.mk -// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed +// Default to max (auto) speed for MCU with internal HighSpeed PHY #ifndef BOARD_DEVICE_RHPORT_SPEED - #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ - CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56) - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED - #else - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED - #endif + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk diff --git a/examples/device/dynamic_configuration/src/tusb_config.h b/examples/device/dynamic_configuration/src/tusb_config.h index 23073faf3..ddc295dcc 100644 --- a/examples/device/dynamic_configuration/src/tusb_config.h +++ b/examples/device/dynamic_configuration/src/tusb_config.h @@ -45,14 +45,9 @@ #endif // RHPort max operational speed can defined by board.mk -// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed +// Default to max (auto) speed for MCU with internal HighSpeed PHY #ifndef BOARD_DEVICE_RHPORT_SPEED - #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ - CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56) - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED - #else - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED - #endif + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk diff --git a/examples/device/hid_boot_interface/src/tusb_config.h b/examples/device/hid_boot_interface/src/tusb_config.h index 1381dd6b2..1c8fa40b2 100644 --- a/examples/device/hid_boot_interface/src/tusb_config.h +++ b/examples/device/hid_boot_interface/src/tusb_config.h @@ -45,15 +45,9 @@ #endif // RHPort max operational speed can defined by board.mk -// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed +// Default to max (auto) speed for MCU with internal HighSpeed PHY #ifndef BOARD_DEVICE_RHPORT_SPEED - #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ - CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56 || CFG_TUSB_MCU == OPT_MCU_SAMX7X || \ - CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X) - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED - #else - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED - #endif + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk diff --git a/examples/device/hid_composite/src/tusb_config.h b/examples/device/hid_composite/src/tusb_config.h index 449efbc7e..d0f2b513f 100644 --- a/examples/device/hid_composite/src/tusb_config.h +++ b/examples/device/hid_composite/src/tusb_config.h @@ -45,15 +45,9 @@ #endif // RHPort max operational speed can defined by board.mk -// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed +// Default to max (auto) speed for MCU with internal HighSpeed PHY #ifndef BOARD_DEVICE_RHPORT_SPEED - #if TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX, OPT_MCU_MIMXRT10XX, OPT_MCU_NUC505) ||\ - TU_CHECK_MCU(OPT_MCU_CXD56, OPT_MCU_SAMX7X, OPT_MCU_BCM2711) ||\ - TU_CHECK_MCU(OPT_MCU_FT90X, OPT_MCU_FT93X) - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED - #else - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED - #endif + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk diff --git a/examples/device/hid_composite_freertos/src/tusb_config.h b/examples/device/hid_composite_freertos/src/tusb_config.h index 062f32ac3..7522bd714 100644 --- a/examples/device/hid_composite_freertos/src/tusb_config.h +++ b/examples/device/hid_composite_freertos/src/tusb_config.h @@ -45,14 +45,9 @@ #endif // RHPort max operational speed can defined by board.mk -// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed +// Default to max (auto) speed for MCU with internal HighSpeed PHY #ifndef BOARD_DEVICE_RHPORT_SPEED - #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ - CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56) - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED - #else - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED - #endif + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk diff --git a/examples/device/hid_generic_inout/src/tusb_config.h b/examples/device/hid_generic_inout/src/tusb_config.h index 1b8b91c41..9db50269c 100644 --- a/examples/device/hid_generic_inout/src/tusb_config.h +++ b/examples/device/hid_generic_inout/src/tusb_config.h @@ -45,14 +45,9 @@ #endif // RHPort max operational speed can defined by board.mk -// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed +// Default to max (auto) speed for MCU with internal HighSpeed PHY #ifndef BOARD_DEVICE_RHPORT_SPEED - #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ - CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56) - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED - #else - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED - #endif + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk diff --git a/examples/device/hid_multiple_interface/src/tusb_config.h b/examples/device/hid_multiple_interface/src/tusb_config.h index c034b086e..32e8c2843 100644 --- a/examples/device/hid_multiple_interface/src/tusb_config.h +++ b/examples/device/hid_multiple_interface/src/tusb_config.h @@ -45,15 +45,9 @@ #endif // RHPort max operational speed can defined by board.mk -// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed +// Default to max (auto) speed for MCU with internal HighSpeed PHY #ifndef BOARD_DEVICE_RHPORT_SPEED - #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ - CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56 || \ - CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X) - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED - #else - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED - #endif + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk diff --git a/examples/device/midi_test/src/tusb_config.h b/examples/device/midi_test/src/tusb_config.h index a40d7605c..967c71403 100644 --- a/examples/device/midi_test/src/tusb_config.h +++ b/examples/device/midi_test/src/tusb_config.h @@ -45,15 +45,9 @@ #endif // RHPort max operational speed can defined by board.mk -// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed +// Default to max (auto) speed for MCU with internal HighSpeed PHY #ifndef BOARD_DEVICE_RHPORT_SPEED - #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ - CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56 || \ - CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X) - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED - #else - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED - #endif + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk diff --git a/examples/device/msc_dual_lun/src/tusb_config.h b/examples/device/msc_dual_lun/src/tusb_config.h index 44da21e54..f617f5a4c 100644 --- a/examples/device/msc_dual_lun/src/tusb_config.h +++ b/examples/device/msc_dual_lun/src/tusb_config.h @@ -45,14 +45,9 @@ #endif // RHPort max operational speed can defined by board.mk -// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed +// Default to max (auto) speed for MCU with internal HighSpeed PHY #ifndef BOARD_DEVICE_RHPORT_SPEED - #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ - CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56) - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED - #else - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED - #endif + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk diff --git a/examples/device/net_lwip_webserver/src/tusb_config.h b/examples/device/net_lwip_webserver/src/tusb_config.h index 114961cb7..b1b48598b 100644 --- a/examples/device/net_lwip_webserver/src/tusb_config.h +++ b/examples/device/net_lwip_webserver/src/tusb_config.h @@ -45,14 +45,9 @@ #endif // RHPort max operational speed can defined by board.mk -// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed +// Default to max (auto) speed for MCU with internal HighSpeed PHY #ifndef BOARD_DEVICE_RHPORT_SPEED - #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ - CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56) - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED - #else - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED - #endif + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk diff --git a/examples/device/uac2_headset/src/tusb_config.h b/examples/device/uac2_headset/src/tusb_config.h index e8d93f56a..3b2f7df48 100644 --- a/examples/device/uac2_headset/src/tusb_config.h +++ b/examples/device/uac2_headset/src/tusb_config.h @@ -42,10 +42,10 @@ extern "C" { #error CFG_TUSB_MCU must be defined #endif -#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX -#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) -#else -#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE +// RHPort max operational speed can defined by board.mk +// Default to max (auto) speed for MCU with internal HighSpeed PHY +#ifndef BOARD_DEVICE_RHPORT_SPEED + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED #endif #ifndef CFG_TUSB_OS diff --git a/examples/device/usbtmc/src/tusb_config.h b/examples/device/usbtmc/src/tusb_config.h index a192d0dbc..5b2215be5 100644 --- a/examples/device/usbtmc/src/tusb_config.h +++ b/examples/device/usbtmc/src/tusb_config.h @@ -27,14 +27,9 @@ #endif // RHPort max operational speed can defined by board.mk -// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed +// Default to max (auto) speed for MCU with internal HighSpeed PHY #ifndef BOARD_DEVICE_RHPORT_SPEED - #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ - CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56) - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED - #else - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED - #endif + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk diff --git a/examples/device/video_capture/src/tusb_config.h b/examples/device/video_capture/src/tusb_config.h index 4feb6a48a..3a079e66b 100644 --- a/examples/device/video_capture/src/tusb_config.h +++ b/examples/device/video_capture/src/tusb_config.h @@ -40,14 +40,9 @@ #endif // RHPort max operational speed can defined by board.mk -// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed +// Default to max (auto) speed for MCU with internal HighSpeed PHY #ifndef BOARD_DEVICE_RHPORT_SPEED - #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ - CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56) - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED - #else - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED - #endif + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk diff --git a/examples/device/webusb_serial/src/tusb_config.h b/examples/device/webusb_serial/src/tusb_config.h index 26b81b389..f5e4694e3 100644 --- a/examples/device/webusb_serial/src/tusb_config.h +++ b/examples/device/webusb_serial/src/tusb_config.h @@ -45,14 +45,9 @@ #endif // RHPort max operational speed can defined by board.mk -// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed +// Default to max (auto) speed for MCU with internal HighSpeed PHY #ifndef BOARD_DEVICE_RHPORT_SPEED - #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ - CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56) - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED - #else - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED - #endif + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk diff --git a/src/device/dcd_attr.h b/src/device/dcd_attr.h index e16a5ccca..e14a3f134 100644 --- a/src/device/dcd_attr.h +++ b/src/device/dcd_attr.h @@ -33,7 +33,8 @@ // - ENDPOINT_MAX: max (logical) number of endpoint // - ENDPOINT_EXCLUSIVE_NUMBER: endpoint number with different direction IN and OUT aren't allowed, // e.g EP1 OUT & EP1 IN cannot exist together -// - PORT_HIGHSPEED: mask to indicate which port support highspeed mode, bit0 for port0 and so on. +// - RHPORT_HIGHSPEED: mask to indicate which port support highspeed mode (without external PHY) +// bit0 for port0 and so on. //------------- NXP -------------// #if TU_CHECK_MCU(OPT_MCU_LPC11UXX, OPT_MCU_LPC13XX, OPT_MCU_LPC15XX) @@ -45,7 +46,8 @@ #elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX) // TODO USB0 has 6, USB1 has 4 #define DCD_ATTR_CONTROLLER_CHIPIDEA_HS - #define DCD_ATTR_ENDPOINT_MAX 6 + #define DCD_ATTR_ENDPOINT_MAX 6 + #define DCD_ATTR_RHPORT_HIGHSPEED 0x01 // Port0 HS, Port1 FS #elif TU_CHECK_MCU(OPT_MCU_LPC51UXX) #define DCD_ATTR_ENDPOINT_MAX 5 @@ -60,7 +62,8 @@ #elif TU_CHECK_MCU(OPT_MCU_MIMXRT10XX) #define DCD_ATTR_CONTROLLER_CHIPIDEA_HS - #define DCD_ATTR_ENDPOINT_MAX 8 + #define DCD_ATTR_ENDPOINT_MAX 8 + #define DCD_ATTR_RHPORT_HIGHSPEED 0x03 // Port0 HS, Port1 HS #elif TU_CHECK_MCU(OPT_MCU_MKL25ZXX, OPT_MCU_K32L2BXX) #define DCD_ATTR_ENDPOINT_MAX 16 @@ -83,7 +86,8 @@ #define DCD_ATTR_ENDPOINT_EXCLUSIVE_NUMBER #elif TU_CHECK_MCU(OPT_MCU_SAMX7X) - #define DCD_ATTR_ENDPOINT_MAX 10 + #define DCD_ATTR_ENDPOINT_MAX 10 + #define DCD_ATTR_RHPORT_HIGHSPEED 0x01 #define DCD_ATTR_ENDPOINT_EXCLUSIVE_NUMBER #elif TU_CHECK_MCU(OPT_MCU_PIC32MZ) @@ -145,7 +149,8 @@ //------------- Sony -------------// #elif TU_CHECK_MCU(OPT_MCU_CXD56) - #define DCD_ATTR_ENDPOINT_MAX 7 + #define DCD_ATTR_ENDPOINT_MAX 7 + #define DCD_ATTR_RHPORT_HIGHSPEED 0x01 #define DCD_ATTR_ENDPOINT_EXCLUSIVE_NUMBER //------------- TI -------------// @@ -167,7 +172,8 @@ #define DCD_ATTR_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_NUC505) - #define DCD_ATTR_ENDPOINT_MAX 12 + #define DCD_ATTR_ENDPOINT_MAX 12 + #define DCD_ATTR_RHPORT_HIGHSPEED 0x01 //------------- Espressif -------------// #elif TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) @@ -195,7 +201,8 @@ //------------- Broadcom -------------// #elif TU_CHECK_MCU(OPT_MCU_BCM2711, OPT_MCU_BCM2835, OPT_MCU_BCM2837) - #define DCD_ATTR_ENDPOINT_MAX 8 + #define DCD_ATTR_ENDPOINT_MAX 8 + #define DCD_ATTR_RHPORT_HIGHSPEED 0x01 //------------- Broadcom -------------// #elif TU_CHECK_MCU(OPT_MCU_XMC4000) @@ -203,10 +210,12 @@ //------------- BridgeTek -------------// #elif TU_CHECK_MCU(OPT_MCU_FT90X) - #define DCD_ATTR_ENDPOINT_MAX 8 + #define DCD_ATTR_ENDPOINT_MAX 8 + #define DCD_ATTR_RHPORT_HIGHSPEED 0x01 #elif TU_CHECK_MCU(OPT_MCU_FT93X) - #define DCD_ATTR_ENDPOINT_MAX 16 + #define DCD_ATTR_ENDPOINT_MAX 16 + #define DCD_ATTR_RHPORT_HIGHSPEED 0x01 //------------ Allwinner -------------// #elif TU_CHECK_MCU(OPT_MCU_F1C100S) @@ -218,8 +227,8 @@ #endif // Default to fullspeed if not defined -//#ifndef PORT_HIGHSPEED -// #define DCD_ATTR_PORT_HIGHSPEED 0x00 -//#endif +#ifndef DCD_ATTR_RHPORT_HIGHSPEED + #define DCD_ATTR_RHPORT_HIGHSPEED 0x00 +#endif #endif diff --git a/src/device/usbd.h b/src/device/usbd.h index ec34817fa..b2bf8ba9d 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -453,7 +453,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 0x04 : 0x01),\ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ TUD_OPT_HIGH_SPEED ? 0x04 : 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) @@ -502,7 +502,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 0x04 : 0x01),\ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ TUD_OPT_HIGH_SPEED ? 0x04 : 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) @@ -550,7 +550,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 0x04 : 0x01),\ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ TUD_OPT_HIGH_SPEED ? 0x04 : 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000),\ /* Standard AS Isochronous Feedback Endpoint Descriptor(4.10.2.1) */\ @@ -558,7 +558,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb // Calculate wMaxPacketSize of Endpoints #define TUD_AUDIO_EP_SIZE(_maxFrequency, _nBytesPerSample, _nChannels) \ - ((((_maxFrequency + ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 7999 : 999)) / ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 8000 : 1000)) + 1) * _nBytesPerSample * _nChannels) + ((((_maxFrequency + (TUD_OPT_HIGH_SPEED ? 7999 : 999)) / (TUD_OPT_HIGH_SPEED ? 8000 : 1000)) + 1) * _nBytesPerSample * _nChannels) //--------------------------------------------------------------------+ diff --git a/src/tusb_option.h b/src/tusb_option.h index 714c6ed9e..5d104e31c 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -172,20 +172,24 @@ #include "tusb_config.h" #endif +#include "device/dcd_attr.h" + //-------------------------------------------------------------------- // RootHub Mode Configuration // CFG_TUSB_RHPORTx_MODE contains operation mode and speed for that port //-------------------------------------------------------------------- -// Lower 4-bit is operational mode -#define OPT_MODE_NONE 0x00 ///< Disabled -#define OPT_MODE_DEVICE 0x01 ///< Device Mode -#define OPT_MODE_HOST 0x02 ///< Host Mode +// Low byte is operational mode +#define OPT_MODE_NONE 0x0000 ///< Disabled +#define OPT_MODE_DEVICE 0x0001 ///< Device Mode +#define OPT_MODE_HOST 0x0002 ///< Host Mode -// Higher 4-bit is max operational speed (corresponding to tusb_speed_t) -#define OPT_MODE_FULL_SPEED 0x00 ///< Max Full Speed -#define OPT_MODE_LOW_SPEED 0x10 ///< Max Low Speed -#define OPT_MODE_HIGH_SPEED 0x20 ///< Max High Speed +// High byte is max operational speed (corresponding to tusb_speed_t) +#define OPT_MODE_DEFAULT_SPEED 0x0000 ///< Default (max) speed supported by MCU +#define OPT_MODE_LOW_SPEED 0x0100 ///< Low Speed +#define OPT_MODE_FULL_SPEED 0x0200 ///< Full Speed +#define OPT_MODE_HIGH_SPEED 0x0400 ///< High Speed +#define OPT_MODE_SPEED_MASK 0xff00 #ifndef CFG_TUSB_RHPORT0_MODE #define CFG_TUSB_RHPORT0_MODE OPT_MODE_NONE @@ -200,20 +204,27 @@ #error "TinyUSB currently does not support same modes on more than 1 roothub port" #endif -// Which roothub port is configured as host -#define TUH_OPT_RHPORT ( ((CFG_TUSB_RHPORT0_MODE) & OPT_MODE_HOST) ? 0 : (((CFG_TUSB_RHPORT1_MODE) & OPT_MODE_HOST) ? 1 : -1) ) -#define CFG_TUH_ENABLED ( TUH_OPT_RHPORT >= 0 ) +//------------- Roothub as Device -------------// -// Which roothub port is configured as device -#define TUD_OPT_RHPORT ( ((CFG_TUSB_RHPORT0_MODE) & OPT_MODE_DEVICE) ? 0 : (((CFG_TUSB_RHPORT1_MODE) & OPT_MODE_DEVICE) ? 1 : -1) ) - -#if TUD_OPT_RHPORT == 0 -#define TUD_OPT_HIGH_SPEED ( (CFG_TUSB_RHPORT0_MODE) & OPT_MODE_HIGH_SPEED ) +#if (CFG_TUSB_RHPORT0_MODE) & OPT_MODE_DEVICE + #define TUD_RHPORT_MODE (CFG_TUSB_RHPORT0_MODE) + #define TUD_OPT_RHPORT 0 +#elif (CFG_TUSB_RHPORT1_MODE) & OPT_MODE_DEVICE + #define TUD_RHPORT_MODE (CFG_TUSB_RHPORT1_MODE) + #define TUD_OPT_RHPORT 1 #else -#define TUD_OPT_HIGH_SPEED ( (CFG_TUSB_RHPORT1_MODE) & OPT_MODE_HIGH_SPEED ) + #define TUD_RHPORT_MODE OPT_MODE_NONE + #define TUD_OPT_RHPORT -1 #endif -#define CFG_TUD_ENABLED ( TUD_OPT_RHPORT >= 0 ) +#define CFG_TUD_ENABLED ( TUD_RHPORT_MODE & OPT_MODE_DEVICE ) +#define TUD_OPT_HIGH_SPEED ( (TUD_RHPORT_MODE & OPT_MODE_SPEED_MASK) ? (TUD_RHPORT_MODE & OPT_MODE_HIGH_SPEED) : (DCD_ATTR_RHPORT_HIGHSPEED & (1 << TUD_OPT_RHPORT)) ) + +// CFG_TUD_SPEED OPT_MODE_HIGH_SPEED + +//------------- Roothub as Host -------------// +#define TUH_OPT_RHPORT ( ((CFG_TUSB_RHPORT0_MODE) & OPT_MODE_HOST) ? 0 : (((CFG_TUSB_RHPORT1_MODE) & OPT_MODE_HOST) ? 1 : -1) ) +#define CFG_TUH_ENABLED ( TUH_OPT_RHPORT >= 0 ) // For backward compatible #define TUSB_OPT_DEVICE_ENABLED CFG_TUD_ENABLED From 99ad3ae2ca9d4db79b2ac92a6991ebdc3dfb94a3 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 25 Feb 2022 13:45:51 +0700 Subject: [PATCH 165/504] rename and move dcd_attr.h to tusb_mcu_attr.h --- src/{device/dcd_attr.h => common/tusb_mcu_attr.h} | 4 ++-- src/device/dcd.h | 1 - src/portable/chipidea/ci_hs/dcd_ci_hs.c | 1 - src/portable/synopsys/dwc2/dcd_dwc2.c | 1 - src/tusb_option.h | 2 +- 5 files changed, 3 insertions(+), 6 deletions(-) rename src/{device/dcd_attr.h => common/tusb_mcu_attr.h} (99%) diff --git a/src/device/dcd_attr.h b/src/common/tusb_mcu_attr.h similarity index 99% rename from src/device/dcd_attr.h rename to src/common/tusb_mcu_attr.h index e14a3f134..c10869d21 100644 --- a/src/device/dcd_attr.h +++ b/src/common/tusb_mcu_attr.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef TUSB_DCD_ATTR_H_ -#define TUSB_DCD_ATTR_H_ +#ifndef TUSB_MCU_ATTR_H_ +#define TUSB_MCU_ATTR_H_ #include "tusb_option.h" diff --git a/src/device/dcd.h b/src/device/dcd.h index fbcef40d4..4e725c95a 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -30,7 +30,6 @@ #include "common/tusb_common.h" #include "osal/osal.h" #include "common/tusb_fifo.h" -#include "dcd_attr.h" #ifdef __cplusplus extern "C" { diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c index ffb2ebd16..6361fe629 100644 --- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c @@ -25,7 +25,6 @@ */ #include "tusb_option.h" -#include "device/dcd_attr.h" #if CFG_TUD_ENABLED && defined(DCD_ATTR_CONTROLLER_CHIPIDEA_HS) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 86dc760c8..ecbc36fb9 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -28,7 +28,6 @@ */ #include "tusb_option.h" -#include "device/dcd_attr.h" #if CFG_TUD_ENABLED && \ ( defined(DCD_ATTR_DWC2_STM32) || \ diff --git a/src/tusb_option.h b/src/tusb_option.h index 5d104e31c..6a3638461 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -172,7 +172,7 @@ #include "tusb_config.h" #endif -#include "device/dcd_attr.h" +#include "common/tusb_mcu_attr.h" //-------------------------------------------------------------------- // RootHub Mode Configuration From 309540473bc2985d83212b9da0527c7500ba2a66 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 25 Feb 2022 22:26:35 +0700 Subject: [PATCH 166/504] minor house keeping --- src/class/msc/msc_host.c | 2 +- src/common/tusb_error.h | 2 ++ src/device/usbd.c | 4 +--- src/host/usbh.c | 1 + src/tusb.c | 2 ++ src/tusb_option.h | 15 +++++++++++++-- 6 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index a49a10522..e4239e375 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if CFG_TUH_ENABLED & CFG_TUH_MSC +#if CFG_TUH_ENABLED && CFG_TUH_MSC #include "host/usbh.h" #include "host/usbh_classdriver.h" diff --git a/src/common/tusb_error.h b/src/common/tusb_error.h index d7ad8c318..42541acd6 100644 --- a/src/common/tusb_error.h +++ b/src/common/tusb_error.h @@ -64,6 +64,8 @@ typedef enum #if CFG_TUSB_DEBUG /// Enum to String for debugging purposes. Only available if \ref CFG_TUSB_DEBUG > 0 extern char const* const tusb_strerr[TUSB_ERROR_COUNT]; +extern char const* const tusb_speed_str[]; + #endif #ifdef __cplusplus diff --git a/src/device/usbd.c b/src/device/usbd.c index e6861ee0a..c20bab76b 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -332,8 +332,6 @@ static char const* const _tusb_std_request_str[] = "Synch Frame" }; -static char const* const _tusb_speed_str[] = { "Full", "Low", "High" }; - // for usbd_control to print the name of control complete driver void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback) { @@ -509,7 +507,7 @@ void tud_task (void) switch ( event.event_id ) { case DCD_EVENT_BUS_RESET: - TU_LOG2(": %s Speed\r\n", _tusb_speed_str[event.bus_reset.speed]); + TU_LOG2(": %s Speed\r\n", tusb_speed_str[event.bus_reset.speed]); usbd_reset(event.rhport); _usbd_dev.speed = event.bus_reset.speed; break; diff --git a/src/host/usbh.c b/src/host/usbh.c index e29ce1e54..ce0ccc3cb 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -709,6 +709,7 @@ static bool enum_new_device(hcd_event_t* event) if ( !hcd_port_connect_status(_dev0.rhport) ) return true; _dev0.speed = hcd_port_speed_get(_dev0.rhport ); + TU_LOG2("%s Speed\r\n", tusb_speed_str[_dev0.speed]); enum_request_addr0_device_desc(); } diff --git a/src/tusb.c b/src/tusb.c index 03fe43104..a30221059 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -163,6 +163,8 @@ uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf, char const* const tusb_strerr[TUSB_ERROR_COUNT] = { ERROR_TABLE(ERROR_STRING) }; +char const* const tusb_speed_str[] = { "Full", "Low", "High" }; + static void dump_str_line(uint8_t const* buf, uint16_t count) { tu_printf(" |"); diff --git a/src/tusb_option.h b/src/tusb_option.h index 6a3638461..5bf336438 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -223,8 +223,19 @@ // CFG_TUD_SPEED OPT_MODE_HIGH_SPEED //------------- Roothub as Host -------------// -#define TUH_OPT_RHPORT ( ((CFG_TUSB_RHPORT0_MODE) & OPT_MODE_HOST) ? 0 : (((CFG_TUSB_RHPORT1_MODE) & OPT_MODE_HOST) ? 1 : -1) ) -#define CFG_TUH_ENABLED ( TUH_OPT_RHPORT >= 0 ) + +#if (CFG_TUSB_RHPORT0_MODE) & OPT_MODE_HOST + #define TUH_RHPORT_MODE (CFG_TUSB_RHPORT0_MODE) + #define TUH_OPT_RHPORT 0 +#elif (CFG_TUSB_RHPORT1_MODE) & OPT_MODE_HOST + #define TUH_RHPORT_MODE (CFG_TUSB_RHPORT1_MODE) + #define TUH_OPT_RHPORT 1 +#else + #define TUH_RHPORT_MODE OPT_MODE_NONE + #define TUH_OPT_RHPORT -1 +#endif + +#define CFG_TUH_ENABLED ( TUH_RHPORT_MODE & OPT_MODE_HOST ) // For backward compatible #define TUSB_OPT_DEVICE_ENABLED CFG_TUD_ENABLED From 89115253da3ef55d59367977b8103a5e321e56aa Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 25 Feb 2022 22:45:05 +0700 Subject: [PATCH 167/504] internal symbol rename --- src/common/tusb_mcu_attr.h | 28 ++++++---- src/host/hcd.h | 1 - src/host/hcd_attr.h | 105 ------------------------------------- src/portable/ehci/ehci.c | 6 +-- src/portable/ohci/ohci.c | 2 +- 5 files changed, 23 insertions(+), 119 deletions(-) delete mode 100644 src/host/hcd_attr.h diff --git a/src/common/tusb_mcu_attr.h b/src/common/tusb_mcu_attr.h index c10869d21..e3393ad04 100644 --- a/src/common/tusb_mcu_attr.h +++ b/src/common/tusb_mcu_attr.h @@ -27,14 +27,13 @@ #ifndef TUSB_MCU_ATTR_H_ #define TUSB_MCU_ATTR_H_ -#include "tusb_option.h" - -// Attribute includes -// - ENDPOINT_MAX: max (logical) number of endpoint -// - ENDPOINT_EXCLUSIVE_NUMBER: endpoint number with different direction IN and OUT aren't allowed, -// e.g EP1 OUT & EP1 IN cannot exist together -// - RHPORT_HIGHSPEED: mask to indicate which port support highspeed mode (without external PHY) -// bit0 for port0 and so on. +/* Attribute includes + * - ENDPOINT_MAX: max (logical) number of endpoint + * - ENDPOINT_EXCLUSIVE_NUMBER: endpoint number with different direction IN and OUT aren't allowed, + * e.g EP1 OUT & EP1 IN cannot exist together + * - RHPORT_HIGHSPEED: mask to indicate which port support highspeed mode (without external PHY) + * bit0 for port0 and so on. + */ //------------- NXP -------------// #if TU_CHECK_MCU(OPT_MCU_LPC11UXX, OPT_MCU_LPC13XX, OPT_MCU_LPC15XX) @@ -42,6 +41,7 @@ #elif TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX) #define DCD_ATTR_ENDPOINT_MAX 16 + #define HCD_ATTR_OHCI #elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX) // TODO USB0 has 6, USB1 has 4 @@ -49,6 +49,8 @@ #define DCD_ATTR_ENDPOINT_MAX 6 #define DCD_ATTR_RHPORT_HIGHSPEED 0x01 // Port0 HS, Port1 FS + #define HCD_ATTR_EHCI + #elif TU_CHECK_MCU(OPT_MCU_LPC51UXX) #define DCD_ATTR_ENDPOINT_MAX 5 @@ -65,6 +67,8 @@ #define DCD_ATTR_ENDPOINT_MAX 8 #define DCD_ATTR_RHPORT_HIGHSPEED 0x03 // Port0 HS, Port1 HS + #define HCD_ATTR_EHCI + #elif TU_CHECK_MCU(OPT_MCU_MKL25ZXX, OPT_MCU_K32L2BXX) #define DCD_ATTR_ENDPOINT_MAX 16 @@ -221,7 +225,13 @@ #elif TU_CHECK_MCU(OPT_MCU_F1C100S) #define DCD_ATTR_ENDPOINT_MAX 4 -#else +#endif + +//--------------------------------------------------------------------+ +// Default Values +//--------------------------------------------------------------------+ + +#ifndef DCD_ATTR_ENDPOINT_MAX #warning "DCD_ATTR_ENDPOINT_MAX is not defined for this MCU, default to 8" #define DCD_ATTR_ENDPOINT_MAX 8 #endif diff --git a/src/host/hcd.h b/src/host/hcd.h index 054fd9647..80500f048 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -30,7 +30,6 @@ #include "common/tusb_common.h" #include "osal/osal.h" #include "common/tusb_fifo.h" -#include "hcd_attr.h" #ifdef __cplusplus extern "C" { diff --git a/src/host/hcd_attr.h b/src/host/hcd_attr.h deleted file mode 100644 index 06011c63c..000000000 --- a/src/host/hcd_attr.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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. - */ - -#ifndef TUSB_HCD_ATTR_H_ -#define TUSB_HCD_ATTR_H_ - -#include "tusb_option.h" - -// Attribute includes -// - ENDPOINT_MAX: max (logical) number of endpoint -// - PORT_HIGHSPEED: mask to indicate which port support highspeed mode, bit0 for port0 and so on. - -//------------- NXP -------------// -#if TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX) - #define HCD_ATTR_OHCI - -#elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX) - #define HCD_ATTR_EHCI_TRANSDIMENSION - -#elif TU_CHECK_MCU(OPT_MCU_LPC54XXX) - // #define HCD_ATTR_EHCI_NXP_PTD - -#elif TU_CHECK_MCU(OPT_MCU_LPC55XX) - // #define HCD_ATTR_EHCI_NXP_PTD - -#elif TU_CHECK_MCU(OPT_MCU_MIMXRT10XX) - #define HCD_ATTR_EHCI_TRANSDIMENSION - -#elif TU_CHECK_MCU(OPT_MCU_MKL25ZXX) - -//------------- Microchip -------------// -#elif TU_CHECK_MCU(OPT_MCU_SAMD21, OPT_MCU_SAMD51, OPT_MCU_SAME5X) || \ - TU_CHECK_MCU(OPT_MCU_SAMD11, OPT_MCU_SAML21, OPT_MCU_SAML22) - -#elif TU_CHECK_MCU(OPT_MCU_SAMG) - -#elif TU_CHECK_MCU(OPT_MCU_SAMX7X) - -//------------- ST -------------// -#elif TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32F1, OPT_MCU_STM32F3) || \ - TU_CHECK_MCU(OPT_MCU_STM32L0, OPT_MCU_STM32L1, OPT_MCU_STM32L4) - -#elif TU_CHECK_MCU(OPT_MCU_STM32F2, OPT_MCU_STM32F3, OPT_MCU_STM32F4) - -#elif TU_CHECK_MCU(OPT_MCU_STM32F7) - -#elif TU_CHECK_MCU(OPT_MCU_STM32H7) - -//------------- Sony -------------// -#elif TU_CHECK_MCU(OPT_MCU_CXD56) - -//------------- Nuvoton -------------// -#elif TU_CHECK_MCU(OPT_MCU_NUC505) - -//------------- Espressif -------------// -#elif TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) - -//------------- Raspberry Pi -------------// -#elif TU_CHECK_MCU(OPT_MCU_RP2040) - -//------------- Silabs -------------// -#elif TU_CHECK_MCU(OPT_MCU_EFM32GG) - -//------------- Renesas -------------// -#elif TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N) - -//#elif TU_CHECK_MCU(OPT_MCU_MM32F327X) -// #define DCD_ATTR_ENDPOINT_MAX not known yet - -//------------- GigaDevice -------------// -#elif TU_CHECK_MCU(OPT_MCU_GD32VF103) - -#else -// #warning "DCD_ATTR_ENDPOINT_MAX is not defined for this MCU, default to 8" -#endif - -// Default to fullspeed if not defined -//#ifndef PORT_HIGHSPEED -// #define DCD_ATTR_PORT_HIGHSPEED 0x00 -//#endif - -#endif diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index 6b86cb2b2..419601245 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -24,9 +24,9 @@ * This file is part of the TinyUSB stack. */ -#include "host/hcd_attr.h" +#include "tusb_option.h" -#if CFG_TUH_ENABLED && defined(HCD_ATTR_EHCI_TRANSDIMENSION) +#if CFG_TUH_ENABLED && defined(HCD_ATTR_EHCI) //--------------------------------------------------------------------+ // INCLUDE @@ -45,7 +45,7 @@ #define EHCI_DBG 2 // Framelist size as small as possible to save SRAM -#ifdef HCD_ATTR_EHCI_TRANSDIMENSION +#ifdef HCD_ATTR_EHCI // NXP Transdimension: 8 elements #define FRAMELIST_SIZE_BIT_VALUE 7u #define FRAMELIST_SIZE_USBCMD_VALUE (((FRAMELIST_SIZE_BIT_VALUE & 3) << EHCI_USBCMD_POS_FRAMELIST_SIZE) | \ diff --git a/src/portable/ohci/ohci.c b/src/portable/ohci/ohci.c index 8860f27a2..c9e1061f9 100644 --- a/src/portable/ohci/ohci.c +++ b/src/portable/ohci/ohci.c @@ -24,7 +24,7 @@ * This file is part of the TinyUSB stack. */ -#include "host/hcd_attr.h" +#include "tusb_option.h" #if CFG_TUH_ENABLED && defined(HCD_ATTR_OHCI) From 0997589c45a7c4dd96da0d9bce37f771520e34c6 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 25 Feb 2022 23:04:39 +0700 Subject: [PATCH 168/504] more symbol rename --- src/common/tusb_mcu_attr.h | 6 +++--- src/portable/chipidea/ci_hs/dcd_ci_hs.c | 2 +- src/portable/ehci/ehci.c | 2 +- src/tusb_option.h | 2 -- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/common/tusb_mcu_attr.h b/src/common/tusb_mcu_attr.h index e3393ad04..0341dd1bf 100644 --- a/src/common/tusb_mcu_attr.h +++ b/src/common/tusb_mcu_attr.h @@ -27,7 +27,7 @@ #ifndef TUSB_MCU_ATTR_H_ #define TUSB_MCU_ATTR_H_ -/* Attribute includes +/* USB Controller Attributes for Device, Host or MCU (both) * - ENDPOINT_MAX: max (logical) number of endpoint * - ENDPOINT_EXCLUSIVE_NUMBER: endpoint number with different direction IN and OUT aren't allowed, * e.g EP1 OUT & EP1 IN cannot exist together @@ -45,7 +45,7 @@ #elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX) // TODO USB0 has 6, USB1 has 4 - #define DCD_ATTR_CONTROLLER_CHIPIDEA_HS + #define MCU_ATTR_CONTROLLER_CHIPIDEA_HS #define DCD_ATTR_ENDPOINT_MAX 6 #define DCD_ATTR_RHPORT_HIGHSPEED 0x01 // Port0 HS, Port1 FS @@ -63,7 +63,7 @@ #define DCD_ATTR_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_MIMXRT10XX) - #define DCD_ATTR_CONTROLLER_CHIPIDEA_HS + #define MCU_ATTR_CONTROLLER_CHIPIDEA_HS #define DCD_ATTR_ENDPOINT_MAX 8 #define DCD_ATTR_RHPORT_HIGHSPEED 0x03 // Port0 HS, Port1 HS diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c index 6361fe629..21087681c 100644 --- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if CFG_TUD_ENABLED && defined(DCD_ATTR_CONTROLLER_CHIPIDEA_HS) +#if CFG_TUD_ENABLED && defined(MCU_ATTR_CONTROLLER_CHIPIDEA_HS) //--------------------------------------------------------------------+ // INCLUDE diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index 419601245..5b42ece48 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -45,7 +45,7 @@ #define EHCI_DBG 2 // Framelist size as small as possible to save SRAM -#ifdef HCD_ATTR_EHCI +#ifdef MCU_ATTR_CONTROLLER_CHIPIDEA_HS // NXP Transdimension: 8 elements #define FRAMELIST_SIZE_BIT_VALUE 7u #define FRAMELIST_SIZE_USBCMD_VALUE (((FRAMELIST_SIZE_BIT_VALUE & 3) << EHCI_USBCMD_POS_FRAMELIST_SIZE) | \ diff --git a/src/tusb_option.h b/src/tusb_option.h index 5bf336438..5cc362f1a 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -220,8 +220,6 @@ #define CFG_TUD_ENABLED ( TUD_RHPORT_MODE & OPT_MODE_DEVICE ) #define TUD_OPT_HIGH_SPEED ( (TUD_RHPORT_MODE & OPT_MODE_SPEED_MASK) ? (TUD_RHPORT_MODE & OPT_MODE_HIGH_SPEED) : (DCD_ATTR_RHPORT_HIGHSPEED & (1 << TUD_OPT_RHPORT)) ) -// CFG_TUD_SPEED OPT_MODE_HIGH_SPEED - //------------- Roothub as Host -------------// #if (CFG_TUSB_RHPORT0_MODE) & OPT_MODE_HOST From 1482a415240171b7ff2bd2ee0f123635dd15f9a4 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 25 Feb 2022 23:16:40 +0700 Subject: [PATCH 169/504] fix uac2_headset build --- examples/device/uac2_headset/src/tusb_config.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/examples/device/uac2_headset/src/tusb_config.h b/examples/device/uac2_headset/src/tusb_config.h index 3b2f7df48..2a1189a79 100644 --- a/examples/device/uac2_headset/src/tusb_config.h +++ b/examples/device/uac2_headset/src/tusb_config.h @@ -42,11 +42,7 @@ extern "C" { #error CFG_TUSB_MCU must be defined #endif -// RHPort max operational speed can defined by board.mk -// Default to max (auto) speed for MCU with internal HighSpeed PHY -#ifndef BOARD_DEVICE_RHPORT_SPEED - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED -#endif +#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE From 8eeda60bd0e81fb3fe7211014ab672b23dc847a3 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Fri, 25 Feb 2022 05:54:41 +0200 Subject: [PATCH 170/504] Set the standard inquiry response additional length field. * The standard inquiry response additional length field needs to be set to the length in bytes of the remaining standard inquiry data (i.e. N - 5), otherwise the kernel driver issues a warning about short inquiry response.. --- src/class/msc/msc_device.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index e09a2b11a..0c18b0ced 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -753,6 +753,7 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ .is_removable = 1, .version = 2, .response_data_format = 2, + .additional_length = sizeof(scsi_inquiry_resp_t) - 5, }; // vendor_id, product_id, product_rev is space padded string From 39fdbc8ffca3cb0a610ce4140e1d527beb47ad3d Mon Sep 17 00:00:00 2001 From: Tom Peterson Date: Fri, 25 Feb 2022 12:39:09 -0600 Subject: [PATCH 171/504] Updated the clearing of the status register bits to use a straight '=', rather than an '|='. Use of the latter caused an extra, unwanted read of the status register before the write-to-clear operation, which, in some cases, allowed new status bits to assert (relative to the initial read of the status register two statements earlier), and then be cleared blindly and unconditionally during the write-back. This had the potential (and, in my case, observed) effect of dropping the handling of an enabled interrupt. Ultimately, the system would lock up in a busy state, with no hope of clearing the condition. See Issue #1339 for more information. --- src/portable/ehci/ehci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index e92f8a951..9b998cda6 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -657,7 +657,7 @@ void hcd_int_handler(uint8_t rhport) uint32_t int_status = regs->status; int_status &= regs->inten; - regs->status |= int_status; // Acknowledge handled interrupt + regs->status = int_status; // Acknowledge handled interrupt if (int_status == 0) return; From c06ecbef0ce7cb286dce85d2329a02c513e2c61b Mon Sep 17 00:00:00 2001 From: Tom Peterson Date: Fri, 25 Feb 2022 16:49:55 -0600 Subject: [PATCH 172/504] The IAR compilier does not resolve references to fields in the anonymous structs defined within the usbh_dev0_t and usbh_device_t structs as they are defined. The problem seems to relate to the placement of the 'volatile' keyword at the struct level. I fixed the problem by removing the 'volatile' from the struct level, and instead placing it on each of the field declarations within the structs. --- src/host/usbh.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index b8439addc..e925a01fe 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -62,12 +62,12 @@ typedef struct uint8_t hub_port; uint8_t speed; - volatile struct TU_ATTR_PACKED + struct TU_ATTR_PACKED { - uint8_t connected : 1; - uint8_t addressed : 1; - uint8_t configured : 1; - uint8_t suspended : 1; + volatile uint8_t connected : 1; + volatile uint8_t addressed : 1; + volatile uint8_t configured : 1; + volatile uint8_t suspended : 1; }; } usbh_dev0_t; @@ -78,12 +78,12 @@ typedef struct { uint8_t hub_port; uint8_t speed; - volatile struct TU_ATTR_PACKED + struct TU_ATTR_PACKED { - uint8_t connected : 1; - uint8_t addressed : 1; - uint8_t configured : 1; - uint8_t suspended : 1; + volatile uint8_t connected : 1; + volatile uint8_t addressed : 1; + volatile uint8_t configured : 1; + volatile uint8_t suspended : 1; }; //------------- device descriptor -------------// From bc63f59af2e75e4fc93715ac88a2a8360f09d69a Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 26 Feb 2022 15:18:51 +0700 Subject: [PATCH 173/504] mcu specific rename --- src/common/{tusb_mcu_attr.h => tusb_mcu.h} | 34 ++++++++++++++++--- src/portable/chipidea/ci_hs/dcd_ci_hs.c | 2 +- src/portable/ehci/ehci.c | 2 +- src/portable/synopsys/dwc2/dcd_dwc2.c | 2 +- src/tusb_option.h | 39 ++++++++-------------- 5 files changed, 46 insertions(+), 33 deletions(-) rename src/common/{tusb_mcu_attr.h => tusb_mcu.h} (91%) diff --git a/src/common/tusb_mcu_attr.h b/src/common/tusb_mcu.h similarity index 91% rename from src/common/tusb_mcu_attr.h rename to src/common/tusb_mcu.h index 0341dd1bf..1f1aeb462 100644 --- a/src/common/tusb_mcu_attr.h +++ b/src/common/tusb_mcu.h @@ -24,8 +24,22 @@ * This file is part of the TinyUSB stack. */ -#ifndef TUSB_MCU_ATTR_H_ -#define TUSB_MCU_ATTR_H_ +#ifndef TUSB_MCU_H_ +#define TUSB_MCU_H_ + +//--------------------------------------------------------------------+ +// Port Specific +// TUP stand for TinyUSB Port (can be renamed) +//--------------------------------------------------------------------+ + +//------------- Unaligned Memory Access -------------// + +// ARMv7+ (M3-M7, M23-M33) can access unaligned memory +#if (defined(__ARM_ARCH) && (__ARM_ARCH >= 7)) + #define TUP_ARCH_STRICT_ALIGN 0 +#else + #define TUP_ARCH_STRICT_ALIGN 1 +#endif /* USB Controller Attributes for Device, Host or MCU (both) * - ENDPOINT_MAX: max (logical) number of endpoint @@ -45,7 +59,7 @@ #elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX) // TODO USB0 has 6, USB1 has 4 - #define MCU_ATTR_CONTROLLER_CHIPIDEA_HS + #define TUP_USBIP_CHIPIDEA_HS #define DCD_ATTR_ENDPOINT_MAX 6 #define DCD_ATTR_RHPORT_HIGHSPEED 0x01 // Port0 HS, Port1 FS @@ -63,7 +77,7 @@ #define DCD_ATTR_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_MIMXRT10XX) - #define MCU_ATTR_CONTROLLER_CHIPIDEA_HS + #define TUP_USBIP_CHIPIDEA_HS #define DCD_ATTR_ENDPOINT_MAX 8 #define DCD_ATTR_RHPORT_HIGHSPEED 0x03 // Port0 HS, Port1 HS @@ -106,6 +120,8 @@ #if defined (STM32F105x8) || defined (STM32F105xB) || defined (STM32F105xC) || \ defined (STM32F107xB) || defined (STM32F107xC) #define DCD_ATTR_ENDPOINT_MAX 4 + + #define TUP_USBIP_DWC2 #define DCD_ATTR_DWC2_STM32 #else #define DCD_ATTR_ENDPOINT_MAX 8 @@ -114,6 +130,8 @@ #elif TU_CHECK_MCU(OPT_MCU_STM32F2) // FS has 4 ep, HS has 5 ep #define DCD_ATTR_ENDPOINT_MAX 6 + + #define TUP_USBIP_DWC2 #define DCD_ATTR_DWC2_STM32 #elif TU_CHECK_MCU(OPT_MCU_STM32F3) @@ -122,15 +140,21 @@ #elif TU_CHECK_MCU(OPT_MCU_STM32F4) // For most mcu, FS has 4, HS has 6. TODO 446/469/479 HS has 9 #define DCD_ATTR_ENDPOINT_MAX 6 + + #define TUP_USBIP_DWC2 #define DCD_ATTR_DWC2_STM32 #elif TU_CHECK_MCU(OPT_MCU_STM32F7) // FS has 6, HS has 9 #define DCD_ATTR_ENDPOINT_MAX 9 + + #define TUP_USBIP_DWC2 #define DCD_ATTR_DWC2_STM32 #elif TU_CHECK_MCU(OPT_MCU_STM32H7) #define DCD_ATTR_ENDPOINT_MAX 9 + + #define TUP_USBIP_DWC2 #define DCD_ATTR_DWC2_STM32 #elif TU_CHECK_MCU(OPT_MCU_STM32G4) @@ -146,6 +170,8 @@ defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || \ defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx) #define DCD_ATTR_ENDPOINT_MAX 6 + + #define TUP_USBIP_DWC2 #define DCD_ATTR_DWC2_STM32 #else #define DCD_ATTR_ENDPOINT_MAX 8 diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c index 21087681c..726c7a517 100644 --- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if CFG_TUD_ENABLED && defined(MCU_ATTR_CONTROLLER_CHIPIDEA_HS) +#if CFG_TUD_ENABLED && defined(TUP_USBIP_CHIPIDEA_HS) //--------------------------------------------------------------------+ // INCLUDE diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index 5b42ece48..ac873455b 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -45,7 +45,7 @@ #define EHCI_DBG 2 // Framelist size as small as possible to save SRAM -#ifdef MCU_ATTR_CONTROLLER_CHIPIDEA_HS +#ifdef TUP_USBIP_CHIPIDEA_HS // NXP Transdimension: 8 elements #define FRAMELIST_SIZE_BIT_VALUE 7u #define FRAMELIST_SIZE_USBCMD_VALUE (((FRAMELIST_SIZE_BIT_VALUE & 3) << EHCI_USBCMD_POS_FRAMELIST_SIZE) | \ diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index ecbc36fb9..377f0f44e 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -30,7 +30,7 @@ #include "tusb_option.h" #if CFG_TUD_ENABLED && \ - ( defined(DCD_ATTR_DWC2_STM32) || \ + ( defined(TUP_USBIP_DWC2) || \ TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3, OPT_MCU_GD32VF103) || \ TU_CHECK_MCU(OPT_MCU_EFM32GG, OPT_MCU_BCM2711, OPT_MCU_BCM2835) || \ TU_CHECK_MCU(OPT_MCU_BCM2837, OPT_MCU_XMC4000) ) diff --git a/src/tusb_option.h b/src/tusb_option.h index 5cc362f1a..3c2207c26 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -172,7 +172,7 @@ #include "tusb_config.h" #endif -#include "common/tusb_mcu_attr.h" +#include "common/tusb_mcu.h" //-------------------------------------------------------------------- // RootHub Mode Configuration @@ -239,6 +239,18 @@ #define TUSB_OPT_DEVICE_ENABLED CFG_TUD_ENABLED #define TUSB_OPT_HOST_ENABLED CFG_TUH_ENABLED +// TODO move later +// TUP_MCU_STRICT_ALIGN will overwrite TUP_ARCH_STRICT_ALIGN. +// In case TUP_MCU_STRICT_ALIGN = 1 and TUP_ARCH_STRICT_ALIGN =0, we will not reply on compiler +// to generate unaligned access code. +// LPC_IP3511 Highspeed cannot access unaligned memory on USB_RAM +#if TUD_OPT_HIGH_SPEED && (CFG_TUSB_MCU == OPT_MCU_LPC54XXX || CFG_TUSB_MCU == OPT_MCU_LPC55XX) + #define TUP_MCU_STRICT_ALIGN 1 +#else + #define TUP_MCU_STRICT_ALIGN 0 +#endif + + //--------------------------------------------------------------------+ // COMMON OPTIONS //--------------------------------------------------------------------+ @@ -371,31 +383,6 @@ #define CFG_TUH_VENDOR 0 #endif -//--------------------------------------------------------------------+ -// Port Specific -// TUP stand for TinyUSB Port (can be renamed) -//--------------------------------------------------------------------+ - -//------------- Unaligned Memory -------------// - -// ARMv7+ (M3-M7, M23-M33) can access unaligned memory -#if (defined(__ARM_ARCH) && (__ARM_ARCH >= 7)) - #define TUP_ARCH_STRICT_ALIGN 0 -#else - #define TUP_ARCH_STRICT_ALIGN 1 -#endif - -// TUP_MCU_STRICT_ALIGN will overwrite TUP_ARCH_STRICT_ALIGN. -// In case TUP_MCU_STRICT_ALIGN = 1 and TUP_ARCH_STRICT_ALIGN =0, we will not reply on compiler -// to generate unaligned access code. -// LPC_IP3511 Highspeed cannot access unaligned memory on USB_RAM -#if TUD_OPT_HIGH_SPEED && (CFG_TUSB_MCU == OPT_MCU_LPC54XXX || CFG_TUSB_MCU == OPT_MCU_LPC55XX) - #define TUP_MCU_STRICT_ALIGN 1 -#else - #define TUP_MCU_STRICT_ALIGN 0 -#endif - - //------------------------------------------------------------------ // Configuration Validation //------------------------------------------------------------------ From 11c89d43abec5a37856e3f026b23ab26c33a656a Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 26 Feb 2022 17:03:54 +0700 Subject: [PATCH 174/504] more internal rename --- src/common/tusb_mcu.h | 160 +++++++++--------- src/device/dcd.h | 2 +- src/portable/chipidea/ci_hs/dcd_ci_hs.c | 6 +- src/portable/ehci/ehci.c | 2 +- src/portable/mentor/musb/dcd_musb.c | 10 +- .../nxp/transdimension/dcd_transdimension.c | 6 +- src/portable/ohci/ohci.c | 2 +- src/portable/sunxi/dcd_sunxi_musb.c | 8 +- src/portable/synopsys/dwc2/dcd_dwc2.c | 2 +- src/tusb_option.h | 2 +- 10 files changed, 101 insertions(+), 99 deletions(-) diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 1f1aeb462..b4e023165 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -51,117 +51,119 @@ //------------- NXP -------------// #if TU_CHECK_MCU(OPT_MCU_LPC11UXX, OPT_MCU_LPC13XX, OPT_MCU_LPC15XX) - #define DCD_ATTR_ENDPOINT_MAX 5 + #define TUP_DCD_ENDPOINT_MAX 5 #elif TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX) - #define DCD_ATTR_ENDPOINT_MAX 16 - #define HCD_ATTR_OHCI + #define TUP_DCD_ENDPOINT_MAX 16 + #define TUP_USBIP_OHCI #elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX) // TODO USB0 has 6, USB1 has 4 #define TUP_USBIP_CHIPIDEA_HS - #define DCD_ATTR_ENDPOINT_MAX 6 - #define DCD_ATTR_RHPORT_HIGHSPEED 0x01 // Port0 HS, Port1 FS + #define TUP_USBIP_EHCI + + #define TUP_DCD_ENDPOINT_MAX 6 + #define TUP_RHPORT_HIGHSPEED 0x01 // Port0 HS, Port1 FS - #define HCD_ATTR_EHCI #elif TU_CHECK_MCU(OPT_MCU_LPC51UXX) - #define DCD_ATTR_ENDPOINT_MAX 5 + #define TUP_DCD_ENDPOINT_MAX 5 #elif TU_CHECK_MCU(OPT_MCU_LPC54XXX) // TODO USB0 has 5, USB1 has 6 - #define DCD_ATTR_ENDPOINT_MAX 6 + #define TUP_DCD_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_LPC55XX) // TODO USB0 has 5, USB1 has 6 - #define DCD_ATTR_ENDPOINT_MAX 6 + #define TUP_DCD_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_MIMXRT10XX) #define TUP_USBIP_CHIPIDEA_HS - #define DCD_ATTR_ENDPOINT_MAX 8 - #define DCD_ATTR_RHPORT_HIGHSPEED 0x03 // Port0 HS, Port1 HS + #define TUP_USBIP_EHCI + + #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_RHPORT_HIGHSPEED 0x03 // Port0 HS, Port1 HS - #define HCD_ATTR_EHCI #elif TU_CHECK_MCU(OPT_MCU_MKL25ZXX, OPT_MCU_K32L2BXX) - #define DCD_ATTR_ENDPOINT_MAX 16 + #define TUP_DCD_ENDPOINT_MAX 16 #elif TU_CHECK_MCU(OPT_MCU_MM32F327X) - #define DCD_ATTR_ENDPOINT_MAX 16 + #define TUP_DCD_ENDPOINT_MAX 16 //------------- Nordic -------------// #elif TU_CHECK_MCU(OPT_MCU_NRF5X) // 8 CBI + 1 ISO - #define DCD_ATTR_ENDPOINT_MAX 9 + #define TUP_DCD_ENDPOINT_MAX 9 //------------- Microchip -------------// #elif TU_CHECK_MCU(OPT_MCU_SAMD21, OPT_MCU_SAMD51, OPT_MCU_SAME5X) || \ TU_CHECK_MCU(OPT_MCU_SAMD11, OPT_MCU_SAML21, OPT_MCU_SAML22) - #define DCD_ATTR_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_SAMG) - #define DCD_ATTR_ENDPOINT_MAX 6 - #define DCD_ATTR_ENDPOINT_EXCLUSIVE_NUMBER + #define TUP_DCD_ENDPOINT_MAX 6 + #define TUP_DCD_ENDPOINT_EXCLUSIVE_NUMBER #elif TU_CHECK_MCU(OPT_MCU_SAMX7X) - #define DCD_ATTR_ENDPOINT_MAX 10 - #define DCD_ATTR_RHPORT_HIGHSPEED 0x01 - #define DCD_ATTR_ENDPOINT_EXCLUSIVE_NUMBER + #define TUP_DCD_ENDPOINT_MAX 10 + #define TUP_RHPORT_HIGHSPEED 0x01 + #define TUP_DCD_ENDPOINT_EXCLUSIVE_NUMBER #elif TU_CHECK_MCU(OPT_MCU_PIC32MZ) - #define DCD_ATTR_ENDPOINT_MAX 8 - #define DCD_ATTR_ENDPOINT_EXCLUSIVE_NUMBER + #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_EXCLUSIVE_NUMBER //------------- ST -------------// #elif TU_CHECK_MCU(OPT_MCU_STM32F0) - #define DCD_ATTR_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_STM32F1) #if defined (STM32F105x8) || defined (STM32F105xB) || defined (STM32F105xC) || \ defined (STM32F107xB) || defined (STM32F107xC) - #define DCD_ATTR_ENDPOINT_MAX 4 - #define TUP_USBIP_DWC2 - #define DCD_ATTR_DWC2_STM32 + #define TUP_USBIP_DWC2_STM32 + + #define TUP_DCD_ENDPOINT_MAX 4 #else - #define DCD_ATTR_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #endif #elif TU_CHECK_MCU(OPT_MCU_STM32F2) - // FS has 4 ep, HS has 5 ep - #define DCD_ATTR_ENDPOINT_MAX 6 - #define TUP_USBIP_DWC2 - #define DCD_ATTR_DWC2_STM32 + #define TUP_USBIP_DWC2_STM32 + + // FS has 4 ep, HS has 5 ep + #define TUP_DCD_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_STM32F3) - #define DCD_ATTR_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_STM32F4) - // For most mcu, FS has 4, HS has 6. TODO 446/469/479 HS has 9 - #define DCD_ATTR_ENDPOINT_MAX 6 - #define TUP_USBIP_DWC2 - #define DCD_ATTR_DWC2_STM32 + #define TUP_USBIP_DWC2_STM32 + + // For most mcu, FS has 4, HS has 6. TODO 446/469/479 HS has 9 + #define TUP_DCD_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_STM32F7) - // FS has 6, HS has 9 - #define DCD_ATTR_ENDPOINT_MAX 9 - #define TUP_USBIP_DWC2 - #define DCD_ATTR_DWC2_STM32 + #define TUP_USBIP_DWC2_STM32 + + // FS has 6, HS has 9 + #define TUP_DCD_ENDPOINT_MAX 9 #elif TU_CHECK_MCU(OPT_MCU_STM32H7) - #define DCD_ATTR_ENDPOINT_MAX 9 - #define TUP_USBIP_DWC2 - #define DCD_ATTR_DWC2_STM32 + #define TUP_USBIP_DWC2_STM32 + + #define TUP_DCD_ENDPOINT_MAX 9 #elif TU_CHECK_MCU(OPT_MCU_STM32G4) - #define DCD_ATTR_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_STM32L0, OPT_MCU_STM32L1) - #define DCD_ATTR_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_STM32L4) #if defined (STM32L475xx) || defined (STM32L476xx) || \ @@ -169,87 +171,87 @@ defined (STM32L4A6xx) || defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \ defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || \ defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx) - #define DCD_ATTR_ENDPOINT_MAX 6 - #define TUP_USBIP_DWC2 - #define DCD_ATTR_DWC2_STM32 + #define TUP_USBIP_DWC2_STM32 + + #define TUP_DCD_ENDPOINT_MAX 6 #else - #define DCD_ATTR_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #endif //------------- Sony -------------// #elif TU_CHECK_MCU(OPT_MCU_CXD56) - #define DCD_ATTR_ENDPOINT_MAX 7 - #define DCD_ATTR_RHPORT_HIGHSPEED 0x01 - #define DCD_ATTR_ENDPOINT_EXCLUSIVE_NUMBER + #define TUP_DCD_ENDPOINT_MAX 7 + #define TUP_RHPORT_HIGHSPEED 0x01 + #define TUP_DCD_ENDPOINT_EXCLUSIVE_NUMBER //------------- TI -------------// #elif TU_CHECK_MCU(OPT_MCU_MSP430x5xx) - #define DCD_ATTR_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) - #define DCD_ATTR_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 //------------- ValentyUSB -------------// #elif TU_CHECK_MCU(OPT_MCU_VALENTYUSB_EPTRI) - #define DCD_ATTR_ENDPOINT_MAX 16 + #define TUP_DCD_ENDPOINT_MAX 16 //------------- Nuvoton -------------// #elif TU_CHECK_MCU(OPT_MCU_NUC121, OPT_MCU_NUC126) - #define DCD_ATTR_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_NUC120) - #define DCD_ATTR_ENDPOINT_MAX 6 + #define TUP_DCD_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_NUC505) - #define DCD_ATTR_ENDPOINT_MAX 12 - #define DCD_ATTR_RHPORT_HIGHSPEED 0x01 + #define TUP_DCD_ENDPOINT_MAX 12 + #define TUP_RHPORT_HIGHSPEED 0x01 //------------- Espressif -------------// #elif TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) - #define DCD_ATTR_ENDPOINT_MAX 6 + #define TUP_DCD_ENDPOINT_MAX 6 //------------- Dialog -------------// #elif TU_CHECK_MCU(OPT_MCU_DA1469X) - #define DCD_ATTR_ENDPOINT_MAX 4 + #define TUP_DCD_ENDPOINT_MAX 4 //------------- Raspberry Pi -------------// #elif TU_CHECK_MCU(OPT_MCU_RP2040) - #define DCD_ATTR_ENDPOINT_MAX 16 + #define TUP_DCD_ENDPOINT_MAX 16 //------------- Silabs -------------// #elif TU_CHECK_MCU(OPT_MCU_EFM32GG) - #define DCD_ATTR_ENDPOINT_MAX 7 + #define TUP_DCD_ENDPOINT_MAX 7 //------------- Renesas -------------// #elif TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N) - #define DCD_ATTR_ENDPOINT_MAX 10 + #define TUP_DCD_ENDPOINT_MAX 10 //------------- GigaDevice -------------// #elif TU_CHECK_MCU(OPT_MCU_GD32VF103) - #define DCD_ATTR_ENDPOINT_MAX 4 + #define TUP_DCD_ENDPOINT_MAX 4 //------------- Broadcom -------------// #elif TU_CHECK_MCU(OPT_MCU_BCM2711, OPT_MCU_BCM2835, OPT_MCU_BCM2837) - #define DCD_ATTR_ENDPOINT_MAX 8 - #define DCD_ATTR_RHPORT_HIGHSPEED 0x01 + #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_RHPORT_HIGHSPEED 0x01 //------------- Broadcom -------------// #elif TU_CHECK_MCU(OPT_MCU_XMC4000) - #define DCD_ATTR_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 //------------- BridgeTek -------------// #elif TU_CHECK_MCU(OPT_MCU_FT90X) - #define DCD_ATTR_ENDPOINT_MAX 8 - #define DCD_ATTR_RHPORT_HIGHSPEED 0x01 + #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_RHPORT_HIGHSPEED 0x01 #elif TU_CHECK_MCU(OPT_MCU_FT93X) - #define DCD_ATTR_ENDPOINT_MAX 16 - #define DCD_ATTR_RHPORT_HIGHSPEED 0x01 + #define TUP_DCD_ENDPOINT_MAX 16 + #define TUP_RHPORT_HIGHSPEED 0x01 //------------ Allwinner -------------// #elif TU_CHECK_MCU(OPT_MCU_F1C100S) - #define DCD_ATTR_ENDPOINT_MAX 4 + #define TUP_DCD_ENDPOINT_MAX 4 #endif @@ -257,14 +259,14 @@ // Default Values //--------------------------------------------------------------------+ -#ifndef DCD_ATTR_ENDPOINT_MAX - #warning "DCD_ATTR_ENDPOINT_MAX is not defined for this MCU, default to 8" - #define DCD_ATTR_ENDPOINT_MAX 8 +#ifndef TUP_DCD_ENDPOINT_MAX + #warning "TUP_DCD_ENDPOINT_MAX is not defined for this MCU, default to 8" + #define TUP_DCD_ENDPOINT_MAX 8 #endif // Default to fullspeed if not defined -#ifndef DCD_ATTR_RHPORT_HIGHSPEED - #define DCD_ATTR_RHPORT_HIGHSPEED 0x00 +#ifndef TUP_RHPORT_HIGHSPEED + #define TUP_RHPORT_HIGHSPEED 0x00 #endif #endif diff --git a/src/device/dcd.h b/src/device/dcd.h index 4e725c95a..8efbc90ef 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -40,7 +40,7 @@ //--------------------------------------------------------------------+ #ifndef CFG_TUD_ENDPPOINT_MAX - #define CFG_TUD_ENDPPOINT_MAX DCD_ATTR_ENDPOINT_MAX + #define CFG_TUD_ENDPPOINT_MAX TUP_DCD_ENDPOINT_MAX #endif //--------------------------------------------------------------------+ diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c index 726c7a517..32c2fc029 100644 --- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c @@ -151,8 +151,8 @@ typedef struct { // Must be at 2K alignment // Each endpoint with direction (IN/OUT) occupies a queue head // for portability, TinyUSB only queue 1 TD for each Qhd - dcd_qhd_t qhd[DCD_ATTR_ENDPOINT_MAX][2] TU_ATTR_ALIGNED(64); - dcd_qtd_t qtd[DCD_ATTR_ENDPOINT_MAX][2] TU_ATTR_ALIGNED(32); + dcd_qhd_t qhd[TUP_DCD_ENDPOINT_MAX][2] TU_ATTR_ALIGNED(64); + dcd_qtd_t qtd[TUP_DCD_ENDPOINT_MAX][2] TU_ATTR_ALIGNED(32); }dcd_data_t; CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(2048) @@ -619,7 +619,7 @@ void dcd_int_handler(uint8_t rhport) if ( edpt_complete ) { - for(uint8_t epnum = 0; epnum < DCD_ATTR_ENDPOINT_MAX; epnum++) + for(uint8_t epnum = 0; epnum < TUP_DCD_ENDPOINT_MAX; epnum++) { if ( tu_bit_test(edpt_complete, epnum) ) process_edpt_complete_isr(rhport, epnum, TUSB_DIR_OUT); if ( tu_bit_test(edpt_complete, epnum+16) ) process_edpt_complete_isr(rhport, epnum, TUSB_DIR_IN); diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index ac873455b..acfc561fe 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if CFG_TUH_ENABLED && defined(HCD_ATTR_EHCI) +#if CFG_TUH_ENABLED && defined(TUP_USBIP_EHCI) //--------------------------------------------------------------------+ // INCLUDE diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 71414e737..d36585592 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -170,13 +170,13 @@ static inline void print_block_list(free_block_t const *blk, unsigned num) static unsigned find_free_memory(uint_fast16_t size_in_log2_minus3) { - free_block_t free_blocks[2 * (DCD_ATTR_ENDPOINT_MAX - 1)]; + free_block_t free_blocks[2 * (TUP_DCD_ENDPOINT_MAX - 1)]; unsigned num_blocks = 1; /* Initialize free memory block list */ free_blocks[0].beg = 64 / 8; free_blocks[0].end = (4 << 10) / 8; /* 4KiB / 8 bytes */ - for (int i = 1; i < DCD_ATTR_ENDPOINT_MAX; ++i) { + for (int i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { uint_fast16_t addr; int num; USB0->EPIDX = i; @@ -575,7 +575,7 @@ static void process_bus_reset(uint8_t rhport) USB0->RXIE = 0; /* Clear FIFO settings */ - for (unsigned i = 1; i < DCD_ATTR_ENDPOINT_MAX; ++i) { + for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { USB0->EPIDX = i; USB0->TXFIFOSZ = 0; USB0->TXFIFOADD = 0; @@ -663,7 +663,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) const unsigned xfer = ep_desc->bmAttributes.xfer; const unsigned mps = tu_edpt_packet_size(ep_desc); - TU_ASSERT(epn < DCD_ATTR_ENDPOINT_MAX); + TU_ASSERT(epn < TUP_DCD_ENDPOINT_MAX); pipe_state_t *pipe = &_dcd.pipe[dir_in][epn - 1]; pipe->buf = NULL; @@ -715,7 +715,7 @@ void dcd_edpt_close_all(uint8_t rhport) NVIC_DisableIRQ(USB0_IRQn); USB0->TXIE = 1; /* Enable only EP0 */ USB0->RXIE = 0; - for (unsigned i = 1; i < DCD_ATTR_ENDPOINT_MAX; ++i) { + for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { regs->TXMAXP = 0; regs->TXCSRH = 0; if (regs->TXCSRL & USB_TXCSRL1_TXRDY) diff --git a/src/portable/nxp/transdimension/dcd_transdimension.c b/src/portable/nxp/transdimension/dcd_transdimension.c index 9f5979ab4..108baf99d 100644 --- a/src/portable/nxp/transdimension/dcd_transdimension.c +++ b/src/portable/nxp/transdimension/dcd_transdimension.c @@ -179,8 +179,8 @@ typedef struct { // Must be at 2K alignment // Each endpoint with direction (IN/OUT) occupies a queue head // for portability, TinyUSB only queue 1 TD for each Qhd - dcd_qhd_t qhd[DCD_ATTR_ENDPOINT_MAX][2] TU_ATTR_ALIGNED(64); - dcd_qtd_t qtd[DCD_ATTR_ENDPOINT_MAX][2] TU_ATTR_ALIGNED(32); + dcd_qhd_t qhd[TUP_DCD_ENDPOINT_MAX][2] TU_ATTR_ALIGNED(64); + dcd_qtd_t qtd[TUP_DCD_ENDPOINT_MAX][2] TU_ATTR_ALIGNED(32); }dcd_data_t; CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(2048) @@ -647,7 +647,7 @@ void dcd_int_handler(uint8_t rhport) if ( edpt_complete ) { - for(uint8_t epnum = 0; epnum < DCD_ATTR_ENDPOINT_MAX; epnum++) + for(uint8_t epnum = 0; epnum < TUP_DCD_ENDPOINT_MAX; epnum++) { if ( tu_bit_test(edpt_complete, epnum) ) process_edpt_complete_isr(rhport, epnum, TUSB_DIR_OUT); if ( tu_bit_test(edpt_complete, epnum+16) ) process_edpt_complete_isr(rhport, epnum, TUSB_DIR_IN); diff --git a/src/portable/ohci/ohci.c b/src/portable/ohci/ohci.c index c9e1061f9..cb4e6dc4a 100644 --- a/src/portable/ohci/ohci.c +++ b/src/portable/ohci/ohci.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if CFG_TUH_ENABLED && defined(HCD_ATTR_OHCI) +#if CFG_TUH_ENABLED && defined(TUP_USBIP_OHCI) //--------------------------------------------------------------------+ // INCLUDE diff --git a/src/portable/sunxi/dcd_sunxi_musb.c b/src/portable/sunxi/dcd_sunxi_musb.c index 447069f88..27514339b 100644 --- a/src/portable/sunxi/dcd_sunxi_musb.c +++ b/src/portable/sunxi/dcd_sunxi_musb.c @@ -426,7 +426,7 @@ static inline void print_block_list(free_block_t const *blk, unsigned num) static unsigned find_free_memory(uint_fast16_t size_in_log2_minus3) { - free_block_t free_blocks[2 * (DCD_ATTR_ENDPOINT_MAX - 1)]; + free_block_t free_blocks[2 * (TUP_DCD_ENDPOINT_MAX - 1)]; unsigned num_blocks = 1; /* Backup current EP to restore later */ u8 backup_ep = USBC_GetActiveEp(); @@ -434,7 +434,7 @@ static unsigned find_free_memory(uint_fast16_t size_in_log2_minus3) /* Initialize free memory block list */ free_blocks[0].beg = 64 / 8; free_blocks[0].end = (USB_FIFO_SIZE_KB << 10) / 8; /* 2KiB / 8 bytes */ - for (int i = 1; i < DCD_ATTR_ENDPOINT_MAX; ++i) { + for (int i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { uint_fast16_t addr; int num; USBC_SelectActiveEp(i); @@ -974,7 +974,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) const unsigned xfer = ep_desc->bmAttributes.xfer; const unsigned mps = tu_edpt_packet_size(ep_desc); - TU_ASSERT(epn < DCD_ATTR_ENDPOINT_MAX); + TU_ASSERT(epn < TUP_DCD_ENDPOINT_MAX); pipe_state_t *pipe = &_dcd.pipe[dir_in][epn - 1]; pipe->buf = NULL; @@ -1033,7 +1033,7 @@ void dcd_edpt_close_all(uint8_t rhport) musb_int_mask(); USBC_Writew(1, USBC_REG_INTTxE(USBC0_BASE)); /* Enable only EP0 */ USBC_Writew(0, USBC_REG_INTRxE(USBC0_BASE)); - for (unsigned i = 1; i < DCD_ATTR_ENDPOINT_MAX; ++i) { + for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { USBC_SelectActiveEp(i); USBC_Writew(0, USBC_REG_TXMAXP(USBC0_BASE)); USBC_Writew((1 << USBC_BP_TXCSR_D_MODE) | (1 << USBC_BP_TXCSR_D_CLEAR_DATA_TOGGLE) | (1 << USBC_BP_TXCSR_D_FLUSH_FIFO), diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 377f0f44e..a765bc275 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -38,7 +38,7 @@ #include "device/dcd.h" #include "dwc2_type.h" -#if defined(DCD_ATTR_DWC2_STM32) +#if defined(TUP_USBIP_DWC2_STM32) #include "dwc2_stm32.h" #elif TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) #include "dwc2_esp32.h" diff --git a/src/tusb_option.h b/src/tusb_option.h index 3c2207c26..25e536787 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -218,7 +218,7 @@ #endif #define CFG_TUD_ENABLED ( TUD_RHPORT_MODE & OPT_MODE_DEVICE ) -#define TUD_OPT_HIGH_SPEED ( (TUD_RHPORT_MODE & OPT_MODE_SPEED_MASK) ? (TUD_RHPORT_MODE & OPT_MODE_HIGH_SPEED) : (DCD_ATTR_RHPORT_HIGHSPEED & (1 << TUD_OPT_RHPORT)) ) +#define TUD_OPT_HIGH_SPEED ( (TUD_RHPORT_MODE & OPT_MODE_SPEED_MASK) ? (TUD_RHPORT_MODE & OPT_MODE_HIGH_SPEED) : (TUP_RHPORT_HIGHSPEED & (1 << TUD_OPT_RHPORT)) ) //------------- Roothub as Host -------------// From a4ba3f2891bad76cb3188159ac8e8dc223175230 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 26 Feb 2022 17:13:06 +0700 Subject: [PATCH 175/504] add TUP_USBIP_DWC2 --- src/common/tusb_mcu.h | 111 ++++++++++++++------------ src/portable/synopsys/dwc2/dcd_dwc2.c | 6 +- 2 files changed, 59 insertions(+), 58 deletions(-) diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index b4e023165..5fc504437 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -51,10 +51,10 @@ //------------- NXP -------------// #if TU_CHECK_MCU(OPT_MCU_LPC11UXX, OPT_MCU_LPC13XX, OPT_MCU_LPC15XX) - #define TUP_DCD_ENDPOINT_MAX 5 + #define TUP_DCD_ENDPOINT_MAX 5 #elif TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX) - #define TUP_DCD_ENDPOINT_MAX 16 + #define TUP_DCD_ENDPOINT_MAX 16 #define TUP_USBIP_OHCI #elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX) @@ -62,8 +62,8 @@ #define TUP_USBIP_CHIPIDEA_HS #define TUP_USBIP_EHCI - #define TUP_DCD_ENDPOINT_MAX 6 - #define TUP_RHPORT_HIGHSPEED 0x01 // Port0 HS, Port1 FS + #define TUP_DCD_ENDPOINT_MAX 6 + #define TUP_RHPORT_HIGHSPEED 0x01 // Port0 HS, Port1 FS #elif TU_CHECK_MCU(OPT_MCU_LPC51UXX) @@ -71,52 +71,52 @@ #elif TU_CHECK_MCU(OPT_MCU_LPC54XXX) // TODO USB0 has 5, USB1 has 6 - #define TUP_DCD_ENDPOINT_MAX 6 + #define TUP_DCD_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_LPC55XX) // TODO USB0 has 5, USB1 has 6 - #define TUP_DCD_ENDPOINT_MAX 6 + #define TUP_DCD_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_MIMXRT10XX) #define TUP_USBIP_CHIPIDEA_HS #define TUP_USBIP_EHCI - #define TUP_DCD_ENDPOINT_MAX 8 - #define TUP_RHPORT_HIGHSPEED 0x03 // Port0 HS, Port1 HS + #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_RHPORT_HIGHSPEED 0x03 // Port0 HS, Port1 HS #elif TU_CHECK_MCU(OPT_MCU_MKL25ZXX, OPT_MCU_K32L2BXX) - #define TUP_DCD_ENDPOINT_MAX 16 + #define TUP_DCD_ENDPOINT_MAX 16 #elif TU_CHECK_MCU(OPT_MCU_MM32F327X) - #define TUP_DCD_ENDPOINT_MAX 16 + #define TUP_DCD_ENDPOINT_MAX 16 //------------- Nordic -------------// #elif TU_CHECK_MCU(OPT_MCU_NRF5X) // 8 CBI + 1 ISO - #define TUP_DCD_ENDPOINT_MAX 9 + #define TUP_DCD_ENDPOINT_MAX 9 //------------- Microchip -------------// #elif TU_CHECK_MCU(OPT_MCU_SAMD21, OPT_MCU_SAMD51, OPT_MCU_SAME5X) || \ TU_CHECK_MCU(OPT_MCU_SAMD11, OPT_MCU_SAML21, OPT_MCU_SAML22) - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_SAMG) - #define TUP_DCD_ENDPOINT_MAX 6 + #define TUP_DCD_ENDPOINT_MAX 6 #define TUP_DCD_ENDPOINT_EXCLUSIVE_NUMBER #elif TU_CHECK_MCU(OPT_MCU_SAMX7X) - #define TUP_DCD_ENDPOINT_MAX 10 - #define TUP_RHPORT_HIGHSPEED 0x01 + #define TUP_DCD_ENDPOINT_MAX 10 + #define TUP_RHPORT_HIGHSPEED 0x01 #define TUP_DCD_ENDPOINT_EXCLUSIVE_NUMBER #elif TU_CHECK_MCU(OPT_MCU_PIC32MZ) - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #define TUP_DCD_ENDPOINT_EXCLUSIVE_NUMBER //------------- ST -------------// #elif TU_CHECK_MCU(OPT_MCU_STM32F0) - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_STM32F1) #if defined (STM32F105x8) || defined (STM32F105xB) || defined (STM32F105xC) || \ @@ -124,9 +124,9 @@ #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 - #define TUP_DCD_ENDPOINT_MAX 4 + #define TUP_DCD_ENDPOINT_MAX 4 #else - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #endif #elif TU_CHECK_MCU(OPT_MCU_STM32F2) @@ -134,36 +134,36 @@ #define TUP_USBIP_DWC2_STM32 // FS has 4 ep, HS has 5 ep - #define TUP_DCD_ENDPOINT_MAX 6 + #define TUP_DCD_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_STM32F3) - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_STM32F4) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 // For most mcu, FS has 4, HS has 6. TODO 446/469/479 HS has 9 - #define TUP_DCD_ENDPOINT_MAX 6 + #define TUP_DCD_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_STM32F7) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 // FS has 6, HS has 9 - #define TUP_DCD_ENDPOINT_MAX 9 + #define TUP_DCD_ENDPOINT_MAX 9 #elif TU_CHECK_MCU(OPT_MCU_STM32H7) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 - #define TUP_DCD_ENDPOINT_MAX 9 + #define TUP_DCD_ENDPOINT_MAX 9 #elif TU_CHECK_MCU(OPT_MCU_STM32G4) - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_STM32L0, OPT_MCU_STM32L1) - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_STM32L4) #if defined (STM32L475xx) || defined (STM32L476xx) || \ @@ -174,84 +174,89 @@ #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 - #define TUP_DCD_ENDPOINT_MAX 6 + #define TUP_DCD_ENDPOINT_MAX 6 #else - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #endif //------------- Sony -------------// #elif TU_CHECK_MCU(OPT_MCU_CXD56) - #define TUP_DCD_ENDPOINT_MAX 7 - #define TUP_RHPORT_HIGHSPEED 0x01 + #define TUP_DCD_ENDPOINT_MAX 7 + #define TUP_RHPORT_HIGHSPEED 0x01 #define TUP_DCD_ENDPOINT_EXCLUSIVE_NUMBER //------------- TI -------------// #elif TU_CHECK_MCU(OPT_MCU_MSP430x5xx) - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 //------------- ValentyUSB -------------// #elif TU_CHECK_MCU(OPT_MCU_VALENTYUSB_EPTRI) - #define TUP_DCD_ENDPOINT_MAX 16 + #define TUP_DCD_ENDPOINT_MAX 16 //------------- Nuvoton -------------// #elif TU_CHECK_MCU(OPT_MCU_NUC121, OPT_MCU_NUC126) - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_NUC120) - #define TUP_DCD_ENDPOINT_MAX 6 + #define TUP_DCD_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_NUC505) - #define TUP_DCD_ENDPOINT_MAX 12 - #define TUP_RHPORT_HIGHSPEED 0x01 + #define TUP_DCD_ENDPOINT_MAX 12 + #define TUP_RHPORT_HIGHSPEED 0x01 //------------- Espressif -------------// #elif TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) - #define TUP_DCD_ENDPOINT_MAX 6 + #define TUP_USBIP_DWC2 + #define TUP_DCD_ENDPOINT_MAX 6 //------------- Dialog -------------// #elif TU_CHECK_MCU(OPT_MCU_DA1469X) - #define TUP_DCD_ENDPOINT_MAX 4 + #define TUP_DCD_ENDPOINT_MAX 4 //------------- Raspberry Pi -------------// #elif TU_CHECK_MCU(OPT_MCU_RP2040) - #define TUP_DCD_ENDPOINT_MAX 16 + #define TUP_DCD_ENDPOINT_MAX 16 //------------- Silabs -------------// #elif TU_CHECK_MCU(OPT_MCU_EFM32GG) - #define TUP_DCD_ENDPOINT_MAX 7 + #define TUP_USBIP_DWC2 + #define TUP_DCD_ENDPOINT_MAX 7 //------------- Renesas -------------// #elif TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N) - #define TUP_DCD_ENDPOINT_MAX 10 + #define TUP_DCD_ENDPOINT_MAX 10 //------------- GigaDevice -------------// #elif TU_CHECK_MCU(OPT_MCU_GD32VF103) - #define TUP_DCD_ENDPOINT_MAX 4 + #define TUP_USBIP_DWC2 + #define TUP_DCD_ENDPOINT_MAX 4 //------------- Broadcom -------------// #elif TU_CHECK_MCU(OPT_MCU_BCM2711, OPT_MCU_BCM2835, OPT_MCU_BCM2837) - #define TUP_DCD_ENDPOINT_MAX 8 - #define TUP_RHPORT_HIGHSPEED 0x01 + #define TUP_USBIP_DWC2 + #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_RHPORT_HIGHSPEED 0x01 //------------- Broadcom -------------// #elif TU_CHECK_MCU(OPT_MCU_XMC4000) - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_USBIP_DWC2 + #define TUP_DCD_ENDPOINT_MAX 8 //------------- BridgeTek -------------// #elif TU_CHECK_MCU(OPT_MCU_FT90X) - #define TUP_DCD_ENDPOINT_MAX 8 - #define TUP_RHPORT_HIGHSPEED 0x01 + #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_RHPORT_HIGHSPEED 0x01 #elif TU_CHECK_MCU(OPT_MCU_FT93X) - #define TUP_DCD_ENDPOINT_MAX 16 - #define TUP_RHPORT_HIGHSPEED 0x01 + #define TUP_DCD_ENDPOINT_MAX 16 + #define TUP_RHPORT_HIGHSPEED 0x01 //------------ Allwinner -------------// #elif TU_CHECK_MCU(OPT_MCU_F1C100S) - #define TUP_DCD_ENDPOINT_MAX 4 + #define TUP_DCD_ENDPOINT_MAX 4 #endif @@ -261,12 +266,12 @@ #ifndef TUP_DCD_ENDPOINT_MAX #warning "TUP_DCD_ENDPOINT_MAX is not defined for this MCU, default to 8" - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #endif // Default to fullspeed if not defined #ifndef TUP_RHPORT_HIGHSPEED - #define TUP_RHPORT_HIGHSPEED 0x00 + #define TUP_RHPORT_HIGHSPEED 0x00 #endif #endif diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index a765bc275..c71f38d2d 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -29,11 +29,7 @@ #include "tusb_option.h" -#if CFG_TUD_ENABLED && \ - ( defined(TUP_USBIP_DWC2) || \ - TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3, OPT_MCU_GD32VF103) || \ - TU_CHECK_MCU(OPT_MCU_EFM32GG, OPT_MCU_BCM2711, OPT_MCU_BCM2835) || \ - TU_CHECK_MCU(OPT_MCU_BCM2837, OPT_MCU_XMC4000) ) +#if CFG_TUD_ENABLED && defined(TUP_USBIP_DWC2) #include "device/dcd.h" #include "dwc2_type.h" From 2fe3a925fbee91c1b5d8515c9fba25e5bd8b87a6 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 26 Feb 2022 17:34:29 +0700 Subject: [PATCH 176/504] add highspeed detect for f723/730/733 --- src/common/tusb_mcu.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 5fc504437..465e33ec7 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -153,6 +153,11 @@ // FS has 6, HS has 9 #define TUP_DCD_ENDPOINT_MAX 9 + // MCU with on-chip HS Phy + #if defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F733xx) + #define TUP_RHPORT_HIGHSPEED 0x02 // Port 0: FS, Port 1: HS + #endif + #elif TU_CHECK_MCU(OPT_MCU_STM32H7) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 From 1d29817139c473971ce239bbc2cb5924de4a644e Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 1 Mar 2022 23:55:53 +0700 Subject: [PATCH 177/504] start to add pio usb (host) support run as proof of concept --- examples/host/cdc_msc_hid/CMakeLists.txt | 2 +- examples/host/cdc_msc_hid/src/tusb_config.h | 7 +- hw/bsp/rp2040/family.c | 3 + hw/bsp/rp2040/family.cmake | 20 +- lib/Pico-PIO-USB | 1 + src/host/hcd.h | 13 +- src/host/usbh.c | 12 +- src/host/usbh_control.c | 9 +- src/portable/raspberrypi/pio/hcd_pio.c | 237 +++++++++++++++++++ src/portable/raspberrypi/rp2040/hcd_rp2040.c | 9 +- 10 files changed, 300 insertions(+), 13 deletions(-) create mode 160000 lib/Pico-PIO-USB create mode 100644 src/portable/raspberrypi/pio/hcd_pio.c diff --git a/examples/host/cdc_msc_hid/CMakeLists.txt b/examples/host/cdc_msc_hid/CMakeLists.txt index 0a99bc3a9..95c07339e 100644 --- a/examples/host/cdc_msc_hid/CMakeLists.txt +++ b/examples/host/cdc_msc_hid/CMakeLists.txt @@ -26,4 +26,4 @@ target_include_directories(${PROJECT} PUBLIC # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. -family_configure_host_example(${PROJECT}) \ No newline at end of file +family_configure_host_example(${PROJECT}) diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index bc6c68e5b..abbe474c2 100644 --- a/examples/host/cdc_msc_hid/src/tusb_config.h +++ b/examples/host/cdc_msc_hid/src/tusb_config.h @@ -42,7 +42,9 @@ #if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | OPT_MODE_HIGH_SPEED) #else - #define CFG_TUSB_RHPORT0_MODE OPT_MODE_HOST + //#define CFG_TUSB_RHPORT0_MODE OPT_MODE_HOST + // rp2040: port0 is native, port 1 for PIO-USB + #define CFG_TUSB_RHPORT1_MODE OPT_MODE_HOST #endif #ifndef CFG_TUSB_OS @@ -71,6 +73,9 @@ // CONFIGURATION //-------------------------------------------------------------------- +#define CFG_TUH_RPI_PIO 1 +//#define CFG_TUSB_RPI_PIO_INC_PATH 1 + // Size of buffer to hold descriptors and other data used for enumeration #define CFG_TUH_ENUMERATION_BUFSIZE 256 diff --git a/hw/bsp/rp2040/family.c b/hw/bsp/rp2040/family.c index fa63dadf5..dcf38b6ec 100644 --- a/hw/bsp/rp2040/family.c +++ b/hw/bsp/rp2040/family.c @@ -127,6 +127,9 @@ void board_init(void) #ifndef BUTTON_BOOTSEL #endif + // Set the system clock to a multiple of 120mhz for bitbanging USB with pico-usb + set_sys_clock_khz(120000, true); + #if defined(UART_DEV) && defined(LIB_PICO_STDIO_UART) bi_decl(bi_2pins_with_func(UART_TX_PIN, UART_TX_PIN, GPIO_FUNC_UART)); uart_inst = uart_get_instance(UART_DEV); diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index 1aa180ef8..ddb34bf7d 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -89,13 +89,27 @@ if (NOT TARGET _rp2040_family_inclusion_marker) ${TOP}/src/class/hid/hid_host.c ${TOP}/src/class/msc/msc_host.c ${TOP}/src/class/vendor/vendor_host.c + + ${TOP}/src/portable/raspberrypi/pio/hcd_pio.c + ${TOP}/lib/Pico-PIO-USB/pio_usb.c + ${TOP}/lib/Pico-PIO-USB/usb_crc.c ) - # Sometimes have to do host specific actions in mostly - # common functions + # Sometimes have to do host specific actions in mostly common functions target_compile_definitions(tinyusb_host_base INTERFACE RP2040_USB_HOST_MODE=1 ) + + # config for host pio + target_link_libraries(tinyusb_host_base INTERFACE + hardware_dma + hardware_pio + pico_multicore + ) + + target_include_directories(tinyusb_host_base INTERFACE + ${TOP}/lib/Pico-PIO-USB + ) add_library(tinyusb_bsp INTERFACE) target_sources(tinyusb_bsp INTERFACE @@ -151,6 +165,8 @@ if (NOT TARGET _rp2040_family_inclusion_marker) _family_initialize_project(${PROJECT} ${DIR}) enable_language(C CXX ASM) pico_sdk_init() + pico_generate_pio_header(tinyusb_host_base ${TOP}/lib/Pico-PIO-USB/usb_tx.pio) + pico_generate_pio_header(tinyusb_host_base ${TOP}/lib/Pico-PIO-USB/usb_rx.pio) endfunction() # This method must be called from the project scope to suppress known warnings in TinyUSB source files diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB new file mode 160000 index 000000000..7d6729900 --- /dev/null +++ b/lib/Pico-PIO-USB @@ -0,0 +1 @@ +Subproject commit 7d672990011695892da523cb0ac29a2c7243a4c9 diff --git a/src/host/hcd.h b/src/host/hcd.h index 80500f048..9d10104f3 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -143,9 +143,20 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr); // Endpoints API //--------------------------------------------------------------------+ -bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]); +// Open an endpoint bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc); + +// Submit a transfer, when complete hcd_event_xfer_complete() must be invoked bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen); + +// Submit a special transfer to send 8-byte Setup Packet, when complete hcd_event_xfer_complete() must be invoked +bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]); + +// Optional: some controllers are capable of carry out the whole Control Transfer (setup, data, status) +// without help of USBH. +bool hcd_edpt_control_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8], uint8_t* data) TU_ATTR_WEAK; + +// clear stall, data toggle is also reset to DATA0 bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr); //--------------------------------------------------------------------+ diff --git a/src/host/usbh.c b/src/host/usbh.c index 130aba40e..ea0a0809d 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -358,12 +358,12 @@ void tuh_task(void) case HCD_EVENT_DEVICE_ATTACH: // TODO due to the shared _usbh_ctrl_buf, we must complete enumerating // one device before enumerating another one. - TU_LOG2("USBH DEVICE ATTACH\r\n"); + TU_LOG2("[rh%d] USBH DEVICE ATTACH\r\n", event.rhport); enum_new_device(&event); break; case HCD_EVENT_DEVICE_REMOVE: - TU_LOG2("USBH DEVICE REMOVED\r\n"); + TU_LOG2("[rh%d] USBH DEVICE REMOVED\r\n", event.rhport); process_device_unplugged(event.rhport, event.connection.hub_addr, event.connection.hub_port); #if CFG_TUH_HUB @@ -703,7 +703,9 @@ static bool enum_new_device(hcd_event_t* event) if (_dev0.hub_addr == 0) { // wait until device is stable TODO non blocking + hcd_port_reset(_dev0.rhport); osal_task_delay(RESET_DELAY); + hcd_port_reset_end( _dev0.rhport); // device unplugged while delaying if ( !hcd_port_connect_status(_dev0.rhport) ) return true; @@ -772,13 +774,17 @@ static bool enum_get_addr0_device_desc_complete(uint8_t dev_addr, tusb_control_r TU_ASSERT( tu_desc_type(desc_device) == TUSB_DESC_DEVICE ); // Reset device again before Set Address + // reset port after 8 byte descriptor TU_LOG2("Port reset \r\n"); if (_dev0.hub_addr == 0) { +#if !CFG_TUH_RPI_PIO // skip this reset for pio-usb // connected directly to roothub - hcd_port_reset( _dev0.rhport ); // reset port after 8 byte descriptor + hcd_port_reset(_dev0.rhport); osal_task_delay(RESET_DELAY); + hcd_port_reset_end(_dev0.rhport); +#endif enum_request_set_addr(); } diff --git a/src/host/usbh_control.c b/src/host/usbh_control.c index d034eec7f..1c73d6626 100644 --- a/src/host/usbh_control.c +++ b/src/host/usbh_control.c @@ -71,7 +71,14 @@ bool tuh_control_xfer (uint8_t dev_addr, tusb_control_request_t const* request, TU_LOG2("\r\n"); // Send setup packet - TU_ASSERT( hcd_setup_send(rhport, dev_addr, (uint8_t const*) &_ctrl_xfer.request) ); + if ( hcd_edpt_control_xfer ) + { + _ctrl_xfer.stage = STAGE_ACK; + TU_ASSERT( hcd_edpt_control_xfer(rhport, dev_addr, (uint8_t const*) &_ctrl_xfer.request, buffer) ); + }else + { + TU_ASSERT( hcd_setup_send(rhport, dev_addr, (uint8_t const*) &_ctrl_xfer.request) ); + } return true; } diff --git a/src/portable/raspberrypi/pio/hcd_pio.c b/src/portable/raspberrypi/pio/hcd_pio.c new file mode 100644 index 000000000..74df49e0d --- /dev/null +++ b/src/portable/raspberrypi/pio/hcd_pio.c @@ -0,0 +1,237 @@ +/* + * 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. + */ + +#include "tusb_option.h" + +#if CFG_TUH_ENABLED && (CFG_TUSB_MCU == OPT_MCU_RP2040) && CFG_TUH_RPI_PIO + +#include "pico.h" +#include "hardware/pio.h" +#include "pio_usb.h" + +//--------------------------------------------------------------------+ +// INCLUDE +//--------------------------------------------------------------------+ +#include "osal/osal.h" + +#include "host/hcd.h" +#include "host/usbh.h" + +#define RHPORT_OFFSET 1 +#define RHPORT_PIO(_x) ((_x)-RHPORT_OFFSET) + + +static usb_device_t *_test_usb_device = NULL; +static pio_usb_configuration_t pio_host_config = PIO_USB_DEFAULT_CONFIG; + +extern root_port_t root_port[PIO_USB_ROOT_PORT_CNT]; +extern usb_device_t usb_device[PIO_USB_DEVICE_CNT]; +extern pio_port_t pio_port[1]; +extern root_port_t root_port[PIO_USB_ROOT_PORT_CNT]; +extern endpoint_t ep_pool[PIO_USB_EP_POOL_CNT]; + + +extern port_pin_status_t get_port_pin_status( root_port_t *port); +extern void configure_fullspeed_host( pio_port_t *pp, const pio_usb_configuration_t *c, root_port_t *port); +extern void configure_lowspeed_host( pio_port_t *pp, const pio_usb_configuration_t *c, root_port_t *port); + +extern void control_setup_transfer( const pio_port_t *pp, uint8_t device_address, uint8_t *tx_data_address, uint8_t tx_data_len); +extern int control_in_protocol( usb_device_t *device, uint8_t *tx_data, uint16_t tx_length, uint8_t *rx_buffer, uint16_t request_length); +extern int control_out_protocol( usb_device_t *device, uint8_t *setup_data, uint16_t setup_length, uint8_t *out_data, uint16_t out_length); + +extern void update_packet_crc16(usb_setup_packet_t * packet); + +//--------------------------------------------------------------------+ +// HCD API +//--------------------------------------------------------------------+ +bool hcd_init(uint8_t rhport) +{ + // To run USB SOF interrupt in core1, create alarm pool in core1. + pio_host_config.alarm_pool = (void*)alarm_pool_create(2, 1); + _test_usb_device = pio_usb_host_init(&pio_host_config); + + return true; +} + +void hcd_port_reset(uint8_t rhport) +{ + rhport = RHPORT_PIO(rhport); + + pio_port_t *pp = &pio_port[0]; + root_port_t *root = &root_port[rhport]; + + pio_sm_set_pins_with_mask(pp->pio_usb_tx, pp->sm_tx, (0b00 << root->pin_dp), + (0b11u << root->pin_dp)); + pio_sm_set_pindirs_with_mask(pp->pio_usb_tx, pp->sm_tx, (0b11u << root->pin_dp), + (0b11u << root->pin_dp)); +} + +void hcd_port_reset_end(uint8_t rhport) +{ + rhport = RHPORT_PIO(rhport); + + pio_port_t *pp = &pio_port[0]; + root_port_t *root = &root_port[rhport]; + + pio_sm_set_pindirs_with_mask(pp->pio_usb_tx, pp->sm_tx, (0b00u << root->pin_dp), + (0b11u << root->pin_dp)); + + busy_wait_us(100); + + // TODO slow speed + bool fullspeed_flag = true; + + if (fullspeed_flag && get_port_pin_status(root) == PORT_PIN_FS_IDLE) { + root->root_device = &usb_device[0]; + if (!root->root_device->connected) { + configure_fullspeed_host(pp, &pio_host_config, root); + root->root_device->is_fullspeed = true; + root->root_device->is_root = true; + root->root_device->connected = true; + root->root_device->root = root; + root->root_device->event = EVENT_CONNECT; + } + } else if (!fullspeed_flag && get_port_pin_status(root) == PORT_PIN_LS_IDLE) { + root->root_device = &usb_device[0]; + if (!root->root_device->connected) { + configure_lowspeed_host(pp, &pio_host_config, root); + root->root_device->is_fullspeed = false; + root->root_device->is_root = true; + root->root_device->connected = true; + root->root_device->root = root; + root->root_device->event = EVENT_CONNECT; + } + } +} + +bool hcd_port_connect_status(uint8_t rhport) +{ + root_port_t* port = &root_port[0]; + bool dp = gpio_get(port->pin_dp); + bool dm = gpio_get(port->pin_dm); + return dp || dm; +} + +tusb_speed_t hcd_port_speed_get(uint8_t rhport) +{ + // TODO determine link speed + return TUSB_SPEED_FULL; +} + +// Close all opened endpoint belong to this device +void hcd_device_close(uint8_t rhport, uint8_t dev_addr) +{ +} + +uint32_t hcd_frame_number(uint8_t rhport) +{ + return 0; +} + +void hcd_int_enable(uint8_t rhport) +{ +} + +void hcd_int_disable(uint8_t rhport) +{ +} + +//--------------------------------------------------------------------+ +// Endpoint API +//--------------------------------------------------------------------+ + +bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) +{ + rhport = RHPORT_PIO(rhport); + + usb_device[0].event = EVENT_NONE; + usb_device[0].address = dev_addr; + + return true; +} + +bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) +{ + (void) rhport; + + return true; +} + +bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) +{ + (void) rhport; + return false; +} + +bool hcd_edpt_control_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8], uint8_t* data) +{ + int ret; + rhport = RHPORT_PIO(rhport); + + uint16_t const len = ((tusb_control_request_t const*) setup_packet)->wLength; + + usb_setup_packet_t pio_setup = { USB_SYNC, USB_PID_DATA0 }; + memcpy(&pio_setup.request_type, setup_packet, 8); + update_packet_crc16(&pio_setup); + + if (setup_packet[0] & TUSB_DIR_IN_MASK) + { + ret = control_in_protocol(&usb_device[0], (uint8_t*) &pio_setup, sizeof(pio_setup), data, len); + }else + { + ret = control_out_protocol(&usb_device[0], (uint8_t*) &pio_setup, sizeof(pio_setup), data, len); + } + + // TODO current pio is blocking + hcd_event_xfer_complete(dev_addr, 0, 0, ret ? XFER_RESULT_FAILED : XFER_RESULT_SUCCESS, false); + + return ret == 0; +} + + +//bool hcd_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) +//{ +// // EPX is shared, so multiple device addresses and endpoint addresses share that +// // so if any transfer is active on epx, we are busy. Interrupt endpoints have their own +// // EPX so ep->active will only be busy if there is a pending transfer on that interrupt endpoint +// // on that device +// pico_trace("hcd_edpt_busy dev addr %d ep_addr 0x%x\n", dev_addr, ep_addr); +// struct hw_endpoint *ep = get_dev_ep(dev_addr, ep_addr); +// assert(ep); +// bool busy = ep->active; +// pico_trace("busy == %d\n", busy); +// return busy; +//} + +bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) +{ + (void) dev_addr; + (void) ep_addr; + + return true; +} + +#endif diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index b6fbdb200..75acefb65 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -27,7 +27,7 @@ #include "tusb_option.h" -#if CFG_TUH_ENABLED && CFG_TUSB_MCU == OPT_MCU_RP2040 +#if CFG_TUH_ENABLED && (CFG_TUSB_MCU == OPT_MCU_RP2040) && !CFG_TUH_RPI_PIO #include "pico.h" #include "rp2040_usb.h" @@ -40,7 +40,8 @@ #include "host/hcd.h" #include "host/usbh.h" -#define ROOT_PORT 0 +// port 0 is native USB port, other is counted as software PIO +#define RHPORT_NATIVE 0 //--------------------------------------------------------------------+ // Low level rp2040 controller functions @@ -185,11 +186,11 @@ static void hcd_rp2040_irq(void) if (dev_speed()) { - hcd_event_device_attach(ROOT_PORT, true); + hcd_event_device_attach(RHPORT_NATIVE, true); } else { - hcd_event_device_remove(ROOT_PORT, true); + hcd_event_device_remove(RHPORT_NATIVE, true); } // Clear speed change interrupt From df4c614597157b540e0936a4555c6a1ba3ac487c Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 2 Mar 2022 00:00:11 +0700 Subject: [PATCH 178/504] update pio usb submodule --- .gitmodules | 3 +++ lib/Pico-PIO-USB | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index fb551060a..9a5d89d00 100644 --- a/.gitmodules +++ b/.gitmodules @@ -140,3 +140,6 @@ [submodule "hw/mcu/allwinner"] path = hw/mcu/allwinner url = https://github.com/hathach/allwinner_driver.git +[submodule "lib/Pico-PIO-USB"] + path = lib/Pico-PIO-USB + url = https://github.com/hathach/Pico-PIO-USB.git diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB index 7d6729900..ee20881ac 160000 --- a/lib/Pico-PIO-USB +++ b/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit 7d672990011695892da523cb0ac29a2c7243a4c9 +Subproject commit ee20881ac8abc515df5e0cfe8851c7c21c47a0ef From d3ed76902eaf52a61f19d88c941045ea1fc5b808 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 2 Mar 2022 00:06:13 +0700 Subject: [PATCH 179/504] clean up --- examples/host/cdc_msc_hid/src/tusb_config.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index abbe474c2..e957b2cde 100644 --- a/examples/host/cdc_msc_hid/src/tusb_config.h +++ b/examples/host/cdc_msc_hid/src/tusb_config.h @@ -39,12 +39,17 @@ #error CFG_TUSB_MCU must be defined #endif +#define CFG_TUH_RPI_PIO 1 +//#define CFG_TUSB_RPI_PIO_INC_PATH 1 + + #if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | OPT_MODE_HIGH_SPEED) +#elif CFG_TUH_RPI_PIO + // rp2040: port0 is native, port 1 for PIO-USB + #define CFG_TUSB_RHPORT1_MODE OPT_MODE_HOST #else - //#define CFG_TUSB_RHPORT0_MODE OPT_MODE_HOST - // rp2040: port0 is native, port 1 for PIO-USB - #define CFG_TUSB_RHPORT1_MODE OPT_MODE_HOST + #define CFG_TUSB_RHPORT0_MODE OPT_MODE_HOST #endif #ifndef CFG_TUSB_OS @@ -73,9 +78,6 @@ // CONFIGURATION //-------------------------------------------------------------------- -#define CFG_TUH_RPI_PIO 1 -//#define CFG_TUSB_RPI_PIO_INC_PATH 1 - // Size of buffer to hold descriptors and other data used for enumeration #define CFG_TUH_ENUMERATION_BUFSIZE 256 From 1b338b288c3e1b91f8b2b77ef3305142188f922e Mon Sep 17 00:00:00 2001 From: caleb crome Date: Tue, 1 Mar 2022 17:24:28 -0800 Subject: [PATCH 180/504] in TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR, _nitfs should be 3. I believe that there is a mistake in the definition of TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR. The nitfs in the audio descriptor is always 3 regardless of ITF_NUM_TOTAL. --- examples/device/uac2_headset/src/usb_descriptors.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/device/uac2_headset/src/usb_descriptors.h b/examples/device/uac2_headset/src/usb_descriptors.h index d9510ea4f..342b4fac1 100644 --- a/examples/device/uac2_headset/src/usb_descriptors.h +++ b/examples/device/uac2_headset/src/usb_descriptors.h @@ -86,7 +86,7 @@ enum #define TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR(_stridx, _epout, _epin) \ /* Standard Interface Association Descriptor (IAD) */\ - TUD_AUDIO_DESC_IAD(/*_firstitfs*/ ITF_NUM_AUDIO_CONTROL, /*_nitfs*/ ITF_NUM_TOTAL, /*_stridx*/ 0x00),\ + TUD_AUDIO_DESC_IAD(/*_firstitfs*/ ITF_NUM_AUDIO_CONTROL, /*_nitfs*/ 3, /*_stridx*/ 0x00),\ /* Standard AC Interface Descriptor(4.7.1) */\ TUD_AUDIO_DESC_STD_AC(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ /* Class-Specific AC Interface Header Descriptor(4.7.2) */\ From 918f3e9caec1e5566feac9214b7142b950a3d27c Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 2 Mar 2022 12:22:20 +0700 Subject: [PATCH 181/504] minor rename --- examples/host/cdc_msc_hid/src/tusb_config.h | 4 ++-- src/host/usbh.c | 2 +- src/portable/raspberrypi/pio/hcd_pio.c | 2 +- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 2 +- src/tusb_option.h | 11 ++++++++--- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index e957b2cde..80ee8cb01 100644 --- a/examples/host/cdc_msc_hid/src/tusb_config.h +++ b/examples/host/cdc_msc_hid/src/tusb_config.h @@ -39,13 +39,13 @@ #error CFG_TUSB_MCU must be defined #endif -#define CFG_TUH_RPI_PIO 1 +#define CFG_TUH_RPI_PIO_USB 1 //#define CFG_TUSB_RPI_PIO_INC_PATH 1 #if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | OPT_MODE_HIGH_SPEED) -#elif CFG_TUH_RPI_PIO +#elif CFG_TUH_RPI_PIO_USB // rp2040: port0 is native, port 1 for PIO-USB #define CFG_TUSB_RHPORT1_MODE OPT_MODE_HOST #else diff --git a/src/host/usbh.c b/src/host/usbh.c index ea0a0809d..1f2a19527 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -779,7 +779,7 @@ static bool enum_get_addr0_device_desc_complete(uint8_t dev_addr, tusb_control_r if (_dev0.hub_addr == 0) { -#if !CFG_TUH_RPI_PIO // skip this reset for pio-usb +#if !CFG_TUH_RPI_PIO_USB // skip this reset for pio-usb // connected directly to roothub hcd_port_reset(_dev0.rhport); osal_task_delay(RESET_DELAY); diff --git a/src/portable/raspberrypi/pio/hcd_pio.c b/src/portable/raspberrypi/pio/hcd_pio.c index 74df49e0d..71645bd45 100644 --- a/src/portable/raspberrypi/pio/hcd_pio.c +++ b/src/portable/raspberrypi/pio/hcd_pio.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if CFG_TUH_ENABLED && (CFG_TUSB_MCU == OPT_MCU_RP2040) && CFG_TUH_RPI_PIO +#if CFG_TUH_ENABLED && (CFG_TUSB_MCU == OPT_MCU_RP2040) && CFG_TUH_RPI_PIO_USB #include "pico.h" #include "hardware/pio.h" diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 75acefb65..53b372fcb 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -27,7 +27,7 @@ #include "tusb_option.h" -#if CFG_TUH_ENABLED && (CFG_TUSB_MCU == OPT_MCU_RP2040) && !CFG_TUH_RPI_PIO +#if CFG_TUH_ENABLED && (CFG_TUSB_MCU == OPT_MCU_RP2040) && !CFG_TUH_RPI_PIO_USB #include "pico.h" #include "rp2040_usb.h" diff --git a/src/tusb_option.h b/src/tusb_option.h index 25e536787..44cdaa3a6 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -252,7 +252,7 @@ //--------------------------------------------------------------------+ -// COMMON OPTIONS +// Common Options (Default) //--------------------------------------------------------------------+ // Debug enable to print out error message @@ -280,7 +280,7 @@ #endif //-------------------------------------------------------------------- -// DEVICE OPTIONS +// Device Options (Default) //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE @@ -345,7 +345,7 @@ #endif //-------------------------------------------------------------------- -// HOST OPTIONS +// Host Options (Default) //-------------------------------------------------------------------- #if CFG_TUH_ENABLED #ifndef CFG_TUH_DEVICE_MAX @@ -383,6 +383,11 @@ #define CFG_TUH_VENDOR 0 #endif +// Enable PIO-USB software host controller +#ifndef CFG_TUH_RPI_PIO_USB +#define CFG_TUH_RPI_PIO_USB 0 +#endif + //------------------------------------------------------------------ // Configuration Validation //------------------------------------------------------------------ From 635fb9dcdd08c736a4b0161381068b51ef4c140e Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 2 Mar 2022 12:33:47 +0700 Subject: [PATCH 182/504] try to fix ci --- src/portable/ehci/ehci.c | 4 ++-- src/portable/mentor/musb/hcd_musb.c | 5 +++++ src/portable/ohci/ohci.c | 5 +++++ src/portable/raspberrypi/rp2040/hcd_rp2040.c | 5 +++++ src/portable/renesas/usba/hcd_usba.c | 5 +++++ 5 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index e2d51dc4b..31e348360 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -160,15 +160,15 @@ void hcd_port_reset(uint8_t rhport) regs->portsc = portsc; } -#if 0 void hcd_port_reset_end(uint8_t rhport) { (void) rhport; +#if 0 ehci_registers_t* regs = ehci_data.regs; regs->portsc_bm.port_reset = 0; -} #endif +} bool hcd_port_connect_status(uint8_t rhport) { diff --git a/src/portable/mentor/musb/hcd_musb.c b/src/portable/mentor/musb/hcd_musb.c index 3bfd65b45..85e18e3aa 100644 --- a/src/portable/mentor/musb/hcd_musb.c +++ b/src/portable/mentor/musb/hcd_musb.c @@ -617,6 +617,11 @@ void hcd_port_reset(uint8_t rhport) _hcd.need_reset = false; } +void hcd_port_reset_end(uint8_t rhport) +{ + (void) rhport; +} + tusb_speed_t hcd_port_speed_get(uint8_t rhport) { (void)rhport; diff --git a/src/portable/ohci/ohci.c b/src/portable/ohci/ohci.c index cb4e6dc4a..db087716f 100644 --- a/src/portable/ohci/ohci.c +++ b/src/portable/ohci/ohci.c @@ -216,6 +216,11 @@ void hcd_port_reset(uint8_t hostid) OHCI_REG->rhport_status[0] = RHPORT_PORT_RESET_STATUS_MASK; } +void hcd_port_reset_end(uint8_t rhport) +{ + (void) rhport; +} + bool hcd_port_connect_status(uint8_t hostid) { (void) hostid; diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 53b372fcb..7bbf00efe 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -387,6 +387,11 @@ void hcd_port_reset(uint8_t rhport) // TODO: Nothing to do here yet. Perhaps need to reset some state? } +void hcd_port_reset_end(uint8_t rhport) +{ + (void) rhport; +} + bool hcd_port_connect_status(uint8_t rhport) { pico_trace("hcd_port_connect_status\n"); diff --git a/src/portable/renesas/usba/hcd_usba.c b/src/portable/renesas/usba/hcd_usba.c index ebb682342..5246ecb94 100644 --- a/src/portable/renesas/usba/hcd_usba.c +++ b/src/portable/renesas/usba/hcd_usba.c @@ -620,6 +620,11 @@ void hcd_port_reset(uint8_t rhport) _hcd.need_reset = false; } +void hcd_port_reset_end(uint8_t rhport) +{ + (void) rhport; +} + tusb_speed_t hcd_port_speed_get(uint8_t rhport) { (void)rhport; From d4d7d35afbfe831b20ba83c2689c678361bfb709 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 2 Mar 2022 13:24:51 +0700 Subject: [PATCH 183/504] checkout pio-usb --- .github/workflows/build_arm.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml index 177f1076e..085274eb5 100644 --- a/.github/workflows/build_arm.yml +++ b/.github/workflows/build_arm.yml @@ -82,6 +82,7 @@ jobs: run: | git clone --depth 1 -b develop https://github.com/raspberrypi/pico-sdk ~/pico-sdk echo >> $GITHUB_ENV PICO_SDK_PATH=~/pico-sdk + git submodule update --init lib/Pico-PIO-USB - name: Set Toolchain URL run: echo >> $GITHUB_ENV TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v10.2.1-1.1/xpack-arm-none-eabi-gcc-10.2.1-1.1-linux-x64.tar.gz From fa62d5abc9b1cede44a8e0630d8a28c90cdcdd00 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 3 Mar 2022 21:57:29 +0700 Subject: [PATCH 184/504] got interrupt endpoint working --- lib/Pico-PIO-USB | 2 +- src/portable/raspberrypi/pio/hcd_pio.c | 41 ++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB index ee20881ac..92268187f 160000 --- a/lib/Pico-PIO-USB +++ b/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit ee20881ac8abc515df5e0cfe8851c7c21c47a0ef +Subproject commit 92268187f3b0490a43d139ed2cb598b06258011f diff --git a/src/portable/raspberrypi/pio/hcd_pio.c b/src/portable/raspberrypi/pio/hcd_pio.c index 71645bd45..8d1903f85 100644 --- a/src/portable/raspberrypi/pio/hcd_pio.c +++ b/src/portable/raspberrypi/pio/hcd_pio.c @@ -167,8 +167,45 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const { rhport = RHPORT_PIO(rhport); - usb_device[0].event = EVENT_NONE; - usb_device[0].address = dev_addr; + usb_device_t *device = &usb_device[0]; + + static uint8_t ep_id_idx; // TODO remove later + + if (ep_desc->bEndpointAddress == 0) + { + device->event = EVENT_NONE; + device->address = dev_addr; + + ep_id_idx = 0; + }else if (ep_desc->bmAttributes.xfer == TUSB_XFER_INTERRUPT) // only support interrupt endpoint + { + endpoint_t *ep = NULL; + for ( int ep_pool_idx = 0; ep_pool_idx < PIO_USB_EP_POOL_CNT; ep_pool_idx++ ) + { + if ( ep_pool[ep_pool_idx].ep_num == 0 ) + { + ep = &ep_pool[ep_pool_idx]; + device->endpoint_id[ep_id_idx] = ep_pool_idx + 1; + ep_id_idx++; + + ep->data_id = 0; + ep->ep_num = ep_desc->bEndpointAddress; + ep->interval = ep_desc->bInterval; + ep->interval_counter = 0; + ep->size = (uint8_t) tu_edpt_packet_size(ep_desc); + ep->attr = EP_ATTR_INTERRUPT; + + break; + } + } + +// TU_LOG1_INT(device->connected); +// TU_LOG1_INT(device->root); +// TU_LOG1_INT(device->is_root); +// TU_LOG1_INT(device->is_fullspeed); +// +// TU_LOG1_INT(ep_id_idx); + } return true; } From 2cd73ca60234748a15b74a2c346778fcb4f4ee61 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 3 Mar 2022 16:53:22 -0800 Subject: [PATCH 185/504] Add host string descriptor functions Plus typo fixes, GCC11 array bounds fix, snprintf for malloc-free debug and pragmas for alignment checks. --- src/common/tusb_common.h | 2 +- src/host/usbh.c | 57 +++++++++++++++++++- src/host/usbh.h | 12 +++++ src/portable/chipidea/ci_hs/hcd_ci_hs.c | 1 + src/portable/ehci/ehci.c | 3 ++ src/portable/ehci/ehci.h | 4 +- src/portable/raspberrypi/rp2040/rp2040_usb.c | 3 ++ 7 files changed, 78 insertions(+), 4 deletions(-) diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 9b9e2b007..80bb40f77 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -349,7 +349,7 @@ static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint3 } // not found return the key value in hex - sprintf(not_found, "0x%08lX", (unsigned long) key); + snprintf(not_found, sizeof(not_found), "0x%08lX", (unsigned long) key); return not_found; } diff --git a/src/host/usbh.c b/src/host/usbh.c index 130aba40e..a3c6c3a04 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -258,6 +258,60 @@ bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t* vid, uint16_t* pid) return true; } +uint8_t tuh_i_manufacturer_get(uint8_t dev_addr) { + TU_VERIFY(tuh_mounted(dev_addr)); + usbh_device_t const* dev = get_device(dev_addr); + + return dev->i_manufacturer; +} + +uint8_t tuh_i_serial_get(uint8_t dev_addr) { + TU_VERIFY(tuh_mounted(dev_addr)); + usbh_device_t const* dev = get_device(dev_addr); + + return dev->i_serial; +} + +uint8_t tuh_i_product_get(uint8_t dev_addr) { + TU_VERIFY(tuh_mounted(dev_addr)); + usbh_device_t const* dev = get_device(dev_addr); + + return dev->i_product; +} + +static tuh_complete_cb_t string_get_cb; + +static bool string_get_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) { + if (string_get_cb != NULL) { + TU_LOG2("string get done %d\r\n", result); + string_get_cb(result); + } + string_get_cb = NULL; + return true; +} + +bool tuh_string_get(uint8_t dev_addr, uint8_t string_index, uint16_t* buf, size_t len, tuh_complete_cb_t complete_cb) { + if (string_get_cb != NULL) { + return false; + } + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_IN + }, + .bRequest = TUSB_REQ_GET_DESCRIPTOR, + .wValue = TUSB_DESC_STRING << 8 | string_index, + .wIndex = 0, + .wLength = len * sizeof(uint16_t) + }; + string_get_cb = complete_cb; + TU_ASSERT( tuh_control_xfer(dev_addr, &request, buf, string_get_complete) ); + return true; +} + tusb_speed_t tuh_speed_get (uint8_t dev_addr) { return (tusb_speed_t) (dev_addr ? get_device(dev_addr)->speed : _dev0.speed); @@ -561,6 +615,7 @@ void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port tu_memclr(dev->ep_status, sizeof(dev->ep_status)); dev->state = TUSB_DEVICE_STATE_UNPLUG; + dev->configured = false; } } } @@ -609,7 +664,7 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) //--------------------------------------------------------------------+ // Enumeration Process -// is a lengthy process with a seires of control transfer to configure +// is a lengthy process with a series of control transfer to configure // newly attached device. Each step is handled by a function in this // section // TODO due to the shared _usbh_ctrl_buf, we must complete enumerating diff --git a/src/host/usbh.h b/src/host/usbh.h index 8411cad28..98e83fc3c 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -38,6 +38,7 @@ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ +typedef bool (*tuh_complete_cb_t)(xfer_result_t result); typedef bool (*tuh_control_complete_cb_t)(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); //--------------------------------------------------------------------+ @@ -58,6 +59,17 @@ extern void hcd_int_handler(uint8_t rhport); #define tuh_int_handler hcd_int_handler bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t* vid, uint16_t* pid); + +// Gets the string indices for common device descriptor data. +uint8_t tuh_i_manufacturer_get(uint8_t dev_addr); +uint8_t tuh_i_serial_get(uint8_t dev_addr); +uint8_t tuh_i_product_get(uint8_t dev_addr); + +// Reads the string descriptor at the string index into the buffer. This is the +// full response so the first entry is the length and the constant 0x03 for +// string descriptor type. +bool tuh_string_get(uint8_t dev_addr, uint8_t string_index, uint16_t* buf, size_t len, tuh_complete_cb_t complete_cb); + tusb_speed_t tuh_speed_get(uint8_t dev_addr); // Check if device is connected and configured diff --git a/src/portable/chipidea/ci_hs/hcd_ci_hs.c b/src/portable/chipidea/ci_hs/hcd_ci_hs.c index 0754b477e..221721b0f 100644 --- a/src/portable/chipidea/ci_hs/hcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/hcd_ci_hs.c @@ -35,6 +35,7 @@ // INCLUDE //--------------------------------------------------------------------+ #include "common/tusb_common.h" +#include "host/hcd.h" #include "portable/ehci/ehci_api.h" #include "ci_hs_type.h" diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index e2d51dc4b..6723e99e9 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -189,7 +189,10 @@ static void list_remove_qhd_by_addr(ehci_link_t* list_head, uint8_t dev_addr) prev = list_next(prev) ) { // TODO check type for ISO iTD and siTD + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-align" ehci_qhd_t* qhd = (ehci_qhd_t*) list_next(prev); + #pragma GCC diagnostic pop if ( qhd->dev_addr == dev_addr ) { // TODO deactive all TD, wait for QHD to inactive before removal diff --git a/src/portable/ehci/ehci.h b/src/portable/ehci/ehci.h index c2bee67a5..ff9ae12e7 100644 --- a/src/portable/ehci/ehci.h +++ b/src/portable/ehci/ehci.h @@ -101,8 +101,8 @@ typedef struct // Word 2: qTQ Token volatile uint32_t ping_err : 1 ; ///< For Highspeed: 0 Out, 1 Ping. Full/Slow used as error indicator - volatile uint32_t non_hs_split_state : 1 ; ///< Used by HC to track the state of slipt transaction - volatile uint32_t non_hs_missed_uframe : 1 ; ///< HC misses a complete slip transaction + volatile uint32_t non_hs_split_state : 1 ; ///< Used by HC to track the state of split transaction + volatile uint32_t non_hs_missed_uframe : 1 ; ///< HC misses a complete split transaction volatile uint32_t xact_err : 1 ; ///< Error (Timeout, CRC, Bad PID ... ) volatile uint32_t babble_err : 1 ; ///< Babble detected, also set Halted bit to 1 volatile uint32_t buffer_err : 1 ; ///< Data overrun/underrun error diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index 293cefaf6..be02493f0 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -58,8 +58,11 @@ void rp2040_usb_init(void) unreset_block_wait(RESETS_RESET_USBCTRL_BITS); // Clear any previous state just in case +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Warray-bounds" memset(usb_hw, 0, sizeof(*usb_hw)); memset(usb_dpram, 0, sizeof(*usb_dpram)); +#pragma GCC diagnostic pop // Mux the controller to the onboard usb phy usb_hw->muxing = USB_USB_MUXING_TO_PHY_BITS | USB_USB_MUXING_SOFTCON_BITS; From eb6b5d1219562e417d879c6d13e0a19eef169ad7 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 3 Mar 2022 21:57:44 -0800 Subject: [PATCH 186/504] Unused ok --- src/host/usbh.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index a3c6c3a04..a61f40910 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -282,8 +282,9 @@ uint8_t tuh_i_product_get(uint8_t dev_addr) { static tuh_complete_cb_t string_get_cb; static bool string_get_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) { + (void) dev_addr; + (void) request; if (string_get_cb != NULL) { - TU_LOG2("string get done %d\r\n", result); string_get_cb(result); } string_get_cb = NULL; From f72da8ee7d7082f9c2f1d796cfb03dcdd1c6d673 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Mar 2022 14:45:26 +0700 Subject: [PATCH 187/504] fix build with esp32s2, also use dwc2 for esp example --- examples/device/hid_composite_freertos/src/CMakeLists.txt | 2 +- src/portable/espressif/esp32sx/dcd_esp32sx.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/device/hid_composite_freertos/src/CMakeLists.txt b/examples/device/hid_composite_freertos/src/CMakeLists.txt index 5d9fc74d3..25da8fcd7 100644 --- a/examples/device/hid_composite_freertos/src/CMakeLists.txt +++ b/examples/device/hid_composite_freertos/src/CMakeLists.txt @@ -31,5 +31,5 @@ target_sources(${COMPONENT_TARGET} PUBLIC "${TOP}/src/class/net/ncm_device.c" "${TOP}/src/class/usbtmc/usbtmc_device.c" "${TOP}/src/class/vendor/vendor_device.c" - "${TOP}/src/portable/espressif/esp32sx/dcd_esp32sx.c" + "${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c" ) diff --git a/src/portable/espressif/esp32sx/dcd_esp32sx.c b/src/portable/espressif/esp32sx/dcd_esp32sx.c index 99cd08e4d..bd8805dd3 100644 --- a/src/portable/espressif/esp32sx/dcd_esp32sx.c +++ b/src/portable/espressif/esp32sx/dcd_esp32sx.c @@ -34,7 +34,6 @@ #include "freertos/xtensa_api.h" #include "esp_intr_alloc.h" #include "esp_log.h" -#include "driver/gpio.h" #include "soc/dport_reg.h" #include "soc/gpio_sig_map.h" #include "soc/usb_periph.h" From c0195fc6270394a489faf29fe8fc42dff48bcff1 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Mar 2022 14:48:29 +0700 Subject: [PATCH 188/504] skip pyocd reset after flash --- examples/rules.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/rules.mk b/examples/rules.mk index 97f6956fa..538dffbcf 100644 --- a/examples/rules.mk +++ b/examples/rules.mk @@ -199,7 +199,7 @@ flash-xfel: $(BUILD)/$(PROJECT)-sunxi.bin PYOCD_OPTION ?= flash-pyocd: $(BUILD)/$(PROJECT).hex pyocd flash -t $(PYOCD_TARGET) $(PYOCD_OPTION) $< - pyocd reset -t $(PYOCD_TARGET) + #pyocd reset -t $(PYOCD_TARGET) # Flash using openocd OPENOCD_OPTION ?= From 96165a1950140c585db4b739709d079228c3320a Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Mar 2022 17:07:04 +0700 Subject: [PATCH 189/504] rename HCD_MAX_XFER to CFG_TUH_ENDPOINT_MAX minor clean up --- src/host/hcd.h | 26 ++++++++++---------- src/host/hub.c | 2 +- src/portable/ehci/ehci.c | 13 ++++++---- src/portable/nxp/khci/hcd_khci.c | 8 +++--- src/portable/ohci/ohci.c | 4 +-- src/portable/ohci/ohci.h | 4 ++- src/portable/raspberrypi/rp2040/rp2040_usb.c | 1 + 7 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/host/hcd.h b/src/host/hcd.h index 80500f048..d50fc2d60 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -35,6 +35,19 @@ extern "C" { #endif +//--------------------------------------------------------------------+ +// Configuration +//--------------------------------------------------------------------+ + +#ifndef CFG_TUH_ENDPOINT_MAX + #define CFG_TUH_ENDPOINT_MAX (CFG_TUH_DEVICE_MAX*(CFG_TUH_HUB + CFG_TUH_HID*2 + CFG_TUH_MSC*2 + CFG_TUH_CDC*3)) +// #ifdef TUP_HCD_ENDPOINT_MAX +// #define CFG_TUH_ENDPPOINT_MAX TUP_HCD_ENDPOINT_MAX +// #else +// #define +// #endif +#endif + //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ @@ -81,17 +94,6 @@ typedef struct } hcd_event_t; -#if CFG_TUH_ENABLED -// Max number of endpoints per device -enum { - // TODO better computation - HCD_MAX_ENDPOINT = CFG_TUH_DEVICE_MAX*(CFG_TUH_HUB + CFG_TUH_HID*2 + CFG_TUH_MSC*2 + CFG_TUH_CDC*3), - HCD_MAX_XFER = HCD_MAX_ENDPOINT*2, -}; - -//#define HCD_MAX_ENDPOINT 16 -//#define HCD_MAX_XFER 16 - typedef struct { uint8_t rhport; uint8_t hub_addr; @@ -99,8 +101,6 @@ typedef struct { uint8_t speed; } hcd_devtree_info_t; -#endif - //--------------------------------------------------------------------+ // Controller API //--------------------------------------------------------------------+ diff --git a/src/host/hub.c b/src/host/hub.c index 53eb1d521..1fec8b892 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -54,7 +54,7 @@ static inline hub_interface_t* get_itf(uint8_t dev_addr) return &hub_data[dev_addr-1-CFG_TUH_DEVICE_MAX]; } -#if CFG_TUSB_DEBUG +#if CFG_TUSB_DEBUG >= 2 static char const* const _hub_feature_str[] = { [HUB_FEATURE_PORT_CONNECTION ] = "PORT_CONNECTION", diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index 6723e99e9..bc0b7b89a 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -58,6 +58,8 @@ #define FRAMELIST_SIZE (1024 >> FRAMELIST_SIZE_BIT_VALUE) +#define HCD_MAX_XFER CFG_TUH_ENDPOINT_MAX + typedef struct { ehci_link_t period_framelist[FRAMELIST_SIZE]; @@ -73,7 +75,7 @@ typedef struct ehci_qtd_t qtd; }control[CFG_TUH_DEVICE_MAX+CFG_TUH_HUB+1]; - ehci_qhd_t qhd_pool[HCD_MAX_ENDPOINT]; + ehci_qhd_t qhd_pool[CFG_TUH_ENDPOINT_MAX]; ehci_qtd_t qtd_pool[HCD_MAX_XFER] TU_ATTR_ALIGNED(32); ehci_registers_t* regs; @@ -189,6 +191,7 @@ static void list_remove_qhd_by_addr(ehci_link_t* list_head, uint8_t dev_addr) prev = list_next(prev) ) { // TODO check type for ISO iTD and siTD + // TODO Suppress cast-align warning #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" ehci_qhd_t* qhd = (ehci_qhd_t*) list_next(prev); @@ -477,7 +480,7 @@ static void async_advance_isr(uint8_t rhport) (void) rhport; ehci_qhd_t* qhd_pool = ehci_data.qhd_pool; - for(uint32_t i = 0; i < HCD_MAX_ENDPOINT; i++) + for(uint32_t i = 0; i < CFG_TUH_ENDPOINT_MAX; i++) { if ( qhd_pool[i].removing ) { @@ -545,7 +548,7 @@ static void period_list_xfer_complete_isr(uint8_t hostid, uint32_t interval_ms) // TODO abstract max loop guard for period while( !next_item.terminate && !(interval_ms > 1 && period_1ms_addr == tu_align32(next_item.address)) && - max_loop < (HCD_MAX_ENDPOINT + EHCI_MAX_ITD + EHCI_MAX_SITD)*CFG_TUH_DEVICE_MAX) + max_loop < (CFG_TUH_ENDPOINT_MAX + EHCI_MAX_ITD + EHCI_MAX_SITD)*CFG_TUH_DEVICE_MAX) { switch ( next_item.type ) { @@ -717,7 +720,7 @@ void hcd_int_handler(uint8_t rhport) //------------- queue head helper -------------// static inline ehci_qhd_t* qhd_find_free (void) { - for (uint32_t i=0; idev_addr == dev_addr) && (p->ep_addr == ep_addr)) return num; @@ -463,7 +463,7 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr) const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn); NVIC_DisableIRQ(USB0_IRQn); pipe_state_t *p = &_hcd.pipe[0]; - pipe_state_t *end = &_hcd.pipe[HCD_MAX_XFER * 2]; + pipe_state_t *end = &_hcd.pipe[CFG_TUH_ENDPOINT_MAX * 2]; for (;p != end; ++p) { if (p->dev_addr == dev_addr) tu_memclr(p, sizeof(*p)); @@ -511,7 +511,7 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const // TU_LOG1("O %u %x\n", dev_addr, ep_addr); /* Find a free pipe */ pipe_state_t *p = &_hcd.pipe[0]; - pipe_state_t *end = &_hcd.pipe[HCD_MAX_XFER * 2]; + pipe_state_t *end = &_hcd.pipe[CFG_TUH_ENDPOINT_MAX * 2]; if (dev_addr || ep_addr) { p += 2; for (; p < end && (p->dev_addr || p->ep_addr); ++p) ; diff --git a/src/portable/ohci/ohci.c b/src/portable/ohci/ohci.c index cb4e6dc4a..c82b9352c 100644 --- a/src/portable/ohci/ohci.c +++ b/src/portable/ohci/ohci.c @@ -313,7 +313,7 @@ static ohci_ed_t * ed_from_addr(uint8_t dev_addr, uint8_t ep_addr) ohci_ed_t* ed_pool = ohci_data.ed_pool; - for(uint32_t i=0; i Date: Fri, 4 Mar 2022 17:16:14 +0700 Subject: [PATCH 190/504] adding new libusb api example --- examples/host/CMakeLists.txt | 1 + examples/host/libusb_api/CMakeLists.txt | 27 ++++++ examples/host/libusb_api/Makefile | 28 +++++++ examples/host/libusb_api/only.txt | 9 ++ examples/host/libusb_api/src/main.c | 98 ++++++++++++++++++++++ examples/host/libusb_api/src/tusb_config.h | 94 +++++++++++++++++++++ 6 files changed, 257 insertions(+) create mode 100644 examples/host/libusb_api/CMakeLists.txt create mode 100644 examples/host/libusb_api/Makefile create mode 100644 examples/host/libusb_api/only.txt create mode 100644 examples/host/libusb_api/src/main.c create mode 100644 examples/host/libusb_api/src/tusb_config.h diff --git a/examples/host/CMakeLists.txt b/examples/host/CMakeLists.txt index 5c63ec0c0..38db6c6cc 100644 --- a/examples/host/CMakeLists.txt +++ b/examples/host/CMakeLists.txt @@ -8,3 +8,4 @@ family_initialize_project(tinyusb_host_examples ${CMAKE_CURRENT_LIST_DIR}) # family_add_subdirectory will filter what to actually add based on selected FAMILY family_add_subdirectory(cdc_msc_hid) family_add_subdirectory(hid_controller) +family_add_subdirectory(libusb_api) diff --git a/examples/host/libusb_api/CMakeLists.txt b/examples/host/libusb_api/CMakeLists.txt new file mode 100644 index 000000000..bff281a8c --- /dev/null +++ b/examples/host/libusb_api/CMakeLists.txt @@ -0,0 +1,27 @@ +cmake_minimum_required(VERSION 3.5) + +include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) + +# gets PROJECT name for the example +family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR}) + +project(${PROJECT}) + +# Checks this example is valid for the family and initializes the project +family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}) + +add_executable(${PROJECT}) + +# Example source +target_sources(${PROJECT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c + ) + +# Example include +target_include_directories(${PROJECT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src + ) + +# Configure compilation flags and libraries for the example... see the corresponding function +# in hw/bsp/FAMILY/family.cmake for details. +family_configure_host_example(${PROJECT}) \ No newline at end of file diff --git a/examples/host/libusb_api/Makefile b/examples/host/libusb_api/Makefile new file mode 100644 index 000000000..c59369ffa --- /dev/null +++ b/examples/host/libusb_api/Makefile @@ -0,0 +1,28 @@ +include ../../../tools/top.mk +include ../../make.mk + +INC += \ + src \ + $(TOP)/hw \ + +# Example source +EXAMPLE_SOURCE += \ + src/main.c + +SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) + +# TODO: suppress warning caused by host stack +CFLAGS += -Wno-error=cast-align -Wno-error=null-dereference + +# TinyUSB Host Stack source +SRC_C += \ + src/class/cdc/cdc_host.c \ + src/class/hid/hid_host.c \ + src/class/msc/msc_host.c \ + src/host/hub.c \ + src/host/usbh.c \ + src/host/usbh_control.c \ + src/portable/ohci/ohci.c \ + src/portable/nxp/lpc17_40/hcd_lpc17_40.c + +include ../../rules.mk diff --git a/examples/host/libusb_api/only.txt b/examples/host/libusb_api/only.txt new file mode 100644 index 000000000..7fe4e3f5c --- /dev/null +++ b/examples/host/libusb_api/only.txt @@ -0,0 +1,9 @@ +mcu:LPC175X_6X +mcu:LPC177X_8X +mcu:LPC18XX +mcu:LPC40XX +mcu:LPC43XX +mcu:MIMXRT10XX +mcu:RP2040 +mcu:MSP432E4 +mcu:RX65X diff --git a/examples/host/libusb_api/src/main.c b/examples/host/libusb_api/src/main.c new file mode 100644 index 000000000..810f8e762 --- /dev/null +++ b/examples/host/libusb_api/src/main.c @@ -0,0 +1,98 @@ +/* + * 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 example current worked and tested with following controller + * - Sony DualShock 4 [CUH-ZCT2x] VID = 0x054c, PID = 0x09cc + */ + + +#include +#include +#include + +#include "bsp/board.h" +#include "tusb.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF PROTYPES +//--------------------------------------------------------------------+ +void led_blinking_task(void); + +extern void cdc_task(void); +extern void hid_app_task(void); + +/*------------- MAIN -------------*/ +int main(void) +{ + board_init(); + + printf("TinyUSB Host HID Controller Example\r\n"); + printf("Note: Events only displayed for explictly supported controllers\r\n"); + + tusb_init(); + + while (1) + { + // tinyusb host task + tuh_task(); + led_blinking_task(); + } + + return 0; +} + +//--------------------------------------------------------------------+ +// TinyUSB Callbacks +//--------------------------------------------------------------------+ + +// Invoked when device is mounted (configured) +void tuh_mount_cb (uint8_t dev_addr) +{ + printf("Device attached, address = %d\r\n", dev_addr); +} + +/// Invoked when device is unmounted (bus reset/unplugged) +void tuh_umount_cb(uint8_t dev_addr) +{ + printf("Device removed, address = %d\r\n", dev_addr); +} + +//--------------------------------------------------------------------+ +// Blinking Task +//--------------------------------------------------------------------+ +void led_blinking_task(void) +{ + const uint32_t interval_ms = 1000; + static uint32_t start_ms = 0; + + static bool led_state = false; + + // Blink every interval ms + if ( board_millis() - start_ms < interval_ms) return; // not enough time + start_ms += interval_ms; + + board_led_write(led_state); + led_state = 1 - led_state; // toggle +} diff --git a/examples/host/libusb_api/src/tusb_config.h b/examples/host/libusb_api/src/tusb_config.h new file mode 100644 index 000000000..234eca402 --- /dev/null +++ b/examples/host/libusb_api/src/tusb_config.h @@ -0,0 +1,94 @@ +/* + * 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 _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +//-------------------------------------------------------------------- +// COMMON CONFIGURATION +//-------------------------------------------------------------------- + +// defined by compiler flags for flexibility +#ifndef CFG_TUSB_MCU + #error CFG_TUSB_MCU must be defined +#endif + +#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | OPT_MODE_HIGH_SPEED) +#else + #define CFG_TUSB_RHPORT0_MODE OPT_MODE_HOST +#endif + +#ifndef CFG_TUSB_OS +#define CFG_TUSB_OS OPT_OS_NONE +#endif + +// CFG_TUSB_DEBUG is defined by compiler in DEBUG build +// #define CFG_TUSB_DEBUG 0 + +/* 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 + +//-------------------------------------------------------------------- +// CONFIGURATION +//-------------------------------------------------------------------- + +// Size of buffer to hold descriptors and other data used for enumeration +#define CFG_TUH_ENUMERATION_BUFSIZE 256 + +// only hub class is enabled +#define CFG_TUH_HUB 1 + +// max device support (excluding hub device) +// 1 hub typically has 4 ports +#define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB ? 4 : 1) + +#define CFG_TUH_ENDPOINT_MAX 8 + +//------------- HID -------------// + +#define CFG_TUH_HID_EP_BUFSIZE 64 + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_CONFIG_H_ */ From 3a7d1cfead0d3147425c305d778723a505900d48 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Mar 2022 17:26:21 +0700 Subject: [PATCH 191/504] minor cleanup --- examples/host/libusb_api/src/main.c | 10 +++++++--- src/host/usbh.c | 13 +++++-------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/examples/host/libusb_api/src/main.c b/examples/host/libusb_api/src/main.c index 810f8e762..07dae1dc6 100644 --- a/examples/host/libusb_api/src/main.c +++ b/examples/host/libusb_api/src/main.c @@ -40,9 +40,6 @@ //--------------------------------------------------------------------+ void led_blinking_task(void); -extern void cdc_task(void); -extern void hid_app_task(void); - /*------------- MAIN -------------*/ int main(void) { @@ -67,10 +64,17 @@ int main(void) // TinyUSB Callbacks //--------------------------------------------------------------------+ +void print_device_descriptor(uint8_t dev_addr) +{ + printf("Device Descriptor:\r\n"); + +} + // Invoked when device is mounted (configured) void tuh_mount_cb (uint8_t dev_addr) { printf("Device attached, address = %d\r\n", dev_addr); + print_device_descriptor(dev_addr); } /// Invoked when device is unmounted (bus reset/unplugged) diff --git a/src/host/usbh.c b/src/host/usbh.c index a61f40910..d655ee7ca 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -37,11 +37,6 @@ // USBH Configuration //--------------------------------------------------------------------+ -// TODO remove,update -#ifndef CFG_TUH_EP_MAX -#define CFG_TUH_EP_MAX 9 -#endif - #ifndef CFG_TUH_TASK_QUEUE_SZ #define CFG_TUH_TASK_QUEUE_SZ 16 #endif @@ -72,7 +67,7 @@ typedef struct } usbh_dev0_t; typedef struct { - // port + // port, must be same layout as usbh_dev0_t uint8_t rhport; uint8_t hub_addr; uint8_t hub_port; @@ -102,7 +97,7 @@ typedef struct { volatile uint8_t state; // device state, value from enum tusbh_device_state_t uint8_t itf2drv[16]; // map interface number to driver (0xff is invalid) - uint8_t ep2drv[CFG_TUH_EP_MAX][2]; // map endpoint to driver ( 0xff is invalid ) + uint8_t ep2drv[CFG_TUH_ENDPOINT_MAX][2]; // map endpoint to driver ( 0xff is invalid ) struct TU_ATTR_PACKED { @@ -111,7 +106,7 @@ typedef struct { volatile bool claimed : 1; // TODO merge ep2drv here, 4-bit should be sufficient - }ep_status[CFG_TUH_EP_MAX][2]; + }ep_status[CFG_TUH_ENDPOINT_MAX][2]; // Mutex for claiming endpoint, only needed when using with preempted RTOS #if CFG_TUSB_OS != OPT_OS_NONE @@ -344,6 +339,8 @@ bool tuh_init(uint8_t rhport) TU_LOG2("USBH init\r\n"); + TU_LOG2_INT(sizeof(usbh_device_t)); + tu_memclr(_usbh_devices, sizeof(_usbh_devices)); tu_memclr(&_dev0, sizeof(_dev0)); From e08a875d52792c03e1e7cd114f0f3f7013c36210 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Mar 2022 19:26:54 +0700 Subject: [PATCH 192/504] add tuh_descriptor_get() and tuh_descriptor_device_get() --- src/common/tusb_common.h | 1 + src/device/usbd.c | 1 + src/host/usbh.c | 64 ++++++++++++++++++++-------------------- src/host/usbh.h | 39 ++++++++++++++---------- 4 files changed, 58 insertions(+), 47 deletions(-) diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 80bb40f77..26865805e 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -38,6 +38,7 @@ #define TU_MIN(_x, _y) ( ( (_x) < (_y) ) ? (_x) : (_y) ) #define TU_MAX(_x, _y) ( ( (_x) > (_y) ) ? (_x) : (_y) ) +#define TU_U16(_high, _low) ((uint16_t) (((_high) << 8) | (_low))) #define TU_U16_HIGH(_u16) ((uint8_t) (((_u16) >> 8) & 0x00ff)) #define TU_U16_LOW(_u16) ((uint8_t) ((_u16) & 0x00ff)) #define U16_TO_U8S_BE(_u16) TU_U16_HIGH(_u16), TU_U16_LOW(_u16) diff --git a/src/device/usbd.c b/src/device/usbd.c index c20bab76b..7926689b7 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -407,6 +407,7 @@ bool tud_init (uint8_t rhport) if ( tud_inited() ) return true; TU_LOG2("USBD init\r\n"); + TU_LOG2_INT(sizeof(usbd_device_t)); tu_varclr(&_usbd_dev); diff --git a/src/host/usbh.c b/src/host/usbh.c index d655ee7ca..4c3bda4b0 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -96,7 +96,7 @@ typedef struct { //------------- device -------------// volatile uint8_t state; // device state, value from enum tusbh_device_state_t - uint8_t itf2drv[16]; // map interface number to driver (0xff is invalid) + uint8_t itf2drv[8]; // map interface number to driver (0xff is invalid) uint8_t ep2drv[CFG_TUH_ENDPOINT_MAX][2]; // map endpoint to driver ( 0xff is invalid ) struct TU_ATTR_PACKED @@ -253,6 +253,34 @@ bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t* vid, uint16_t* pid) return true; } + +bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, + void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +{ + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_IN + }, + .bRequest = TUSB_REQ_GET_DESCRIPTOR, + .wValue = tu_htole16( TU_U16(type, index) ), + .wIndex = 0, + .wLength = len + }; + + TU_ASSERT( tuh_control_xfer(daddr, &request, buffer, complete_cb) ); + + return true; +} + +bool tuh_descriptor_device_get(uint8_t daddr, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +{ + return tuh_descriptor_get(daddr, TUSB_DESC_DEVICE, 0, buffer, len, complete_cb); +} + uint8_t tuh_i_manufacturer_get(uint8_t dev_addr) { TU_VERIFY(tuh_mounted(dev_addr)); usbh_device_t const* dev = get_device(dev_addr); @@ -338,7 +366,6 @@ bool tuh_init(uint8_t rhport) if (_usbh_initialized) return _usbh_initialized; TU_LOG2("USBH init\r\n"); - TU_LOG2_INT(sizeof(usbh_device_t)); tu_memclr(_usbh_devices, sizeof(_usbh_devices)); @@ -785,23 +812,10 @@ static bool enum_request_addr0_device_desc(void) uint8_t const addr0 = 0; TU_ASSERT( usbh_edpt_control_open(addr0, 8) ); - //------------- Get first 8 bytes of device descriptor to get Control Endpoint Size -------------// + // Get first 8 bytes of device descriptor for Control Endpoint size TU_LOG2("Get 8 byte of Device Descriptor\r\n"); - tusb_control_request_t const request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_DEVICE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_IN - }, - .bRequest = TUSB_REQ_GET_DESCRIPTOR, - .wValue = TUSB_DESC_DEVICE << 8, - .wIndex = 0, - .wLength = 8 - }; - TU_ASSERT( tuh_control_xfer(addr0, &request, _usbh_ctrl_buf, enum_get_addr0_device_desc_complete) ); + TU_ASSERT(tuh_descriptor_device_get(addr0, _usbh_ctrl_buf, 8, enum_get_addr0_device_desc_complete)); return true; } @@ -909,22 +923,8 @@ static bool enum_set_address_complete(uint8_t dev_addr, tusb_control_request_t c // Get full device descriptor TU_LOG2("Get Device Descriptor\r\n"); - tusb_control_request_t const new_request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_DEVICE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_IN - }, - .bRequest = TUSB_REQ_GET_DESCRIPTOR, - .wValue = TUSB_DESC_DEVICE << 8, - .wIndex = 0, - .wLength = sizeof(tusb_desc_device_t) - }; - - TU_ASSERT(tuh_control_xfer(new_addr, &new_request, _usbh_ctrl_buf, enum_get_device_desc_complete)); + TU_ASSERT(tuh_descriptor_device_get(new_addr, _usbh_ctrl_buf, sizeof(tusb_desc_device_t), enum_get_device_desc_complete)); return true; } diff --git a/src/host/usbh.h b/src/host/usbh.h index 98e83fc3c..9af139283 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -39,7 +39,7 @@ //--------------------------------------------------------------------+ typedef bool (*tuh_complete_cb_t)(xfer_result_t result); -typedef bool (*tuh_control_complete_cb_t)(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +typedef bool (*tuh_control_complete_cb_t)(uint8_t daddr, tusb_control_request_t const * request, xfer_result_t result); //--------------------------------------------------------------------+ // APPLICATION API @@ -58,40 +58,49 @@ void tuh_task(void); extern void hcd_int_handler(uint8_t rhport); #define tuh_int_handler hcd_int_handler -bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t* vid, uint16_t* pid); +//------------- descriptors -------------// + +// Get an descriptor +bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, + void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); + +// Get device descriptor +bool tuh_descriptor_device_get(uint8_t daddr, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); + +bool tuh_vid_pid_get(uint8_t daddr, uint16_t* vid, uint16_t* pid); // Gets the string indices for common device descriptor data. -uint8_t tuh_i_manufacturer_get(uint8_t dev_addr); -uint8_t tuh_i_serial_get(uint8_t dev_addr); -uint8_t tuh_i_product_get(uint8_t dev_addr); +uint8_t tuh_i_manufacturer_get(uint8_t daddr); +uint8_t tuh_i_serial_get(uint8_t daddr); +uint8_t tuh_i_product_get(uint8_t daddr); // Reads the string descriptor at the string index into the buffer. This is the // full response so the first entry is the length and the constant 0x03 for // string descriptor type. -bool tuh_string_get(uint8_t dev_addr, uint8_t string_index, uint16_t* buf, size_t len, tuh_complete_cb_t complete_cb); +bool tuh_string_get(uint8_t daddr, uint8_t string_index, uint16_t* buf, size_t len, tuh_complete_cb_t complete_cb); -tusb_speed_t tuh_speed_get(uint8_t dev_addr); +tusb_speed_t tuh_speed_get(uint8_t daddr); // Check if device is connected and configured -bool tuh_mounted(uint8_t dev_addr); +bool tuh_mounted(uint8_t daddr); // Check if device is suspended -static inline bool tuh_suspended(uint8_t dev_addr) +static inline bool tuh_suspended(uint8_t daddr) { // TODO implement suspend & resume on host - (void) dev_addr; + (void) daddr; return false; } // Check if device is ready to communicate with TU_ATTR_ALWAYS_INLINE -static inline bool tuh_ready(uint8_t dev_addr) +static inline bool tuh_ready(uint8_t daddr) { - return tuh_mounted(dev_addr) && !tuh_suspended(dev_addr); + return tuh_mounted(daddr) && !tuh_suspended(daddr); } // Carry out control transfer -bool tuh_control_xfer (uint8_t dev_addr, tusb_control_request_t const* request, void* buffer, tuh_control_complete_cb_t complete_cb); +bool tuh_control_xfer (uint8_t daddr, tusb_control_request_t const* request, void* buffer, tuh_control_complete_cb_t complete_cb); //--------------------------------------------------------------------+ // APPLICATION CALLBACK @@ -99,10 +108,10 @@ bool tuh_control_xfer (uint8_t dev_addr, tusb_control_request_t const* request, //TU_ATTR_WEAK uint8_t tuh_attach_cb (tusb_desc_device_t const *desc_device); // Invoked when device is mounted (configured) -TU_ATTR_WEAK void tuh_mount_cb (uint8_t dev_addr); +TU_ATTR_WEAK void tuh_mount_cb (uint8_t daddr); /// Invoked when device is unmounted (bus reset/unplugged) -TU_ATTR_WEAK void tuh_umount_cb(uint8_t dev_addr); +TU_ATTR_WEAK void tuh_umount_cb(uint8_t daddr); #ifdef __cplusplus } From 032e2c292997f4f8fe58239fcca535bb53ed2348 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Mar 2022 19:28:53 +0700 Subject: [PATCH 193/504] add CFG_TUH_INTERFACE_MAX config --- src/host/usbh.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index 4c3bda4b0..7a994e104 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -41,6 +41,10 @@ #define CFG_TUH_TASK_QUEUE_SZ 16 #endif +#ifndef CFG_TUH_INTERFACE_MAX +#define CFG_TUH_INTERFACE_MAX 8 +#endif + // Debug level of USBD #define USBH_DBG_LVL 2 @@ -96,7 +100,7 @@ typedef struct { //------------- device -------------// volatile uint8_t state; // device state, value from enum tusbh_device_state_t - uint8_t itf2drv[8]; // map interface number to driver (0xff is invalid) + uint8_t itf2drv[CFG_TUH_INTERFACE_MAX]; // map interface number to driver (0xff is invalid) uint8_t ep2drv[CFG_TUH_ENDPOINT_MAX][2]; // map endpoint to driver ( 0xff is invalid ) struct TU_ATTR_PACKED @@ -665,7 +669,7 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) { usbh_device_t* dev = get_device(dev_addr); - for(itf_num++; itf_num < sizeof(dev->itf2drv); itf_num++) + for(itf_num++; itf_num < CFG_TUH_INTERFACE_MAX; itf_num++) { // continue with next valid interface // TODO skip IAD binding interface such as CDCs @@ -680,7 +684,7 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) } // all interface are configured - if (itf_num == sizeof(dev->itf2drv)) + if (itf_num == CFG_TUH_INTERFACE_MAX) { // Invoke callback if available if (tuh_mount_cb) tuh_mount_cb(dev_addr); From 7480c2e46b10faa0cbdac5c9db803dbb1597cd34 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Mar 2022 21:04:52 +0700 Subject: [PATCH 194/504] correct qhd and qtd count for ehci/ohci --- src/host/hcd.h | 2 +- src/portable/ehci/ehci.c | 7 ++++--- src/portable/ohci/ohci.c | 6 +++--- src/portable/ohci/ohci.h | 5 +++-- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/host/hcd.h b/src/host/hcd.h index d50fc2d60..9819f5f2a 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -40,7 +40,7 @@ //--------------------------------------------------------------------+ #ifndef CFG_TUH_ENDPOINT_MAX - #define CFG_TUH_ENDPOINT_MAX (CFG_TUH_DEVICE_MAX*(CFG_TUH_HUB + CFG_TUH_HID*2 + CFG_TUH_MSC*2 + CFG_TUH_CDC*3)) + #define CFG_TUH_ENDPOINT_MAX (CFG_TUH_HUB + CFG_TUH_HID*2 + CFG_TUH_MSC*2 + CFG_TUH_CDC*3) // #ifdef TUP_HCD_ENDPOINT_MAX // #define CFG_TUH_ENDPPOINT_MAX TUP_HCD_ENDPOINT_MAX // #else diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index bc0b7b89a..2220474d7 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -58,7 +58,8 @@ #define FRAMELIST_SIZE (1024 >> FRAMELIST_SIZE_BIT_VALUE) -#define HCD_MAX_XFER CFG_TUH_ENDPOINT_MAX +#define QHD_MAX (CFG_TUH_DEVICE_MAX*CFG_TUH_ENDPOINT_MAX) +#define QTD_MAX QHD_MAX typedef struct { @@ -76,7 +77,7 @@ typedef struct }control[CFG_TUH_DEVICE_MAX+CFG_TUH_HUB+1]; ehci_qhd_t qhd_pool[CFG_TUH_ENDPOINT_MAX]; - ehci_qtd_t qtd_pool[HCD_MAX_XFER] TU_ATTR_ALIGNED(32); + ehci_qtd_t qtd_pool[QTD_MAX] TU_ATTR_ALIGNED(32); ehci_registers_t* regs; @@ -752,7 +753,7 @@ static inline ehci_qhd_t* qhd_get_from_addr(uint8_t dev_addr, uint8_t ep_addr) //------------- TD helper -------------// static inline ehci_qtd_t* qtd_find_free(void) { - for (uint32_t i=0; i Date: Fri, 4 Mar 2022 21:14:59 +0700 Subject: [PATCH 195/504] add tuh_descriptor_configuration_get() --- src/host/usbh.c | 45 ++++++++++----------------------------------- src/host/usbh.h | 3 +++ 2 files changed, 13 insertions(+), 35 deletions(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index 7a994e104..96d2cccd3 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -285,6 +285,11 @@ bool tuh_descriptor_device_get(uint8_t daddr, void* buffer, uint16_t len, tuh_co return tuh_descriptor_get(daddr, TUSB_DESC_DEVICE, 0, buffer, len, complete_cb); } +bool tuh_descriptor_configuration_get(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +{ + return tuh_descriptor_get(daddr, TUSB_DESC_CONFIGURATION, index, buffer, len, complete_cb); +} + uint8_t tuh_i_manufacturer_get(uint8_t dev_addr) { TU_VERIFY(tuh_mounted(dev_addr)); usbh_device_t const* dev = get_device(dev_addr); @@ -948,23 +953,9 @@ static bool enum_get_device_desc_complete(uint8_t dev_addr, tusb_control_request // if (tuh_attach_cb) tuh_attach_cb((tusb_desc_device_t*) _usbh_ctrl_buf); - TU_LOG2("Get 9 bytes of Configuration Descriptor\r\n"); - tusb_control_request_t const new_request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_DEVICE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_IN - }, - .bRequest = TUSB_REQ_GET_DESCRIPTOR, - .wValue = (TUSB_DESC_CONFIGURATION << 8) | (CONFIG_NUM - 1), - .wIndex = 0, - .wLength = 9 - }; - - TU_ASSERT( tuh_control_xfer(dev_addr, &new_request, _usbh_ctrl_buf, enum_get_9byte_config_desc_complete) ); - + // Get 9-byte for total length + TU_LOG2("Get Configuration[0] Descriptor (9 bytes)\r\n"); + TU_ASSERT( tuh_descriptor_configuration_get(dev_addr, 0, _usbh_ctrl_buf, 9, enum_get_9byte_config_desc_complete) ); return true; } @@ -982,24 +973,8 @@ static bool enum_get_9byte_config_desc_complete(uint8_t dev_addr, tusb_control_r TU_ASSERT(total_len <= CFG_TUH_ENUMERATION_BUFSIZE); // Get full configuration descriptor - TU_LOG2("Get Configuration Descriptor\r\n"); - tusb_control_request_t const new_request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_DEVICE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_IN - }, - .bRequest = TUSB_REQ_GET_DESCRIPTOR, - .wValue = (TUSB_DESC_CONFIGURATION << 8) | (CONFIG_NUM - 1), - .wIndex = 0, - .wLength = total_len - - }; - - TU_ASSERT( tuh_control_xfer(dev_addr, &new_request, _usbh_ctrl_buf, enum_get_config_desc_complete) ); - + TU_LOG2("Get Configuration[0] Descriptor\r\n"); + TU_ASSERT( tuh_descriptor_configuration_get(dev_addr, 0, _usbh_ctrl_buf, total_len, enum_get_config_desc_complete) ); return true; } diff --git a/src/host/usbh.h b/src/host/usbh.h index 9af139283..6926fce8a 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -67,6 +67,9 @@ bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, // Get device descriptor bool tuh_descriptor_device_get(uint8_t daddr, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); +// Get configuration descriptor +bool tuh_descriptor_configuration_get(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); + bool tuh_vid_pid_get(uint8_t daddr, uint16_t* vid, uint16_t* pid); // Gets the string indices for common device descriptor data. From 15ced09bb2c19663670e2f3a268155b5ecc6e72d Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Mar 2022 21:41:27 +0700 Subject: [PATCH 196/504] add tuh_configuration_set() --- src/host/usbh.c | 116 +++++++++++++++++++++++------------------------- src/host/usbh.h | 52 +++++++++++++--------- 2 files changed, 86 insertions(+), 82 deletions(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index 96d2cccd3..ec607a1b6 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -257,9 +257,26 @@ bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t* vid, uint16_t* pid) return true; } +tusb_speed_t tuh_speed_get (uint8_t dev_addr) +{ + return (tusb_speed_t) (dev_addr ? get_device(dev_addr)->speed : _dev0.speed); +} -bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, - void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +#if CFG_TUSB_OS == OPT_OS_NONE +void osal_task_delay(uint32_t msec) +{ + (void) msec; + + const uint32_t start = hcd_frame_number(TUH_OPT_RHPORT); + while ( ( hcd_frame_number(TUH_OPT_RHPORT) - start ) < msec ) {} +} +#endif + +//--------------------------------------------------------------------+ +// Descriptors +//--------------------------------------------------------------------+ + +bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) { tusb_control_request_t const request = { @@ -272,7 +289,7 @@ bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, .bRequest = TUSB_REQ_GET_DESCRIPTOR, .wValue = tu_htole16( TU_U16(type, index) ), .wIndex = 0, - .wLength = len + .wLength = tu_htole16(len) }; TU_ASSERT( tuh_control_xfer(daddr, &request, buffer, complete_cb) ); @@ -290,6 +307,27 @@ bool tuh_descriptor_configuration_get(uint8_t daddr, uint8_t index, void* buffer return tuh_descriptor_get(daddr, TUSB_DESC_CONFIGURATION, index, buffer, len, complete_cb); } +bool tuh_descriptor_string_get(uint8_t daddr, uint16_t language_id, uint8_t index, + void* buf, uint16_t len, tuh_control_complete_cb_t complete_cb) +{ + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_IN + }, + .bRequest = TUSB_REQ_GET_DESCRIPTOR, + .wValue = tu_htole16( TU_U16(TUSB_DESC_STRING, index) ), + .wIndex = tu_htole16(language_id), + .wLength = tu_htole16(len) + }; + + TU_ASSERT( tuh_control_xfer(daddr, &request, buf, complete_cb) ); + return true; +} + uint8_t tuh_i_manufacturer_get(uint8_t dev_addr) { TU_VERIFY(tuh_mounted(dev_addr)); usbh_device_t const* dev = get_device(dev_addr); @@ -311,55 +349,27 @@ uint8_t tuh_i_product_get(uint8_t dev_addr) { return dev->i_product; } -static tuh_complete_cb_t string_get_cb; - -static bool string_get_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) { - (void) dev_addr; - (void) request; - if (string_get_cb != NULL) { - string_get_cb(result); - } - string_get_cb = NULL; - return true; -} - -bool tuh_string_get(uint8_t dev_addr, uint8_t string_index, uint16_t* buf, size_t len, tuh_complete_cb_t complete_cb) { - if (string_get_cb != NULL) { - return false; - } +bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, tuh_control_complete_cb_t complete_cb) +{ + TU_LOG2("Set Configuration = %d\r\n", config_num); tusb_control_request_t const request = { .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_DEVICE, .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_IN + .direction = TUSB_DIR_OUT }, - .bRequest = TUSB_REQ_GET_DESCRIPTOR, - .wValue = TUSB_DESC_STRING << 8 | string_index, + .bRequest = TUSB_REQ_SET_CONFIGURATION, + .wValue = tu_htole16(config_num), .wIndex = 0, - .wLength = len * sizeof(uint16_t) + .wLength = 0 }; - string_get_cb = complete_cb; - TU_ASSERT( tuh_control_xfer(dev_addr, &request, buf, string_get_complete) ); + + TU_ASSERT( tuh_control_xfer(daddr, &request, NULL, complete_cb) ); return true; } -tusb_speed_t tuh_speed_get (uint8_t dev_addr) -{ - return (tusb_speed_t) (dev_addr ? get_device(dev_addr)->speed : _dev0.speed); -} - -#if CFG_TUSB_OS == OPT_OS_NONE -void osal_task_delay(uint32_t msec) -{ - (void) msec; - - const uint32_t start = hcd_frame_number(TUH_OPT_RHPORT); - while ( ( hcd_frame_number(TUH_OPT_RHPORT) - start ) < msec ) {} -} -#endif - //--------------------------------------------------------------------+ // CLASS-USBD API (don't require to verify parameters) //--------------------------------------------------------------------+ @@ -903,7 +913,7 @@ static bool enum_request_set_addr(void) .direction = TUSB_DIR_OUT }, .bRequest = TUSB_REQ_SET_ADDRESS, - .wValue = new_addr, + .wValue = tu_htole16(new_addr), .wIndex = 0, .wLength = 0 }; @@ -954,8 +964,9 @@ static bool enum_get_device_desc_complete(uint8_t dev_addr, tusb_control_request // if (tuh_attach_cb) tuh_attach_cb((tusb_desc_device_t*) _usbh_ctrl_buf); // Get 9-byte for total length + uint8_t const config_idx = CONFIG_NUM - 1; TU_LOG2("Get Configuration[0] Descriptor (9 bytes)\r\n"); - TU_ASSERT( tuh_descriptor_configuration_get(dev_addr, 0, _usbh_ctrl_buf, 9, enum_get_9byte_config_desc_complete) ); + TU_ASSERT( tuh_descriptor_configuration_get(dev_addr, config_idx, _usbh_ctrl_buf, 9, enum_get_9byte_config_desc_complete) ); return true; } @@ -973,8 +984,9 @@ static bool enum_get_9byte_config_desc_complete(uint8_t dev_addr, tusb_control_r TU_ASSERT(total_len <= CFG_TUH_ENUMERATION_BUFSIZE); // Get full configuration descriptor + uint8_t const config_idx = CONFIG_NUM - 1; TU_LOG2("Get Configuration[0] Descriptor\r\n"); - TU_ASSERT( tuh_descriptor_configuration_get(dev_addr, 0, _usbh_ctrl_buf, total_len, enum_get_config_desc_complete) ); + TU_ASSERT( tuh_descriptor_configuration_get(dev_addr, config_idx, _usbh_ctrl_buf, total_len, enum_get_config_desc_complete) ); return true; } @@ -987,23 +999,7 @@ static bool enum_get_config_desc_complete(uint8_t dev_addr, tusb_control_request // Driver open aren't allowed to make any usb transfer yet TU_ASSERT( parse_configuration_descriptor(dev_addr, (tusb_desc_configuration_t*) _usbh_ctrl_buf) ); - TU_LOG2("Set Configuration = %d\r\n", CONFIG_NUM); - tusb_control_request_t const new_request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_DEVICE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_OUT - }, - .bRequest = TUSB_REQ_SET_CONFIGURATION, - .wValue = CONFIG_NUM, - .wIndex = 0, - .wLength = 0 - }; - - TU_ASSERT( tuh_control_xfer(dev_addr, &new_request, NULL, enum_set_config_complete) ); - + TU_ASSERT( tuh_configuration_set(dev_addr, CONFIG_NUM, enum_set_config_complete) ); return true; } diff --git a/src/host/usbh.h b/src/host/usbh.h index 6926fce8a..a10d6df0e 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -58,36 +58,15 @@ void tuh_task(void); extern void hcd_int_handler(uint8_t rhport); #define tuh_int_handler hcd_int_handler -//------------- descriptors -------------// - -// Get an descriptor -bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, - void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); - -// Get device descriptor -bool tuh_descriptor_device_get(uint8_t daddr, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); - -// Get configuration descriptor -bool tuh_descriptor_configuration_get(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); - bool tuh_vid_pid_get(uint8_t daddr, uint16_t* vid, uint16_t* pid); -// Gets the string indices for common device descriptor data. -uint8_t tuh_i_manufacturer_get(uint8_t daddr); -uint8_t tuh_i_serial_get(uint8_t daddr); -uint8_t tuh_i_product_get(uint8_t daddr); - -// Reads the string descriptor at the string index into the buffer. This is the -// full response so the first entry is the length and the constant 0x03 for -// string descriptor type. -bool tuh_string_get(uint8_t daddr, uint8_t string_index, uint16_t* buf, size_t len, tuh_complete_cb_t complete_cb); - tusb_speed_t tuh_speed_get(uint8_t daddr); // Check if device is connected and configured bool tuh_mounted(uint8_t daddr); // Check if device is suspended +TU_ATTR_ALWAYS_INLINE static inline bool tuh_suspended(uint8_t daddr) { // TODO implement suspend & resume on host @@ -105,6 +84,35 @@ static inline bool tuh_ready(uint8_t daddr) // Carry out control transfer bool tuh_control_xfer (uint8_t daddr, tusb_control_request_t const* request, void* buffer, tuh_control_complete_cb_t complete_cb); +// Set Configuration +// config_num = 0 will un-configure device. Note: config_num = config_descriptor_index + 1 +bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, tuh_control_complete_cb_t complete_cb); + +//------------- descriptors -------------// + +// Get an descriptor +bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, + void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); + +// Get device descriptor +bool tuh_descriptor_device_get(uint8_t daddr, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); + +// Get configuration descriptor +bool tuh_descriptor_configuration_get(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); + +// Get string descriptor +// Reads the string descriptor at the string index into the buffer. This is the +// full response so the first entry is the length and the constant 0x03 for +// string descriptor type. +bool tuh_descriptor_string_get(uint8_t daddr, uint16_t language_id, uint8_t index, + void* buf, uint16_t len, tuh_control_complete_cb_t complete_cb); + + +// Gets the string indices for common device descriptor data. +uint8_t tuh_i_manufacturer_get(uint8_t daddr); +uint8_t tuh_i_serial_get(uint8_t daddr); +uint8_t tuh_i_product_get(uint8_t daddr); + //--------------------------------------------------------------------+ // APPLICATION CALLBACK //--------------------------------------------------------------------+ From 271f905521edfdcfc5649bbe6906f3d3c6d4b10f Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Mar 2022 22:23:56 +0700 Subject: [PATCH 197/504] add tuh_descriptor_string_manufacturer/produce/serial_get --- src/host/usbh.c | 47 +++++++++++++++++++++++++---------------------- src/host/usbh.h | 16 ++++++++-------- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index ec607a1b6..241231c1e 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -86,10 +86,11 @@ typedef struct { }; //------------- device descriptor -------------// + uint8_t ep0_size; + uint16_t vid; uint16_t pid; - uint8_t ep0_size; uint8_t i_manufacturer; uint8_t i_product; uint8_t i_serial; @@ -248,7 +249,6 @@ bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t* vid, uint16_t* pid) *vid = *pid = 0; TU_VERIFY(tuh_mounted(dev_addr)); - usbh_device_t const* dev = get_device(dev_addr); *vid = dev->vid; @@ -308,7 +308,7 @@ bool tuh_descriptor_configuration_get(uint8_t daddr, uint8_t index, void* buffer } bool tuh_descriptor_string_get(uint8_t daddr, uint16_t language_id, uint8_t index, - void* buf, uint16_t len, tuh_control_complete_cb_t complete_cb) + void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) { tusb_control_request_t const request = { @@ -324,29 +324,32 @@ bool tuh_descriptor_string_get(uint8_t daddr, uint16_t language_id, uint8_t inde .wLength = tu_htole16(len) }; - TU_ASSERT( tuh_control_xfer(daddr, &request, buf, complete_cb) ); + TU_ASSERT( tuh_control_xfer(daddr, &request, buffer, complete_cb) ); return true; } -uint8_t tuh_i_manufacturer_get(uint8_t dev_addr) { - TU_VERIFY(tuh_mounted(dev_addr)); - usbh_device_t const* dev = get_device(dev_addr); - - return dev->i_manufacturer; +// Get manufacturer string descriptor +bool tuh_descriptor_string_manufacturer_get(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +{ + TU_VERIFY(tuh_mounted(daddr)); + usbh_device_t const* dev = get_device(daddr); + return tuh_descriptor_string_get(daddr, language_id, dev->i_manufacturer, buffer, len, complete_cb); } -uint8_t tuh_i_serial_get(uint8_t dev_addr) { - TU_VERIFY(tuh_mounted(dev_addr)); - usbh_device_t const* dev = get_device(dev_addr); - - return dev->i_serial; +// Get product string descriptor +bool tuh_descriptor_string_product_get(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +{ + TU_VERIFY(tuh_mounted(daddr)); + usbh_device_t const* dev = get_device(daddr); + return tuh_descriptor_string_get(daddr, language_id, dev->i_product, buffer, len, complete_cb); } -uint8_t tuh_i_product_get(uint8_t dev_addr) { - TU_VERIFY(tuh_mounted(dev_addr)); - usbh_device_t const* dev = get_device(dev_addr); - - return dev->i_product; +// Get serial string descriptor +bool tuh_descriptor_string_serial_get(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +{ + TU_VERIFY(tuh_mounted(daddr)); + usbh_device_t const* dev = get_device(daddr); + return tuh_descriptor_string_get(daddr, language_id, dev->i_serial, buffer, len, complete_cb); } bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, tuh_control_complete_cb_t complete_cb) @@ -957,9 +960,9 @@ static bool enum_get_device_desc_complete(uint8_t dev_addr, tusb_control_request dev->vid = desc_device->idVendor; dev->pid = desc_device->idProduct; - dev->i_manufacturer = desc_device->iManufacturer; - dev->i_product = desc_device->iProduct; - dev->i_serial = desc_device->iSerialNumber; +// dev->i_manufacturer = desc_device->iManufacturer; +// dev->i_product = desc_device->iProduct; +// dev->i_serial = desc_device->iSerialNumber; // if (tuh_attach_cb) tuh_attach_cb((tusb_desc_device_t*) _usbh_ctrl_buf); diff --git a/src/host/usbh.h b/src/host/usbh.h index a10d6df0e..1aef603a0 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -101,17 +101,17 @@ bool tuh_descriptor_device_get(uint8_t daddr, void* buffer, uint16_t len, tuh_co bool tuh_descriptor_configuration_get(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); // Get string descriptor -// Reads the string descriptor at the string index into the buffer. This is the -// full response so the first entry is the length and the constant 0x03 for -// string descriptor type. bool tuh_descriptor_string_get(uint8_t daddr, uint16_t language_id, uint8_t index, - void* buf, uint16_t len, tuh_control_complete_cb_t complete_cb); + void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); +// Get manufacturer string descriptor +bool tuh_descriptor_string_manufacturer_get(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); -// Gets the string indices for common device descriptor data. -uint8_t tuh_i_manufacturer_get(uint8_t daddr); -uint8_t tuh_i_serial_get(uint8_t daddr); -uint8_t tuh_i_product_get(uint8_t daddr); +// Get product string descriptor +bool tuh_descriptor_string_product_get(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); + +// Get serial string descriptor +bool tuh_descriptor_string_serial_get(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); //--------------------------------------------------------------------+ // APPLICATION CALLBACK From b9a6cd8b6163e79d42ba3b56515579f6c1d5f3b2 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Mar 2022 22:25:50 +0700 Subject: [PATCH 198/504] rename example --- examples/host/CMakeLists.txt | 1 - examples/host/{libusb_api => bare_api}/CMakeLists.txt | 0 examples/host/{libusb_api => bare_api}/Makefile | 0 examples/host/{libusb_api => bare_api}/only.txt | 0 examples/host/{libusb_api => bare_api}/src/main.c | 0 examples/host/{libusb_api => bare_api}/src/tusb_config.h | 0 6 files changed, 1 deletion(-) rename examples/host/{libusb_api => bare_api}/CMakeLists.txt (100%) rename examples/host/{libusb_api => bare_api}/Makefile (100%) rename examples/host/{libusb_api => bare_api}/only.txt (100%) rename examples/host/{libusb_api => bare_api}/src/main.c (100%) rename examples/host/{libusb_api => bare_api}/src/tusb_config.h (100%) diff --git a/examples/host/CMakeLists.txt b/examples/host/CMakeLists.txt index 38db6c6cc..5c63ec0c0 100644 --- a/examples/host/CMakeLists.txt +++ b/examples/host/CMakeLists.txt @@ -8,4 +8,3 @@ family_initialize_project(tinyusb_host_examples ${CMAKE_CURRENT_LIST_DIR}) # family_add_subdirectory will filter what to actually add based on selected FAMILY family_add_subdirectory(cdc_msc_hid) family_add_subdirectory(hid_controller) -family_add_subdirectory(libusb_api) diff --git a/examples/host/libusb_api/CMakeLists.txt b/examples/host/bare_api/CMakeLists.txt similarity index 100% rename from examples/host/libusb_api/CMakeLists.txt rename to examples/host/bare_api/CMakeLists.txt diff --git a/examples/host/libusb_api/Makefile b/examples/host/bare_api/Makefile similarity index 100% rename from examples/host/libusb_api/Makefile rename to examples/host/bare_api/Makefile diff --git a/examples/host/libusb_api/only.txt b/examples/host/bare_api/only.txt similarity index 100% rename from examples/host/libusb_api/only.txt rename to examples/host/bare_api/only.txt diff --git a/examples/host/libusb_api/src/main.c b/examples/host/bare_api/src/main.c similarity index 100% rename from examples/host/libusb_api/src/main.c rename to examples/host/bare_api/src/main.c diff --git a/examples/host/libusb_api/src/tusb_config.h b/examples/host/bare_api/src/tusb_config.h similarity index 100% rename from examples/host/libusb_api/src/tusb_config.h rename to examples/host/bare_api/src/tusb_config.h From 56c2d4b666856dedd9ced301d8a273c55ee2afd6 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Mar 2022 22:31:48 +0700 Subject: [PATCH 199/504] fix naming, and build --- examples/host/bare_api/src/main.c | 2 +- src/host/usbh.h | 1 - src/portable/ehci/ehci.c | 10 +++++----- src/portable/ohci/ohci.h | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index 07dae1dc6..b6b1527c0 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -66,8 +66,8 @@ int main(void) void print_device_descriptor(uint8_t dev_addr) { + (void) dev_addr; printf("Device Descriptor:\r\n"); - } // Invoked when device is mounted (configured) diff --git a/src/host/usbh.h b/src/host/usbh.h index 1aef603a0..9465d1d1b 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -38,7 +38,6 @@ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -typedef bool (*tuh_complete_cb_t)(xfer_result_t result); typedef bool (*tuh_control_complete_cb_t)(uint8_t daddr, tusb_control_request_t const * request, xfer_result_t result); //--------------------------------------------------------------------+ diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index 2220474d7..8d420f26a 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -76,7 +76,7 @@ typedef struct ehci_qtd_t qtd; }control[CFG_TUH_DEVICE_MAX+CFG_TUH_HUB+1]; - ehci_qhd_t qhd_pool[CFG_TUH_ENDPOINT_MAX]; + ehci_qhd_t qhd_pool[QHD_MAX]; ehci_qtd_t qtd_pool[QTD_MAX] TU_ATTR_ALIGNED(32); ehci_registers_t* regs; @@ -481,7 +481,7 @@ static void async_advance_isr(uint8_t rhport) (void) rhport; ehci_qhd_t* qhd_pool = ehci_data.qhd_pool; - for(uint32_t i = 0; i < CFG_TUH_ENDPOINT_MAX; i++) + for(uint32_t i = 0; i < QHD_MAX; i++) { if ( qhd_pool[i].removing ) { @@ -549,7 +549,7 @@ static void period_list_xfer_complete_isr(uint8_t hostid, uint32_t interval_ms) // TODO abstract max loop guard for period while( !next_item.terminate && !(interval_ms > 1 && period_1ms_addr == tu_align32(next_item.address)) && - max_loop < (CFG_TUH_ENDPOINT_MAX + EHCI_MAX_ITD + EHCI_MAX_SITD)*CFG_TUH_DEVICE_MAX) + max_loop < (QHD_MAX + EHCI_MAX_ITD + EHCI_MAX_SITD)*CFG_TUH_DEVICE_MAX) { switch ( next_item.type ) { @@ -721,7 +721,7 @@ void hcd_int_handler(uint8_t rhport) //------------- queue head helper -------------// static inline ehci_qhd_t* qhd_find_free (void) { - for (uint32_t i=0; i Date: Fri, 4 Mar 2022 15:35:32 +0000 Subject: [PATCH 200/504] documentatio: fix bad supported dev table format --- docs/reference/supported.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index 7c5402d93..7ce982713 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -42,7 +42,7 @@ Supported MCUs +--------------+---------+-------------+--------+------+-----------+-------------------+--------------+ | NXP | iMXRT | RT10xx | ✔ | ✔ | ✔ | ci_hs | | | +---------+-------------+--------+------+-----------+-------------------+--------------+ -| | Kinetis | KL25 | ✔ | ⚠ | ✖ | | | +| | Kinetis | KL25 | ✔ | ⚠ | ✖ | | | | | +-------------+--------+------+-----------+-------------------+--------------+ | | | K32L2 | ✔ | | ✖ | | | | +---------+-------------+--------+------+-----------+-------------------+--------------+ From f291243121ef35e88c16c47a259213d455c4a401 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 4 Mar 2022 11:38:02 -0800 Subject: [PATCH 201/504] Fix string descriptor fetch --- src/host/usbh.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index 241231c1e..192979ce6 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -333,6 +333,9 @@ bool tuh_descriptor_string_manufacturer_get(uint8_t daddr, uint16_t language_id, { TU_VERIFY(tuh_mounted(daddr)); usbh_device_t const* dev = get_device(daddr); + if (dev->i_manufacturer == 0) { + return false; + } return tuh_descriptor_string_get(daddr, language_id, dev->i_manufacturer, buffer, len, complete_cb); } @@ -341,6 +344,9 @@ bool tuh_descriptor_string_product_get(uint8_t daddr, uint16_t language_id, void { TU_VERIFY(tuh_mounted(daddr)); usbh_device_t const* dev = get_device(daddr); + if (dev->i_product == 0) { + return false; + } return tuh_descriptor_string_get(daddr, language_id, dev->i_product, buffer, len, complete_cb); } @@ -349,6 +355,9 @@ bool tuh_descriptor_string_serial_get(uint8_t daddr, uint16_t language_id, void* { TU_VERIFY(tuh_mounted(daddr)); usbh_device_t const* dev = get_device(daddr); + if (dev->i_serial == 0) { + return false; + } return tuh_descriptor_string_get(daddr, language_id, dev->i_serial, buffer, len, complete_cb); } @@ -960,9 +969,9 @@ static bool enum_get_device_desc_complete(uint8_t dev_addr, tusb_control_request dev->vid = desc_device->idVendor; dev->pid = desc_device->idProduct; -// dev->i_manufacturer = desc_device->iManufacturer; -// dev->i_product = desc_device->iProduct; -// dev->i_serial = desc_device->iSerialNumber; + dev->i_manufacturer = desc_device->iManufacturer; + dev->i_product = desc_device->iProduct; + dev->i_serial = desc_device->iSerialNumber; // if (tuh_attach_cb) tuh_attach_cb((tusb_desc_device_t*) _usbh_ctrl_buf); From 2bef4410f9ca71e60ce4072cca02ca6b544c0caa Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Sat, 5 Mar 2022 17:07:04 +0100 Subject: [PATCH 202/504] Add stm32wb cmsis and hal driver submodules from ST --- .gitmodules | 6 ++++++ hw/mcu/st/cmsis_device_wb | 1 + hw/mcu/st/stm32wbxx_hal_driver | 1 + 3 files changed, 8 insertions(+) create mode 160000 hw/mcu/st/cmsis_device_wb create mode 160000 hw/mcu/st/stm32wbxx_hal_driver diff --git a/.gitmodules b/.gitmodules index fb551060a..21bbf08c0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -97,6 +97,12 @@ [submodule "hw/mcu/st/stm32l5xx_hal_driver"] path = hw/mcu/st/stm32l5xx_hal_driver url = https://github.com/STMicroelectronics/stm32l5xx_hal_driver.git +[submodule "hw/mcu/st/cmsis_device_wb"] + path = hw/mcu/st/cmsis_device_wb + url = https://github.com/STMicroelectronics/cmsis_device_wb.git +[submodule "hw/mcu/st/stm32wbxx_hal_driver"] + path = hw/mcu/st/stm32wbxx_hal_driver + url = https://github.com/STMicroelectronics/stm32wbxx_hal_driver.git [submodule "lib/sct_neopixel"] path = lib/sct_neopixel url = https://github.com/gsteiert/sct_neopixel diff --git a/hw/mcu/st/cmsis_device_wb b/hw/mcu/st/cmsis_device_wb new file mode 160000 index 000000000..9c5d1920d --- /dev/null +++ b/hw/mcu/st/cmsis_device_wb @@ -0,0 +1 @@ +Subproject commit 9c5d1920dd9fabbe2548e10561d63db829bb744f diff --git a/hw/mcu/st/stm32wbxx_hal_driver b/hw/mcu/st/stm32wbxx_hal_driver new file mode 160000 index 000000000..2c5f06638 --- /dev/null +++ b/hw/mcu/st/stm32wbxx_hal_driver @@ -0,0 +1 @@ +Subproject commit 2c5f06638be516c1b772f768456ba637f077bac8 From 65bf5ddb1bfe87719fc612d1eae44087b87e682a Mon Sep 17 00:00:00 2001 From: QianHao <929254256@qq.com> Date: Mon, 7 Mar 2022 08:04:49 +0000 Subject: [PATCH 203/504] Modify the wrong macro definition code --- src/portable/synopsys/dwc2/dwc2_type.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h index dbef20314..7fa2028eb 100644 --- a/src/portable/synopsys/dwc2/dwc2_type.h +++ b/src/portable/synopsys/dwc2/dwc2_type.h @@ -986,16 +986,16 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); /******************** Bit definition for OTG register ********************/ #define GNPTXFSIZ_NPTXFSA_Pos (0U) -#define GNPTXFSIZ_NPTXFSA_Msk (0xFFFFUL << NPTXFSA_Pos) // 0x0000FFFF */ +#define GNPTXFSIZ_NPTXFSA_Msk (0xFFFFUL << GNPTXFSIZ_NPTXFSA_Pos) // 0x0000FFFF */ #define GNPTXFSIZ_NPTXFSA GNPTXFSIZ_NPTXFSA_Msk // Nonperiodic transmit RAM start address */ #define GNPTXFSIZ_NPTXFD_Pos (16U) -#define GNPTXFSIZ_NPTXFD_Msk (0xFFFFUL << NPTXFD_Pos) // 0xFFFF0000 */ +#define GNPTXFSIZ_NPTXFD_Msk (0xFFFFUL << GNPTXFSIZ_NPTXFD_Pos) // 0xFFFF0000 */ #define GNPTXFSIZ_NPTXFD GNPTXFSIZ_NPTXFD_Msk // Nonperiodic TxFIFO depth */ #define DIEPTXF0_TX0FSA_Pos (0U) -#define DIEPTXF0_TX0FSA_Msk (0xFFFFUL << TX0FSA_Pos) // 0x0000FFFF */ +#define DIEPTXF0_TX0FSA_Msk (0xFFFFUL << DIEPTXF0_TX0FSA_Pos) // 0x0000FFFF */ #define DIEPTXF0_TX0FSA DIEPTXF0_TX0FSA_Msk // Endpoint 0 transmit RAM start address */ #define DIEPTXF0_TX0FD_Pos (16U) -#define DIEPTXF0_TX0FD_Msk (0xFFFFUL << TX0FD_Pos) // 0xFFFF0000 */ +#define DIEPTXF0_TX0FD_Msk (0xFFFFUL << DIEPTXF0_TX0FD_Pos) // 0xFFFF0000 */ #define DIEPTXF0_TX0FD DIEPTXF0_TX0FD_Msk // Endpoint 0 TxFIFO depth */ /******************** Bit definition for DVBUSPULSE register ********************/ From a18ac842298d3742dc7044bd0db5c2351a4219a8 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Sat, 5 Mar 2022 17:09:04 +0100 Subject: [PATCH 204/504] Add support for STM32WB mcu --- src/common/tusb_mcu.h | 3 +++ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 10 +++++++++- src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h | 7 +++++++ src/tusb_option.h | 1 + 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 465e33ec7..8eb4ad475 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -184,6 +184,9 @@ #define TUP_DCD_ENDPOINT_MAX 8 #endif +#elif TU_CHECK_MCU(OPT_MCU_STM32WB) +#define TUP_DCD_ENDPOINT_MAX 8 + //------------- Sony -------------// #elif TU_CHECK_MCU(OPT_MCU_CXD56) #define TUP_DCD_ENDPOINT_MAX 7 diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index f201a02cf..4fd189188 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -110,7 +110,7 @@ #endif #if CFG_TUD_ENABLED && \ - ( TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32F3, OPT_MCU_STM32L0, OPT_MCU_STM32L1, OPT_MCU_STM32G4) || \ + ( TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32F3, OPT_MCU_STM32L0, OPT_MCU_STM32L1, OPT_MCU_STM32G4, OPT_MCU_STM32WB) || \ (TU_CHECK_MCU(OPT_MCU_STM32F1) && defined(STM32F1_FSDEV)) \ ) @@ -328,6 +328,10 @@ void dcd_int_enable (uint8_t rhport) NVIC_EnableIRQ(USB_LP_IRQn); NVIC_EnableIRQ(USBWakeUp_IRQn); +#elif CFG_TUSB_MCU == OPT_MCU_STM32WB + NVIC_EnableIRQ(USB_HP_IRQn); + NVIC_EnableIRQ(USB_LP_IRQn); + #else #error Unknown arch in USB driver #endif @@ -370,6 +374,10 @@ void dcd_int_disable(uint8_t rhport) NVIC_DisableIRQ(USB_LP_IRQn); NVIC_DisableIRQ(USBWakeUp_IRQn); +#elif CFG_TUSB_MCU == OPT_MCU_STM32WB + NVIC_DisableIRQ(USB_HP_IRQn); + NVIC_DisableIRQ(USB_LP_IRQn); + #else #error Unknown arch in USB driver #endif diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h index 596f7be6c..bffae4500 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h @@ -91,6 +91,13 @@ #include "stm32g4xx.h" #define PMA_LENGTH (1024u) +#elif CFG_TUSB_MCU == OPT_MCU_STM32WB + #include "stm32wbxx.h" + #define PMA_LENGTH (1024u) + /* ST provided header has incorrect value */ + #undef USB_PMAADDR + #define USB_PMAADDR USB1_PMAADDR + #else #error You are using an untested or unimplemented STM32 variant. Please update the driver. // This includes L1x0, L1x1, L1x2, L4x2 and L4x3, G1x1, G1x3, and G1x4 diff --git a/src/tusb_option.h b/src/tusb_option.h index 25e536787..3f404872a 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -80,6 +80,7 @@ #define OPT_MCU_STM32L4 309 ///< ST L4 #define OPT_MCU_STM32G0 310 ///< ST G0 #define OPT_MCU_STM32G4 311 ///< ST G4 +#define OPT_MCU_STM32WB 312 ///< ST WB // Sony #define OPT_MCU_CXD56 400 ///< SONY CXD56 From 76c8d4d95b78ae479ce21e8780c50c733ac18829 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Sat, 5 Mar 2022 17:12:01 +0100 Subject: [PATCH 205/504] Add support for nucleo-wb55rg --- hw/bsp/stm32wb/boards/stm32wb55nucleo/board.h | 122 ++++++ .../stm32wb/boards/stm32wb55nucleo/board.mk | 9 + .../stm32wb55nucleo/stm32wb55xx_flash_cm4.ld | 171 +++++++++ hw/bsp/stm32wb/family.c | 190 ++++++++++ hw/bsp/stm32wb/family.mk | 44 +++ hw/bsp/stm32wb/stm32wbxx_hal_conf.h | 349 ++++++++++++++++++ 6 files changed, 885 insertions(+) create mode 100644 hw/bsp/stm32wb/boards/stm32wb55nucleo/board.h create mode 100644 hw/bsp/stm32wb/boards/stm32wb55nucleo/board.mk create mode 100644 hw/bsp/stm32wb/boards/stm32wb55nucleo/stm32wb55xx_flash_cm4.ld create mode 100644 hw/bsp/stm32wb/family.c create mode 100644 hw/bsp/stm32wb/family.mk create mode 100644 hw/bsp/stm32wb/stm32wbxx_hal_conf.h diff --git a/hw/bsp/stm32wb/boards/stm32wb55nucleo/board.h b/hw/bsp/stm32wb/boards/stm32wb55nucleo/board.h new file mode 100644 index 000000000..f42c7d6dd --- /dev/null +++ b/hw/bsp/stm32wb/boards/stm32wb55nucleo/board.h @@ -0,0 +1,122 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2022, Jerzy Kasenberg + * + * 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 BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// LED +#define LED_PORT GPIOB +#define LED_PIN GPIO_PIN_5 +#define LED_STATE_ON 1 + +// Button +#define BUTTON_PORT GPIOC +#define BUTTON_PIN GPIO_PIN_4 +#define BUTTON_STATE_ACTIVE 0 + +// UART Enable for STLink VCOM +#define UART_DEV USART1 +#define UART_CLK_EN __HAL_RCC_USART1_CLK_ENABLE +#define UART_GPIO_PORT GPIOB +#define UART_GPIO_AF GPIO_AF7_USART1 +#define UART_TX_PIN GPIO_PIN_6 +#define UART_RX_PIN GPIO_PIN_7 + + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_clock_init(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + + // Initializes the CPU, AHB and APB busses clocks + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48 | RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV4; + RCC_OscInitStruct.PLL.PLLN = 24; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4; + RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV4; + RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV3; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + // Initializes the CPU, AHB and APB busses clocks + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3); + + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB; + PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) ; + +#if 0 // TODO need to check if USB clock is enabled + /* Enable HSI48 */ + memset(&RCC_OscInitStruct, 0, sizeof(RCC_OscInitStruct)); + + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /*Enable CRS Clock*/ + RCC_CRSInitTypeDef RCC_CRSInitStruct= {0}; + __HAL_RCC_CRS_CLK_ENABLE(); + + /* Default Synchro Signal division factor (not divided) */ + RCC_CRSInitStruct.Prescaler = RCC_CRS_SYNC_DIV1; + + /* Set the SYNCSRC[1:0] bits according to CRS_Source value */ + RCC_CRSInitStruct.Source = RCC_CRS_SYNC_SOURCE_USB; + + /* HSI48 is synchronized with USB SOF at 1KHz rate */ + RCC_CRSInitStruct.ReloadValue = __HAL_RCC_CRS_RELOADVALUE_CALCULATE(48000000, 1000); + RCC_CRSInitStruct.ErrorLimitValue = RCC_CRS_ERRORLIMIT_DEFAULT; + + /* Set the TRIM[5:0] to the default value */ + RCC_CRSInitStruct.HSI48CalibrationValue = RCC_CRS_HSI48CALIBRATION_DEFAULT; + + /* Start automatic synchronization */ + HAL_RCCEx_CRSConfig(&RCC_CRSInitStruct); +#endif +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/stm32wb/boards/stm32wb55nucleo/board.mk b/hw/bsp/stm32wb/boards/stm32wb55nucleo/board.mk new file mode 100644 index 000000000..d6adc6b63 --- /dev/null +++ b/hw/bsp/stm32wb/boards/stm32wb55nucleo/board.mk @@ -0,0 +1,9 @@ +CFLAGS += \ + -DSTM32WB55xx + +LD_FILE = $(BOARD_PATH)/stm32wb55xx_flash_cm4.ld + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32wb55xx_cm4.s + +# For flash-jlink target +JLINK_DEVICE = STM32WB55RG diff --git a/hw/bsp/stm32wb/boards/stm32wb55nucleo/stm32wb55xx_flash_cm4.ld b/hw/bsp/stm32wb/boards/stm32wb55nucleo/stm32wb55xx_flash_cm4.ld new file mode 100644 index 000000000..660f30161 --- /dev/null +++ b/hw/bsp/stm32wb/boards/stm32wb55nucleo/stm32wb55xx_flash_cm4.ld @@ -0,0 +1,171 @@ +/** +***************************************************************************** +** +** File : stm32wb55xx_flash_cm4.ld +** +** Abstract : System Workbench Minimal System calls file +** +** For more information about which c-functions +** need which of these lowlevel functions +** please consult the Newlib libc-manual +** +** Environment : System Workbench for MCU +** +** Distribution: The file is distributed “as is,” without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +** Copyright (c) 2019 STMicroelectronics. +** All rights reserved. +** +** This software is licensed under terms that can be found in the LICENSE file +** in the root directory of this software component. +** If no LICENSE file comes with this software, it is provided AS-IS. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20030000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x400; /* required amount of heap */ +_Min_Stack_Size = 0x1000; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K +RAM1 (xrw) : ORIGIN = 0x20000008, LENGTH = 0x2FFF8 +RAM_SHARED (xrw) : ORIGIN = 0x20030000, LENGTH = 10K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM1 AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM1 + + /* 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); + } >RAM1 + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } + MAPPING_TABLE (NOLOAD) : { *(MAPPING_TABLE) } >RAM_SHARED + MB_MEM1 (NOLOAD) : { *(MB_MEM1) } >RAM_SHARED + MB_MEM2 (NOLOAD) : { _sMB_MEM2 = . ; *(MB_MEM2) ; _eMB_MEM2 = . ; } >RAM_SHARED +} + + diff --git a/hw/bsp/stm32wb/family.c b/hw/bsp/stm32wb/family.c new file mode 100644 index 000000000..1ed38308b --- /dev/null +++ b/hw/bsp/stm32wb/family.c @@ -0,0 +1,190 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2022 Jerzy Kasenberg + * + * 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 "stm32wbxx_hal.h" +#include "bsp/board.h" +#include "board.h" + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void USB_HP_IRQHandler(void) +{ + tud_int_handler(0); +} + +void USB_LP_IRQHandler(void) +{ + tud_int_handler(0); +} + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ +UART_HandleTypeDef UartHandle; + +void board_init(void) +{ + board_clock_init(); + + // Enable All GPIOs clocks + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOE_CLK_ENABLE(); + + UART_CLK_EN(); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // Explicitly disable systick to prevent its ISR runs before scheduler start + SysTick->CTRL &= ~1U; + + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(OTG_FS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); +#endif + + GPIO_InitTypeDef GPIO_InitStruct; + + // LED + GPIO_InitStruct.Pin = LED_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct); + +#if 0 + // MCO configuration for System clock value verification PA8 will have SYSCLK / 2 + GPIO_InitStruct.Pin = 8; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF0_MCO; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_2); +#endif + + board_led_write(false); + + // Button + GPIO_InitStruct.Pin = BUTTON_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = BUTTON_STATE_ACTIVE ? GPIO_PULLDOWN : GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); + +#ifdef UART_DEV + // UART + GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = UART_GPIO_AF; + HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); + + UartHandle = (UART_HandleTypeDef){ + .Instance = UART_DEV, + .Init.BaudRate = CFG_BOARD_UART_BAUDRATE, + .Init.WordLength = UART_WORDLENGTH_8B, + .Init.StopBits = UART_STOPBITS_1, + .Init.Parity = UART_PARITY_NONE, + .Init.HwFlowCtl = UART_HWCONTROL_NONE, + .Init.Mode = UART_MODE_TX_RX, + .Init.OverSampling = UART_OVERSAMPLING_16 + }; + HAL_UART_Init(&UartHandle); +#endif + + // USB Pins TODO double check USB clock and pin setup + // Configure USB DM and DP pins. This is optional, and maintained only for user guidance. + GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + HAL_PWREx_EnableVddUSB(); + __HAL_RCC_USB_CLK_ENABLE(); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +} + +uint32_t board_button_read(void) +{ + return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); +} + +int board_uart_read(uint8_t* buf, int len) +{ + (void) buf; (void) len; + return 0; +} + +int board_uart_write(void const * buf, int len) +{ +#ifdef UART_DEV + HAL_UART_Transmit(&UartHandle, (uint8_t*)(uintptr_t) buf, len, 0xffff); + return len; +#else + (void) buf; (void) len; (void) UartHandle; + 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; +} +#endif + +void HardFault_Handler (void) +{ + asm("bkpt"); +} + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void) +{ + +} diff --git a/hw/bsp/stm32wb/family.mk b/hw/bsp/stm32wb/family.mk new file mode 100644 index 000000000..f85c5badd --- /dev/null +++ b/hw/bsp/stm32wb/family.mk @@ -0,0 +1,44 @@ +UF2_FAMILY_ID = 0x70d16653 +ST_FAMILY = wb +DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/st/cmsis_device_$(ST_FAMILY) hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) +ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +include $(TOP)/$(BOARD_PATH)/board.mk + +CFLAGS += \ + -flto \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m4 \ + -mfloat-abi=hard \ + -mfpu=fpv4-sp-d16 \ + -nostdlib -nostartfiles \ + -DCFG_TUSB_MCU=OPT_MCU_STM32WB + +# suppress warning caused by vendor mcu driver +CFLAGS += -Wno-error=cast-align -Wno-unused-parameter + +SRC_C += \ + src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ + $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + $(TOP)/$(ST_CMSIS)/Include \ + $(TOP)/$(ST_HAL_DRIVER)/Inc + +# For freeRTOS port source +FREERTOS_PORT = ARM_CM4F + +# flash target using on-board stlink +flash: flash-stlink diff --git a/hw/bsp/stm32wb/stm32wbxx_hal_conf.h b/hw/bsp/stm32wb/stm32wbxx_hal_conf.h new file mode 100644 index 000000000..754c94ed9 --- /dev/null +++ b/hw/bsp/stm32wb/stm32wbxx_hal_conf.h @@ -0,0 +1,349 @@ +/** + ****************************************************************************** + * @file stm32wbxx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32WBxx_HAL_CONF_H +#define __STM32WBxx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/*#define HAL_ADC_MODULE_ENABLED */ +/*#define HAL_COMP_MODULE_ENABLED */ +/*#define HAL_CRC_MODULE_ENABLED */ +/*#define HAL_HSEM_MODULE_ENABLED */ +/*#define HAL_IPCC_MODULE_ENABLED */ +/*#define HAL_IRDA_MODULE_ENABLED */ +/*#define HAL_LCD_MODULE_ENABLED */ +/*#define HAL_LPTIM_MODULE_ENABLED */ +/*#define HAL_PCD_MODULE_ENABLED */ +/*#define HAL_PKA_MODULE_ENABLED */ +/*#define HAL_QSPI_MODULE_ENABLED */ +#define HAL_RTC_MODULE_ENABLED +/*#define HAL_SAI_MODULE_ENABLED */ +/*#define HAL_SMBUS_MODULE_ENABLED */ +/*#define HAL_SMARTCARD_MODULE_ENABLED */ +/*#define HAL_TSC_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/*#define HAL_USART_MODULE_ENABLED */ +/*#define HAL_WWDG_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_IWDG_MODULE_ENABLED +#define HAL_TIM_MODULE_ENABLED +#define HAL_SPI_MODULE_ENABLED +#define HAL_I2C_MODULE_ENABLED +#define HAL_RNG_MODULE_ENABLED +/*#define HAL_CRYP_MODULE_ENABLED */ + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0u +#define USE_HAL_COMP_REGISTER_CALLBACKS 0u +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0u +#define USE_HAL_I2C_REGISTER_CALLBACKS 0u +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0u +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0u +#define USE_HAL_PCD_REGISTER_CALLBACKS 0u +#define USE_HAL_PKA_REGISTER_CALLBACKS 0u +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0u +#define USE_HAL_RNG_REGISTER_CALLBACKS 0u +#define USE_HAL_RTC_REGISTER_CALLBACKS 0u +#define USE_HAL_SAI_REGISTER_CALLBACKS 0u +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0u +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0u +#define USE_HAL_SPI_REGISTER_CALLBACKS 0u +#define USE_HAL_TIM_REGISTER_CALLBACKS 0u +#define USE_HAL_TSC_REGISTER_CALLBACKS 0u +#define USE_HAL_UART_REGISTER_CALLBACKS 0u +#define USE_HAL_USART_REGISTER_CALLBACKS 0u +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0u + +/* ########################## Oscillator Values adaptation ####################*/ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) +#define HSE_VALUE 32000000U /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT ((uint32_t)100) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal Multiple Speed oscillator (MSI) default value. + * This value is the default MSI range value after Reset. + */ +#if !defined (MSI_VALUE) + #define MSI_VALUE ((uint32_t)4000000) /*!< Value of the Internal oscillator in Hz*/ +#endif /* MSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) +#define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI1) value. + */ +#if !defined (LSI1_VALUE) + #define LSI1_VALUE ((uint32_t)32000) /*!< LSI1 Typical Value in Hz*/ +#endif /* LSI1_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature.*/ +/** + * @brief Internal Low Speed oscillator (LSI2) value. + */ +#if !defined (LSI2_VALUE) + #define LSI2_VALUE ((uint32_t)32000) /*!< LSI2 Typical Value in Hz*/ +#endif /* LSI2_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature.*/ + +/** + * @brief External Low Speed oscillator (LSE) value. + * This value is used by the UART, RTC HAL module to compute the system frequency + */ +#if !defined (LSE_VALUE) +#define LSE_VALUE 32768U /*!< Value of the External oscillator in Hz*/ +#endif /* LSE_VALUE */ + +/** + * @brief Internal Multiple Speed oscillator (HSI48) default value. + * This value is the default HSI48 range value after Reset. + */ +#if !defined (HSI48_VALUE) + #define HSI48_VALUE ((uint32_t)48000000) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI48_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) +#define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for SAI1 peripheral + * This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source + * frequency. + */ +#if !defined (EXTERNAL_SAI1_CLOCK_VALUE) + #define EXTERNAL_SAI1_CLOCK_VALUE ((uint32_t)2097000) /*!< Value of the SAI1 External clock source in Hz*/ +#endif /* EXTERNAL_SAI1_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ + +#define VDD_VALUE 3300U /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY 0U /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1 +#define INSTRUCTION_CACHE_ENABLE 1 +#define DATA_CACHE_ENABLE 1 + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver + * Activated: CRC code is present inside driver + * Deactivated: CRC code cleaned from driver + */ + +#define USE_SPI_CRC 0U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32wbxx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32wbxx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED + #include "stm32wbxx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32wbxx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32wbxx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32wbxx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32wbxx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32wbxx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_HSEM_MODULE_ENABLED + #include "stm32wbxx_hal_hsem.h" +#endif /* HAL_HSEM_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32wbxx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_IPCC_MODULE_ENABLED + #include "stm32wbxx_hal_ipcc.h" +#endif /* HAL_IPCC_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32wbxx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32wbxx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LCD_MODULE_ENABLED + #include "stm32wbxx_hal_lcd.h" +#endif /* HAL_LCD_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32wbxx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32wbxx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_PKA_MODULE_ENABLED + #include "stm32wbxx_hal_pka.h" +#endif /* HAL_PKA_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32wbxx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED + #define USE_HAL_QSPI_REGISTER_CALLBACKS 0U + #include "stm32wbxx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32wbxx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32wbxx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32wbxx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32wbxx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32wbxx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32wbxx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32wbxx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32wbxx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_TSC_MODULE_ENABLED + #include "stm32wbxx_hal_tsc.h" +#endif /* HAL_TSC_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32wbxx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32wbxx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32wbxx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ +#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ +void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32WBxx_HAL_CONF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ From 61615203fde586211854e531a5c6a88da5c8ea4a Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 7 Mar 2022 15:33:27 +0100 Subject: [PATCH 206/504] Add missing releases to Mynewt repository.yml This make it possible to setup Mynewt project with latest releases. --- repository.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/repository.yml b/repository.yml index 21d092373..aaec10eb7 100644 --- a/repository.yml +++ b/repository.yml @@ -9,7 +9,9 @@ repo.versions: "0.10.0": "0.10.0" "0.10.1": "0.10.1" "0.11.0": "0.11.0" + "0.12.0": "0.12.0" + "0.13.0": "0.13.0" "0-dev": "0.0.0" # master - "0-latest": "0.11.0" # latest stable release + "0-latest": "0.13.0" # latest stable release From ce60e98f6da2030f8fe8c8b6c63a7a33019e6c74 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 7 Mar 2022 23:00:11 +0700 Subject: [PATCH 207/504] remove broadcom/synopssy (repalced by synopsys/dwc2) --- src/portable/broadcom/synopsys/dcd_synopsys.c | 1267 -------------- .../broadcom/synopsys/synopsys_common.h | 1476 ----------------- 2 files changed, 2743 deletions(-) delete mode 100644 src/portable/broadcom/synopsys/dcd_synopsys.c delete mode 100644 src/portable/broadcom/synopsys/synopsys_common.h diff --git a/src/portable/broadcom/synopsys/dcd_synopsys.c b/src/portable/broadcom/synopsys/dcd_synopsys.c deleted file mode 100644 index c4881ee50..000000000 --- a/src/portable/broadcom/synopsys/dcd_synopsys.c +++ /dev/null @@ -1,1267 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2018 Scott Shawcroft, 2019 William D. Jones for Adafruit Industries - * Copyright (c) 2019 Ha Thach (tinyusb.org) - * Copyright (c) 2020 Jan Duempelmann - * Copyright (c) 2020 Reinhard Panhuber - * - * 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_BCM2711 ) \ - - -#include "synopsys_common.h" - -#include "broadcom/interrupts.h" - -// Since TinyUSB doesn't use SOF for now, and this interrupt too often (1ms interval) -// We disable SOF for now until needed later on -#define USE_SOF 0 - -// EP_MAX : Max number of bi-directional endpoints including EP0 -// EP_FIFO_SIZE : Size of dedicated USB SRAM -#if CFG_TUSB_MCU == OPT_MCU_BCM2711 -// #include "bcm2711.h" -#define EP_MAX_FS 8 -#define EP_FIFO_SIZE_FS 4096 -#define EP_MAX_HS 8 -#define EP_FIFO_SIZE_HS 4096 -#else -#error "Unsupported MCUs" -#endif - -#define EP_MAX 8 -#define EP_FIFO_SIZE 4096 - -// Info on values here: https://github.com/torvalds/linux/blob/79160a603bdb51916226caf4a6616cc4e1c58a58/Documentation/devicetree/bindings/usb/dwc2.yaml - -// From: https://github.com/raspberrypi/linux/blob/rpi-5.10.y/arch/arm/boot/dts/bcm283x.dtsi -// usb: usb@7e980000 { -// compatible = "brcm,bcm2835-usb"; -// reg = <0x7e980000 0x10000>; -// interrupts = <1 9>; -// #address-cells = <1>; -// #size-cells = <0>; -// clocks = <&clk_usb>; -// clock-names = "otg"; -// phys = <&usbphy>; -// phy-names = "usb2-phy"; -// }; - -// From: https://github.com/raspberrypi/linux/blob/rpi-5.10.y/arch/arm/boot/dts/bcm283x-rpi-usb-otg.dtsi -// SPDX-License-Identifier: GPL-2.0 -// &usb { -// dr_mode = "otg"; -// g-rx-fifo-size = <256>; -// g-np-tx-fifo-size = <32>; - -// * According to dwc2 the sum of all device EP -// * fifo sizes shouldn't exceed 3776 bytes. - -// g-tx-fifo-size = <256 256 512 512 512 768 768>; -// }; - -// From: https://github.com/raspberrypi/linux/blob/rpi-5.10.y/arch/arm/boot/dts/bcm2711-rpi.dtsi -// &usb { -// /* Enable the FIQ support */ -// reg = <0x7e980000 0x10000>, -// <0x7e00b200 0x200>; -// interrupts = , -// ; -// status = "disabled"; -// }; - -// From: https://github.com/raspberrypi/linux/blob/rpi-5.10.y/arch/arm/boot/dts/bcm2711.dtsi -// &usb { -// interrupts = ; -// }; - -// From: https://github.com/torvalds/linux/blob/1d597682d3e669ec7021aa33d088ed3d136a5149/drivers/usb/dwc2/params.c -// static void dwc2_set_bcm_params(struct dwc2_hsotg *hsotg) -// { -// struct dwc2_core_params *p = &hsotg->params; - -// p->host_rx_fifo_size = 774; -// p->max_transfer_size = 65535; -// p->max_packet_count = 511; -// p->ahbcfg = 0x10; -// } - -#include "device/dcd.h" - -TU_VERIFY_STATIC(sizeof(USB_OTG_GlobalTypeDef) == 0x140, "size is incorrect"); - -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM -//--------------------------------------------------------------------+ - -#define RHPORT_REGS_BASE USB_OTG_GLOBAL_BASE - -#define GLOBAL_BASE(_port) ((USB_OTG_GlobalTypeDef*) RHPORT_REGS_BASE) -#define DEVICE_BASE(_port) (USB_OTG_DeviceTypeDef *) (USB_OTG_DEVICE_BASE) -#define OUT_EP_BASE(_port) (USB_OTG_OUTEndpointTypeDef *) (RHPORT_REGS_BASE + USB_OTG_OUT_ENDPOINT_BASE) -#define IN_EP_BASE(_port) (USB_OTG_INEndpointTypeDef *) (RHPORT_REGS_BASE + USB_OTG_IN_ENDPOINT_BASE) -#define FIFO_BASE(_port, _x) ((volatile uint32_t *) (RHPORT_REGS_BASE + USB_OTG_FIFO_BASE + (_x) * USB_OTG_FIFO_SIZE)) - -enum -{ - DCD_HIGH_SPEED = 0, // Highspeed mode - DCD_FULL_SPEED_USE_HS = 1, // Full speed in Highspeed port (probably with internal PHY) - DCD_FULL_SPEED = 3, // Full speed with internal PHY -}; - -static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[2]; - -typedef struct { - uint8_t * buffer; - tu_fifo_t * ff; - uint16_t total_len; - uint16_t max_size; - uint8_t interval; -} xfer_ctl_t; - -typedef volatile uint32_t * usb_fifo_t; - -xfer_ctl_t xfer_status[EP_MAX][2]; -#define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir] - -// EP0 transfers are limited to 1 packet - larger sizes has to be split -static uint16_t ep0_pending[2]; // Index determines direction as tusb_dir_t type - -// TX FIFO RAM allocation so far in words - RX FIFO size is readily available from usb_otg->GRXFSIZ -static uint16_t _allocated_fifo_words_tx; // TX FIFO size in words (IN EPs) -static bool _out_ep_closed; // Flag to check if RX FIFO size needs an update (reduce its size) - -// Calculate the RX FIFO size according to recommendations from reference manual -static inline uint16_t calc_rx_ff_size(uint16_t ep_size) -{ - return 15 + 2*(ep_size/4) + 2*EP_MAX; -} - -static void update_grxfsiz(uint8_t rhport) -{ - (void) rhport; - - USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); - - // Determine largest EP size for RX FIFO - uint16_t max_epsize = 0; - for (uint8_t epnum = 0; epnum < EP_MAX; epnum++) - { - max_epsize = tu_max16(max_epsize, xfer_status[epnum][TUSB_DIR_OUT].max_size); - } - - // Update size of RX FIFO - usb_otg->GRXFSIZ = calc_rx_ff_size(max_epsize); -} - -// Setup the control endpoint 0. -static void bus_reset(uint8_t rhport) -{ - (void) rhport; - - USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); - USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); - - tu_memclr(xfer_status, sizeof(xfer_status)); - _out_ep_closed = false; - - // clear device address - dev->DCFG &= ~USB_OTG_DCFG_DAD_Msk; - - // 1. NAK for all OUT endpoints - for(uint8_t n = 0; n < EP_MAX; n++) { - out_ep[n].DOEPCTL |= USB_OTG_DOEPCTL_SNAK; - } - - // 2. Un-mask interrupt bits - dev->DAINTMSK = (1 << USB_OTG_DAINTMSK_OEPM_Pos) | (1 << USB_OTG_DAINTMSK_IEPM_Pos); - dev->DOEPMSK = USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM; - dev->DIEPMSK = USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM; - - // "USB Data FIFOs" section in reference manual - // Peripheral FIFO architecture - // - // The FIFO is split up in a lower part where the RX FIFO is located and an upper part where the TX FIFOs start. - // We do this to allow the RX FIFO to grow dynamically which is possible since the free space is located - // between the RX and TX FIFOs. This is required by ISO OUT EPs which need a bigger FIFO than the standard - // configuration done below. - // - // Dynamically FIFO sizes are of interest only for ISO EPs since all others are usually not opened and closed. - // All EPs other than ISO are opened as soon as the driver starts up i.e. when the host sends a - // configure interface command. Hence, all IN EPs other the ISO will be located at the top. IN ISO EPs are usually - // opened when the host sends an additional command: setInterface. At this point in time - // the ISO EP will be located next to the free space and can change its size. In case more IN EPs change its size - // an additional memory - // - // --------------- 320 or 1024 ( 1280 or 4096 bytes ) - // | IN FIFO 0 | - // --------------- (320 or 1024) - 16 - // | IN FIFO 1 | - // --------------- (320 or 1024) - 16 - x - // | . . . . | - // --------------- (320 or 1024) - 16 - x - y - ... - z - // | IN FIFO MAX | - // --------------- - // | FREE | - // --------------- GRXFSIZ - // | OUT FIFO | - // | ( Shared ) | - // --------------- 0 - // - // According to "FIFO RAM allocation" section in RM, FIFO RAM are allocated as follows (each word 32-bits): - // - Each EP IN needs at least max packet size, 16 words is sufficient for EP0 IN - // - // - All EP OUT shared a unique OUT FIFO which uses - // - 13 for setup packets + control words (up to 3 setup packets). - // - 1 for global NAK (not required/used here). - // - Largest-EPsize / 4 + 1. ( FS: 64 bytes, HS: 512 bytes). Recommended is "2 x (Largest-EPsize/4) + 1" - // - 2 for each used OUT endpoint - // - // Therefore GRXFSIZ = 13 + 1 + 1 + 2 x (Largest-EPsize/4) + 2 x EPOUTnum - // - FullSpeed (64 Bytes ): GRXFSIZ = 15 + 2 x 16 + 2 x EP_MAX = 47 + 2 x EP_MAX - // - Highspeed (512 bytes): GRXFSIZ = 15 + 2 x 128 + 2 x EP_MAX = 271 + 2 x EP_MAX - // - // NOTE: Largest-EPsize & EPOUTnum is actual used endpoints in configuration. Since DCD has no knowledge - // of the overall picture yet. We will use the worst scenario: largest possible + EP_MAX - // - // For Isochronous, largest EP size can be 1023/1024 for FS/HS respectively. In addition if multiple ISO - // are enabled at least "2 x (Largest-EPsize/4) + 1" are recommended. Maybe provide a macro for application to - // overwrite this. - - #if TUD_OPT_HIGH_SPEED - usb_otg->GRXFSIZ = calc_rx_ff_size(512); - #else - usb_otg->GRXFSIZ = calc_rx_ff_size(64); - #endif - - _allocated_fifo_words_tx = 16; - - // Control IN uses FIFO 0 with 64 bytes ( 16 32-bit word ) - usb_otg->DIEPTXF0_HNPTXFSIZ = (16 << USB_OTG_TX0FD_Pos) | (EP_FIFO_SIZE/4 - _allocated_fifo_words_tx); - - // Fixed control EP0 size to 64 bytes - in_ep[0].DIEPCTL &= ~(0x03 << USB_OTG_DIEPCTL_MPSIZ_Pos); - xfer_status[0][TUSB_DIR_OUT].max_size = xfer_status[0][TUSB_DIR_IN].max_size = 64; - - out_ep[0].DOEPTSIZ |= (3 << USB_OTG_DOEPTSIZ_STUPCNT_Pos); - - usb_otg->GINTMSK |= USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT; -} - -// Set turn-around timeout according to link speed -extern uint32_t SystemCoreClock; -static void set_turnaround(USB_OTG_GlobalTypeDef * usb_otg, tusb_speed_t speed) -{ - usb_otg->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT; - - if ( speed == TUSB_SPEED_HIGH ) - { - // Use fixed 0x09 for Highspeed - usb_otg->GUSBCFG |= (0x09 << USB_OTG_GUSBCFG_TRDT_Pos); - } - else - { - // Turnaround timeout depends on the MCU clock - uint32_t turnaround; - - if ( SystemCoreClock >= 32000000U ) - turnaround = 0x6U; - else if ( SystemCoreClock >= 27500000U ) - turnaround = 0x7U; - else if ( SystemCoreClock >= 24000000U ) - turnaround = 0x8U; - else if ( SystemCoreClock >= 21800000U ) - turnaround = 0x9U; - else if ( SystemCoreClock >= 20000000U ) - turnaround = 0xAU; - else if ( SystemCoreClock >= 18500000U ) - turnaround = 0xBU; - else if ( SystemCoreClock >= 17200000U ) - turnaround = 0xCU; - else if ( SystemCoreClock >= 16000000U ) - turnaround = 0xDU; - else if ( SystemCoreClock >= 15000000U ) - turnaround = 0xEU; - else - turnaround = 0xFU; - - // Fullspeed depends on MCU clocks, but we will use 0x06 for 32+ Mhz - usb_otg->GUSBCFG |= (turnaround << USB_OTG_GUSBCFG_TRDT_Pos); - } -} - -static tusb_speed_t get_speed(uint8_t rhport) -{ - (void) rhport; - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - uint32_t const enum_spd = (dev->DSTS & USB_OTG_DSTS_ENUMSPD_Msk) >> USB_OTG_DSTS_ENUMSPD_Pos; - return (enum_spd == DCD_HIGH_SPEED) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL; -} - -static void set_speed(uint8_t rhport, tusb_speed_t speed) -{ - uint32_t bitvalue; - - if ( rhport == 1 ) - { - bitvalue = ((TUSB_SPEED_HIGH == speed) ? DCD_HIGH_SPEED : DCD_FULL_SPEED_USE_HS); - } - else - { - bitvalue = DCD_FULL_SPEED; - } - - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - - // Clear and set speed bits - dev->DCFG &= ~(3 << USB_OTG_DCFG_DSPD_Pos); - dev->DCFG |= (bitvalue << USB_OTG_DCFG_DSPD_Pos); -} - -#if 0 -// From CM4IO xtal to usb hub, may not be correct -#define HSE_VALUE 24000000 - -static bool USB_HS_PHYCInit(void) -{ - USB_HS_PHYC_GlobalTypeDef *usb_hs_phyc = (USB_HS_PHYC_GlobalTypeDef*) USB_HS_PHYC_CONTROLLER_BASE; - - // Enable LDO - usb_hs_phyc->USB_HS_PHYC_LDO |= USB_HS_PHYC_LDO_ENABLE; - - // Wait until LDO ready - while ( 0 == (usb_hs_phyc->USB_HS_PHYC_LDO & USB_HS_PHYC_LDO_STATUS) ) {} - - uint32_t phyc_pll = 0; - - // TODO Try to get HSE_VALUE from registers instead of depending CFLAGS - switch ( HSE_VALUE ) - { - case 12000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12MHZ ; break; - case 12500000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12_5MHZ ; break; - case 16000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_16MHZ ; break; - case 24000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_24MHZ ; break; - case 25000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_25MHZ ; break; - case 32000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_Msk ; break; // Value not defined in header - default: - TU_ASSERT(0); - } - usb_hs_phyc->USB_HS_PHYC_PLL = phyc_pll; - - // Control the tuning interface of the High Speed PHY - // Use magic value (USB_HS_PHYC_TUNE_VALUE) from ST driver - usb_hs_phyc->USB_HS_PHYC_TUNE |= 0x00000F13U; - - // Enable PLL internal PHY - usb_hs_phyc->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL_PLLEN; - - // Original ST code has 2 ms delay for PLL stabilization. - // Primitive test shows that more than 10 USB un/replug cycle showed no error with enumeration - - return true; -} -#endif - -static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t const dir, uint16_t const num_packets, uint16_t total_bytes) -{ - (void) rhport; - - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); - USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); - - // EP0 is limited to one packet each xfer - // We use multiple transaction of xfer->max_size length to get a whole transfer done - if(epnum == 0) { - xfer_ctl_t * const xfer = XFER_CTL_BASE(epnum, dir); - total_bytes = tu_min16(ep0_pending[dir], xfer->max_size); - ep0_pending[dir] -= total_bytes; - } - - // IN and OUT endpoint xfers are interrupt-driven, we just schedule them here. - if(dir == TUSB_DIR_IN) { - // A full IN transfer (multiple packets, possibly) triggers XFRC. - in_ep[epnum].DIEPTSIZ = (num_packets << USB_OTG_DIEPTSIZ_PKTCNT_Pos) | - ((total_bytes << USB_OTG_DIEPTSIZ_XFRSIZ_Pos) & USB_OTG_DIEPTSIZ_XFRSIZ_Msk); - - in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_EPENA | USB_OTG_DIEPCTL_CNAK; - // For ISO endpoint set correct odd/even bit for next frame. - if ((in_ep[epnum].DIEPCTL & USB_OTG_DIEPCTL_EPTYP) == USB_OTG_DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) - { - // Take odd/even bit from frame counter. - uint32_t const odd_frame_now = (dev->DSTS & (1u << USB_OTG_DSTS_FNSOF_Pos)); - in_ep[epnum].DIEPCTL |= (odd_frame_now ? USB_OTG_DIEPCTL_SD0PID_SEVNFRM_Msk : USB_OTG_DIEPCTL_SODDFRM_Msk); - } - // Enable fifo empty interrupt only if there are something to put in the fifo. - if(total_bytes != 0) { - dev->DIEPEMPMSK |= (1 << epnum); - } - } else { - // A full OUT transfer (multiple packets, possibly) triggers XFRC. - out_ep[epnum].DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT_Msk | USB_OTG_DOEPTSIZ_XFRSIZ); - out_ep[epnum].DOEPTSIZ |= (num_packets << USB_OTG_DOEPTSIZ_PKTCNT_Pos) | - ((total_bytes << USB_OTG_DOEPTSIZ_XFRSIZ_Pos) & USB_OTG_DOEPTSIZ_XFRSIZ_Msk); - - out_ep[epnum].DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK; - if ((out_ep[epnum].DOEPCTL & USB_OTG_DOEPCTL_EPTYP) == USB_OTG_DOEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) - { - // Take odd/even bit from frame counter. - uint32_t const odd_frame_now = (dev->DSTS & (1u << USB_OTG_DSTS_FNSOF_Pos)); - out_ep[epnum].DOEPCTL |= (odd_frame_now ? USB_OTG_DOEPCTL_SD0PID_SEVNFRM_Msk : USB_OTG_DOEPCTL_SODDFRM_Msk); - } - } -} - -/*------------------------------------------------------------------*/ -/* Controller API - *------------------------------------------------------------------*/ - -TU_ATTR_UNUSED -static void reset_core(USB_OTG_GlobalTypeDef * usb_otg) { - while ((usb_otg->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0) {} - - TU_LOG(2, " resetting\r\n"); - usb_otg->GRSTCTL |= USB_OTG_GRSTCTL_CSRST; - TU_LOG(2, " waiting\r\n"); - while ((usb_otg->GRSTCTL & (USB_OTG_GRSTCTL_AHBIDL | USB_OTG_GRSTCTL_CSRST)) != USB_OTG_GRSTCTL_AHBIDL) {} - TU_LOG(2, " reset done\r\n"); -} - -void dcd_init (uint8_t rhport) -{ - printf("test done\r\n"); - // Programming model begins in the last section of the chapter on the USB - // peripheral in each Reference Manual. - TU_LOG(2, " dcd_init\r\n"); - - TU_LOG2("Test 123\r\n"); - - USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); - -#if 1 - // No VBUS sense - usb_otg->GCCFG &= ~(1UL << 21); // USB_OTG_GCCFG_VBDEN - - // B-peripheral session valid override enable - usb_otg->GOTGCTL |= (1UL << 6); // USB_OTG_GOTGCTL_BVALOEN - usb_otg->GOTGCTL |= (1UL << 7); // USB_OTG_GOTGCTL_BVALOVAL - - // Force device mode - usb_otg->GUSBCFG &= ~USB_OTG_GUSBCFG_FHMOD; - usb_otg->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD; - - // deactivate internal PHY - usb_otg->GCCFG &= ~USB_OTG_GCCFG_PWRDWN; - - // Init The UTMI Interface - usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL); - - // Select default internal VBUS Indicator and Drive for ULPI - usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI); - - // Select UTMI Interface - usb_otg->GUSBCFG &= ~(1UL << 4); // USB_OTG_GUSBCFG_ULPI_UTMI_SEL - usb_otg->GCCFG |= (1UL << 32); // USB_OTG_GCCFG_PHYHSEN - - // Enables control of a High Speed USB PHY - //USB_HS_PHYCInit(); - - // Reset core after selecting PHY - // Wait AHB IDLE, reset then wait until it is cleared -// while ((usb_otg->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U) {} -// usb_otg->GRSTCTL |= USB_OTG_GRSTCTL_CSRST; -// while ((usb_otg->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST) {} - - reset_core(usb_otg); - - // Restart PHY clock - *((volatile uint32_t *)(RHPORT_REGS_BASE + USB_OTG_PCGCCTL_BASE)) = 0; - -#else - - // ReadBackReg(&Core->Usb); - // Core->Usb.UlpiDriveExternalVbus = 0; - // Core->Usb.TsDlinePulseEnable = 0; - // WriteThroughReg(&Core->Usb); - - // This sequence is modeled after: https://github.com/Chadderz121/csud/blob/e13b9355d043a9cdd384b335060f1bc0416df61e/source/hcd/dwc/designware20.c#L689 - usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIEVBUSD); - reset_core(usb_otg); - - // Core->Usb.ModeSelect = UTMI; - // LOG_DEBUG("HCD: Interface: UTMI+.\n"); - // Core->Usb.PhyInterface = false; - - // HcdReset(); - TU_LOG2("init phy\r\n"); - usb_otg->GUSBCFG |= (1 << 4); // bit four sets UTMI+ mode - usb_otg->GUSBCFG &= ~(1 << 3); // bit three disables phy interface - reset_core(usb_otg); - - // LOG_DEBUG("HCD: ULPI FSLS configuration: disabled.\n"); - // Core->Usb.UlpiFsls = false; - // Core->Usb.ulpi_clk_sus_m = false; - usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_ULPICSM); - - // LOG_DEBUG("HCD: DMA configuration: enabled.\n"); - // Core->Ahb.DmaEnable = true; - // Core->Ahb.DmaRemainderMode = Incremental; - usb_otg->GAHBCFG &= ~(1 << 23); // Remainder mode - usb_otg->GAHBCFG |= USB_OTG_GAHBCFG_DMAEN; - - // LOG_DEBUG("HCD: HNP/SRP configuration: HNP, SRP.\n"); - // Core->Usb.HnpCapable = true; - // Core->Usb.SrpCapable = true; - usb_otg->GUSBCFG |= USB_OTG_GUSBCFG_SRPCAP | USB_OTG_GUSBCFG_HNPCAP; - -#endif - - // Clear all interrupts - usb_otg->GINTSTS |= usb_otg->GINTSTS; - - // Required as part of core initialization. - // TODO: How should mode mismatch be handled? It will cause - // the core to stop working/require reset. - usb_otg->GINTMSK |= USB_OTG_GINTMSK_OTGINT | USB_OTG_GINTMSK_MMISM; - - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - - // If USB host misbehaves during status portion of control xfer - // (non zero-length packet), send STALL back and discard. - dev->DCFG |= USB_OTG_DCFG_NZLSOHSK; - - set_speed(rhport, TUSB_SPEED_HIGH); - - // TODO internal phy (full speed) - usb_otg->GCCFG |= USB_OTG_GCCFG_PWRDWN; - - usb_otg->GINTMSK |= USB_OTG_GINTMSK_USBRST | USB_OTG_GINTMSK_ENUMDNEM | - USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_WUIM | - USB_OTG_GINTMSK_RXFLVLM | (USE_SOF ? USB_OTG_GINTMSK_SOFM : 0); - - // Enable global interrupt - usb_otg->GAHBCFG |= USB_OTG_GAHBCFG_GINT; - - dcd_connect(rhport); -} - -void dcd_int_enable (uint8_t rhport) -{ - (void) rhport; - BP_EnableIRQ(USB_IRQn); -} - -void dcd_int_disable (uint8_t rhport) -{ - (void) rhport; - BP_DisableIRQ(USB_IRQn); -} - -void dcd_set_address (uint8_t rhport, uint8_t dev_addr) -{ - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - dev->DCFG = (dev->DCFG & ~USB_OTG_DCFG_DAD_Msk) | (dev_addr << USB_OTG_DCFG_DAD_Pos); - - // Response with status after changing device address - dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); -} - -static void remote_wakeup_delay(void) -{ - // try to delay for 1 ms - uint32_t count = SystemCoreClock / 1000; - while ( count-- ) - { - // __NOP(); - } -} - -void dcd_remote_wakeup(uint8_t rhport) -{ - (void) rhport; - - USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - - // set remote wakeup - dev->DCTL |= USB_OTG_DCTL_RWUSIG; - - // enable SOF to detect bus resume - usb_otg->GINTSTS = USB_OTG_GINTSTS_SOF; - usb_otg->GINTMSK |= USB_OTG_GINTMSK_SOFM; - - // Per specs: remote wakeup signal bit must be clear within 1-15ms - remote_wakeup_delay(); - - dev->DCTL &= ~USB_OTG_DCTL_RWUSIG; -} - -void dcd_connect(uint8_t rhport) -{ - (void) rhport; - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - dev->DCTL &= ~USB_OTG_DCTL_SDIS; -} - -void dcd_disconnect(uint8_t rhport) -{ - (void) rhport; - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - dev->DCTL |= USB_OTG_DCTL_SDIS; -} - - -/*------------------------------------------------------------------*/ -/* DCD Endpoint port - *------------------------------------------------------------------*/ - -bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) -{ - (void) rhport; - - USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); - USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); - - uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); - uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); - - TU_ASSERT(epnum < EP_MAX); - - xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); - xfer->max_size = tu_edpt_packet_size(desc_edpt); - xfer->interval = desc_edpt->bInterval; - - uint16_t const fifo_size = (xfer->max_size + 3) / 4; // Round up to next full word - - if(dir == TUSB_DIR_OUT) - { - // Calculate required size of RX FIFO - uint16_t const sz = calc_rx_ff_size(4*fifo_size); - - // If size_rx needs to be extended check if possible and if so enlarge it - if (usb_otg->GRXFSIZ < sz) - { - TU_ASSERT(sz + _allocated_fifo_words_tx <= EP_FIFO_SIZE/4); - - // Enlarge RX FIFO - usb_otg->GRXFSIZ = sz; - } - - out_ep[epnum].DOEPCTL |= (1 << USB_OTG_DOEPCTL_USBAEP_Pos) | - (desc_edpt->bmAttributes.xfer << USB_OTG_DOEPCTL_EPTYP_Pos) | - (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? USB_OTG_DOEPCTL_SD0PID_SEVNFRM : 0) | - (xfer->max_size << USB_OTG_DOEPCTL_MPSIZ_Pos); - - dev->DAINTMSK |= (1 << (USB_OTG_DAINTMSK_OEPM_Pos + epnum)); - } - else - { - // "USB Data FIFOs" section in reference manual - // Peripheral FIFO architecture - // - // --------------- 320 or 1024 ( 1280 or 4096 bytes ) - // | IN FIFO 0 | - // --------------- (320 or 1024) - 16 - // | IN FIFO 1 | - // --------------- (320 or 1024) - 16 - x - // | . . . . | - // --------------- (320 or 1024) - 16 - x - y - ... - z - // | IN FIFO MAX | - // --------------- - // | FREE | - // --------------- GRXFSIZ - // | OUT FIFO | - // | ( Shared ) | - // --------------- 0 - // - // In FIFO is allocated by following rules: - // - IN EP 1 gets FIFO 1, IN EP "n" gets FIFO "n". - - // Check if free space is available - TU_ASSERT(_allocated_fifo_words_tx + fifo_size + usb_otg->GRXFSIZ <= EP_FIFO_SIZE/4); - - _allocated_fifo_words_tx += fifo_size; - - TU_LOG(2, " Allocated %u bytes at offset %u", fifo_size*4, EP_FIFO_SIZE-_allocated_fifo_words_tx*4); - - // DIEPTXF starts at FIFO #1. - // Both TXFD and TXSA are in unit of 32-bit words. - usb_otg->DIEPTXF[epnum - 1] = (fifo_size << USB_OTG_DIEPTXF_INEPTXFD_Pos) | (EP_FIFO_SIZE/4 - _allocated_fifo_words_tx); - - in_ep[epnum].DIEPCTL |= (1 << USB_OTG_DIEPCTL_USBAEP_Pos) | - (epnum << USB_OTG_DIEPCTL_TXFNUM_Pos) | - (desc_edpt->bmAttributes.xfer << USB_OTG_DIEPCTL_EPTYP_Pos) | - (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? USB_OTG_DIEPCTL_SD0PID_SEVNFRM : 0) | - (xfer->max_size << USB_OTG_DIEPCTL_MPSIZ_Pos); - - dev->DAINTMSK |= (1 << (USB_OTG_DAINTMSK_IEPM_Pos + epnum)); - } - - return true; -} - -// Close all non-control endpoints, cancel all pending transfers if any. -void dcd_edpt_close_all (uint8_t rhport) -{ - (void) rhport; - -// USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); - USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); - - // Disable non-control interrupt - dev->DAINTMSK = (1 << USB_OTG_DAINTMSK_OEPM_Pos) | (1 << USB_OTG_DAINTMSK_IEPM_Pos); - - for(uint8_t n = 1; n < EP_MAX; n++) - { - // disable OUT endpoint - out_ep[n].DOEPCTL = 0; - xfer_status[n][TUSB_DIR_OUT].max_size = 0; - - // disable IN endpoint - in_ep[n].DIEPCTL = 0; - xfer_status[n][TUSB_DIR_IN].max_size = 0; - } - - // reset allocated fifo IN - _allocated_fifo_words_tx = 16; -} - -bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) -{ - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); - xfer->buffer = buffer; - xfer->ff = NULL; - xfer->total_len = total_bytes; - - // EP0 can only handle one packet - if(epnum == 0) { - ep0_pending[dir] = total_bytes; - // Schedule the first transaction for EP0 transfer - edpt_schedule_packets(rhport, epnum, dir, 1, ep0_pending[dir]); - return true; - } - - uint16_t num_packets = (total_bytes / xfer->max_size); - uint16_t const short_packet_size = total_bytes % xfer->max_size; - - // Zero-size packet is special case. - if(short_packet_size > 0 || (total_bytes == 0)) { - num_packets++; - } - - // Schedule packets to be sent within interrupt - edpt_schedule_packets(rhport, epnum, dir, num_packets, total_bytes); - - return true; -} - -// The number of bytes has to be given explicitly to allow more flexible control of how many -// 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) -{ - // USB buffers always work in bytes so to avoid unnecessary divisions we demand item_size = 1 - TU_ASSERT(ff->item_size == 1); - - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); - xfer->buffer = NULL; - xfer->ff = ff; - xfer->total_len = total_bytes; - - uint16_t num_packets = (total_bytes / xfer->max_size); - uint16_t const short_packet_size = total_bytes % xfer->max_size; - - // Zero-size packet is special case. - if(short_packet_size > 0 || (total_bytes == 0)) num_packets++; - - // Schedule packets to be sent within interrupt - edpt_schedule_packets(rhport, epnum, dir, num_packets, total_bytes); - - return true; -} - -static void dcd_edpt_disable (uint8_t rhport, uint8_t ep_addr, bool stall) -{ - (void) rhport; - - USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); - USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); - - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - if(dir == TUSB_DIR_IN) { - // Only disable currently enabled non-control endpoint - if ( (epnum == 0) || !(in_ep[epnum].DIEPCTL & USB_OTG_DIEPCTL_EPENA) ){ - in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_SNAK | (stall ? USB_OTG_DIEPCTL_STALL : 0); - } else { - // Stop transmitting packets and NAK IN xfers. - in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_SNAK; - while((in_ep[epnum].DIEPINT & USB_OTG_DIEPINT_INEPNE) == 0); - - // Disable the endpoint. - in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_EPDIS | (stall ? USB_OTG_DIEPCTL_STALL : 0); - while((in_ep[epnum].DIEPINT & USB_OTG_DIEPINT_EPDISD_Msk) == 0); - in_ep[epnum].DIEPINT = USB_OTG_DIEPINT_EPDISD; - } - - // Flush the FIFO, and wait until we have confirmed it cleared. - usb_otg->GRSTCTL |= (epnum << USB_OTG_GRSTCTL_TXFNUM_Pos); - usb_otg->GRSTCTL |= USB_OTG_GRSTCTL_TXFFLSH; - while((usb_otg->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH_Msk) != 0); - } else { - // Only disable currently enabled non-control endpoint - if ( (epnum == 0) || !(out_ep[epnum].DOEPCTL & USB_OTG_DOEPCTL_EPENA) ){ - out_ep[epnum].DOEPCTL |= stall ? USB_OTG_DOEPCTL_STALL : 0; - } else { - // Asserting GONAK is required to STALL an OUT endpoint. - // Simpler to use polling here, we don't use the "B"OUTNAKEFF interrupt - // anyway, and it can't be cleared by user code. If this while loop never - // finishes, we have bigger problems than just the stack. - dev->DCTL |= USB_OTG_DCTL_SGONAK; - while((usb_otg->GINTSTS & USB_OTG_GINTSTS_BOUTNAKEFF_Msk) == 0); - - // Ditto here- disable the endpoint. - out_ep[epnum].DOEPCTL |= USB_OTG_DOEPCTL_EPDIS | (stall ? USB_OTG_DOEPCTL_STALL : 0); - while((out_ep[epnum].DOEPINT & USB_OTG_DOEPINT_EPDISD_Msk) == 0); - out_ep[epnum].DOEPINT = USB_OTG_DOEPINT_EPDISD; - - // Allow other OUT endpoints to keep receiving. - dev->DCTL |= USB_OTG_DCTL_CGONAK; - } - } -} - -/** - * Close an endpoint. - */ -void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) -{ - USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); - - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - dcd_edpt_disable(rhport, ep_addr, false); - - // Update max_size - xfer_status[epnum][dir].max_size = 0; // max_size = 0 marks a disabled EP - required for changing FIFO allocation - - if (dir == TUSB_DIR_IN) - { - uint16_t const fifo_size = (usb_otg->DIEPTXF[epnum - 1] & USB_OTG_DIEPTXF_INEPTXFD_Msk) >> USB_OTG_DIEPTXF_INEPTXFD_Pos; - uint16_t const fifo_start = (usb_otg->DIEPTXF[epnum - 1] & USB_OTG_DIEPTXF_INEPTXSA_Msk) >> USB_OTG_DIEPTXF_INEPTXSA_Pos; - // For now only the last opened endpoint can be closed without fuss. - TU_ASSERT(fifo_start == EP_FIFO_SIZE/4 - _allocated_fifo_words_tx,); - _allocated_fifo_words_tx -= fifo_size; - } - else - { - _out_ep_closed = true; // Set flag such that RX FIFO gets reduced in size once RX FIFO is empty - } -} - -void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) -{ - dcd_edpt_disable(rhport, ep_addr, true); -} - -void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) -{ - (void) rhport; - - USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); - USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); - - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - // Clear stall and reset data toggle - if(dir == TUSB_DIR_IN) { - in_ep[epnum].DIEPCTL &= ~USB_OTG_DIEPCTL_STALL; - in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; - } else { - out_ep[epnum].DOEPCTL &= ~USB_OTG_DOEPCTL_STALL; - out_ep[epnum].DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; - } -} - -/*------------------------------------------------------------------*/ - -// Read a single data packet from receive FIFO -static void read_fifo_packet(uint8_t rhport, uint8_t * dst, uint16_t len) -{ - (void) rhport; - - usb_fifo_t rx_fifo = FIFO_BASE(rhport, 0); - - // Reading full available 32 bit words from fifo - uint16_t full_words = len >> 2; - for(uint16_t i = 0; i < full_words; i++) { - uint32_t tmp = *rx_fifo; - dst[0] = tmp & 0x000000FF; - dst[1] = (tmp & 0x0000FF00) >> 8; - dst[2] = (tmp & 0x00FF0000) >> 16; - dst[3] = (tmp & 0xFF000000) >> 24; - dst += 4; - } - - // Read the remaining 1-3 bytes from fifo - uint8_t bytes_rem = len & 0x03; - if(bytes_rem != 0) { - uint32_t tmp = *rx_fifo; - dst[0] = tmp & 0x000000FF; - if(bytes_rem > 1) { - dst[1] = (tmp & 0x0000FF00) >> 8; - } - if(bytes_rem > 2) { - dst[2] = (tmp & 0x00FF0000) >> 16; - } - } -} - -// Write a single data packet to EPIN FIFO -static void write_fifo_packet(uint8_t rhport, uint8_t fifo_num, uint8_t * src, uint16_t len) -{ - (void) rhport; - - usb_fifo_t tx_fifo = FIFO_BASE(rhport, fifo_num); - - // Pushing full available 32 bit words to fifo - uint16_t full_words = len >> 2; - for(uint16_t i = 0; i < full_words; i++){ - *tx_fifo = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0]; - src += 4; - } - - // Write the remaining 1-3 bytes into fifo - uint8_t bytes_rem = len & 0x03; - if(bytes_rem){ - uint32_t tmp_word = 0; - tmp_word |= src[0]; - if(bytes_rem > 1){ - tmp_word |= src[1] << 8; - } - if(bytes_rem > 2){ - tmp_word |= src[2] << 16; - } - *tx_fifo = tmp_word; - } -} - -static void handle_rxflvl_ints(uint8_t rhport, USB_OTG_OUTEndpointTypeDef * out_ep) { - USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); - usb_fifo_t rx_fifo = FIFO_BASE(rhport, 0); - - // Pop control word off FIFO - uint32_t ctl_word = usb_otg->GRXSTSP; - uint8_t pktsts = (ctl_word & USB_OTG_GRXSTSP_PKTSTS_Msk) >> USB_OTG_GRXSTSP_PKTSTS_Pos; - uint8_t epnum = (ctl_word & USB_OTG_GRXSTSP_EPNUM_Msk) >> USB_OTG_GRXSTSP_EPNUM_Pos; - uint16_t bcnt = (ctl_word & USB_OTG_GRXSTSP_BCNT_Msk) >> USB_OTG_GRXSTSP_BCNT_Pos; - - switch(pktsts) { - case 0x01: // Global OUT NAK (Interrupt) - break; - - case 0x02: // Out packet recvd - { - xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); - - // Read packet off RxFIFO - if (xfer->ff) - { - // Ring buffer - tu_fifo_write_n_const_addr_full_words(xfer->ff, (const void *)(uintptr_t) rx_fifo, bcnt); - } - else - { - // Linear buffer - read_fifo_packet(rhport, xfer->buffer, bcnt); - - // Increment pointer to xfer data - xfer->buffer += bcnt; - } - - // Truncate transfer length in case of short packet - if(bcnt < xfer->max_size) { - xfer->total_len -= (out_ep[epnum].DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ_Msk) >> USB_OTG_DOEPTSIZ_XFRSIZ_Pos; - if(epnum == 0) { - xfer->total_len -= ep0_pending[TUSB_DIR_OUT]; - ep0_pending[TUSB_DIR_OUT] = 0; - } - } - } - break; - - case 0x03: // Out packet done (Interrupt) - break; - - case 0x04: // Setup packet done (Interrupt) - out_ep[epnum].DOEPTSIZ |= (3 << USB_OTG_DOEPTSIZ_STUPCNT_Pos); - break; - - case 0x06: // Setup packet recvd - // We can receive up to three setup packets in succession, but - // only the last one is valid. - _setup_packet[0] = (* rx_fifo); - _setup_packet[1] = (* rx_fifo); - break; - - default: // Invalid - TU_BREAKPOINT(); - break; - } -} - -static void handle_epout_ints(uint8_t rhport, USB_OTG_DeviceTypeDef * dev, USB_OTG_OUTEndpointTypeDef * out_ep) { - // DAINT for a given EP clears when DOEPINTx is cleared. - // OEPINT will be cleared when DAINT's out bits are cleared. - for(uint8_t n = 0; n < EP_MAX; n++) { - xfer_ctl_t * xfer = XFER_CTL_BASE(n, TUSB_DIR_OUT); - - if(dev->DAINT & (1 << (USB_OTG_DAINT_OEPINT_Pos + n))) { - // SETUP packet Setup Phase done. - if(out_ep[n].DOEPINT & USB_OTG_DOEPINT_STUP) { - out_ep[n].DOEPINT = USB_OTG_DOEPINT_STUP; - dcd_event_setup_received(rhport, (uint8_t*) &_setup_packet[0], true); - } - - // OUT XFER complete - if(out_ep[n].DOEPINT & USB_OTG_DOEPINT_XFRC) { - out_ep[n].DOEPINT = USB_OTG_DOEPINT_XFRC; - - // EP0 can only handle one packet - if((n == 0) && ep0_pending[TUSB_DIR_OUT]) { - // Schedule another packet to be received. - edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); - } else { - dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); - } - } - } - } -} - -static void handle_epin_ints(uint8_t rhport, USB_OTG_DeviceTypeDef * dev, USB_OTG_INEndpointTypeDef * in_ep) { - // DAINT for a given EP clears when DIEPINTx is cleared. - // IEPINT will be cleared when DAINT's out bits are cleared. - for ( uint8_t n = 0; n < EP_MAX; n++ ) - { - xfer_ctl_t *xfer = XFER_CTL_BASE(n, TUSB_DIR_IN); - - if ( dev->DAINT & (1 << (USB_OTG_DAINT_IEPINT_Pos + n)) ) - { - // IN XFER complete (entire xfer). - if ( in_ep[n].DIEPINT & USB_OTG_DIEPINT_XFRC ) - { - in_ep[n].DIEPINT = USB_OTG_DIEPINT_XFRC; - - // EP0 can only handle one packet - if((n == 0) && ep0_pending[TUSB_DIR_IN]) { - // Schedule another packet to be transmitted. - edpt_schedule_packets(rhport, n, TUSB_DIR_IN, 1, ep0_pending[TUSB_DIR_IN]); - } else { - dcd_event_xfer_complete(rhport, n | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true); - } - } - - // XFER FIFO empty - if ( (in_ep[n].DIEPINT & USB_OTG_DIEPINT_TXFE) && (dev->DIEPEMPMSK & (1 << n)) ) - { - // DIEPINT's TXFE bit is read-only, software cannot clear it. - // It will only be cleared by hardware when written bytes is more than - // - 64 bytes or - // - Half of TX FIFO size (configured by DIEPTXF) - - uint16_t remaining_packets = (in_ep[n].DIEPTSIZ & USB_OTG_DIEPTSIZ_PKTCNT_Msk) >> USB_OTG_DIEPTSIZ_PKTCNT_Pos; - - // Process every single packet (only whole packets can be written to fifo) - for(uint16_t i = 0; i < remaining_packets; i++) - { - uint16_t const remaining_bytes = (in_ep[n].DIEPTSIZ & USB_OTG_DIEPTSIZ_XFRSIZ_Msk) >> USB_OTG_DIEPTSIZ_XFRSIZ_Pos; - - // Packet can not be larger than ep max size - uint16_t const packet_size = tu_min16(remaining_bytes, xfer->max_size); - - // It's only possible to write full packets into FIFO. Therefore DTXFSTS register of current - // EP has to be checked if the buffer can take another WHOLE packet - if(packet_size > ((in_ep[n].DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV_Msk) << 2)) break; - - // Push packet to Tx-FIFO - if (xfer->ff) - { - usb_fifo_t tx_fifo = FIFO_BASE(rhport, n); - tu_fifo_read_n_const_addr_full_words(xfer->ff, (void *)(uintptr_t) tx_fifo, packet_size); - } - else - { - write_fifo_packet(rhport, n, xfer->buffer, packet_size); - - // Increment pointer to xfer data - xfer->buffer += packet_size; - } - } - - // Turn off TXFE if all bytes are written. - if (((in_ep[n].DIEPTSIZ & USB_OTG_DIEPTSIZ_XFRSIZ_Msk) >> USB_OTG_DIEPTSIZ_XFRSIZ_Pos) == 0) - { - dev->DIEPEMPMSK &= ~(1 << n); - } - } - } - } -} - -void dcd_int_handler(uint8_t rhport) -{ - USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); - USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); - - uint32_t const int_status = usb_otg->GINTSTS & usb_otg->GINTMSK; - - if(int_status & USB_OTG_GINTSTS_USBRST) - { - // USBRST is start of reset. - usb_otg->GINTSTS = USB_OTG_GINTSTS_USBRST; - bus_reset(rhport); - } - - if(int_status & USB_OTG_GINTSTS_ENUMDNE) - { - // ENUMDNE is the end of reset where speed of the link is detected - - usb_otg->GINTSTS = USB_OTG_GINTSTS_ENUMDNE; - - tusb_speed_t const speed = get_speed(rhport); - - set_turnaround(usb_otg, speed); - dcd_event_bus_reset(rhport, speed, true); - } - - if(int_status & USB_OTG_GINTSTS_USBSUSP) - { - usb_otg->GINTSTS = USB_OTG_GINTSTS_USBSUSP; - dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); - } - - if(int_status & USB_OTG_GINTSTS_WKUINT) - { - usb_otg->GINTSTS = USB_OTG_GINTSTS_WKUINT; - dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); - } - - // TODO check USB_OTG_GINTSTS_DISCINT for disconnect detection - // if(int_status & USB_OTG_GINTSTS_DISCINT) - - if(int_status & USB_OTG_GINTSTS_OTGINT) - { - // OTG INT bit is read-only - uint32_t const otg_int = usb_otg->GOTGINT; - - if (otg_int & USB_OTG_GOTGINT_SEDET) - { - dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); - } - - usb_otg->GOTGINT = otg_int; - } - - if(int_status & USB_OTG_GINTSTS_SOF) - { - usb_otg->GINTSTS = USB_OTG_GINTSTS_SOF; - - // Disable SOF interrupt since currently only used for remote wakeup detection - usb_otg->GINTMSK &= ~USB_OTG_GINTMSK_SOFM; - - dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); - } - - // RxFIFO non-empty interrupt handling. - if(int_status & USB_OTG_GINTSTS_RXFLVL) - { - // RXFLVL bit is read-only - - // Mask out RXFLVL while reading data from FIFO - usb_otg->GINTMSK &= ~USB_OTG_GINTMSK_RXFLVLM; - - // Loop until all available packets were handled - do - { - handle_rxflvl_ints(rhport, out_ep); - } while(usb_otg->GINTSTS & USB_OTG_GINTSTS_RXFLVL); - - // Manage RX FIFO size - if (_out_ep_closed) - { - update_grxfsiz(rhport); - - // Disable flag - _out_ep_closed = false; - } - - usb_otg->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM; - } - - // OUT endpoint interrupt handling. - if(int_status & USB_OTG_GINTSTS_OEPINT) - { - // OEPINT is read-only - handle_epout_ints(rhport, dev, out_ep); - } - - // IN endpoint interrupt handling. - if(int_status & USB_OTG_GINTSTS_IEPINT) - { - // IEPINT bit read-only - handle_epin_ints(rhport, dev, in_ep); - } - - // // Check for Incomplete isochronous IN transfer - // if(int_status & USB_OTG_GINTSTS_IISOIXFR) { - // printf(" IISOIXFR!\r\n"); - //// TU_LOG2(" IISOIXFR!\r\n"); - // } -} - -#endif diff --git a/src/portable/broadcom/synopsys/synopsys_common.h b/src/portable/broadcom/synopsys/synopsys_common.h deleted file mode 100644 index 81ce3b4a9..000000000 --- a/src/portable/broadcom/synopsys/synopsys_common.h +++ /dev/null @@ -1,1476 +0,0 @@ -/** - ****************************************************************************** - * @file synopsys_common.h - * @author MCD Application Team - * @brief CMSIS Cortex-M3 Device USB OTG peripheral Header File. - * This file contains the USB OTG peripheral register's definitions, bits - * definitions and memory mapping for STM32F1xx devices. - * - * This file contains: - * - Data structures and the address mapping for the USB OTG peripheral - * - The Peripheral's registers declarations and bits definition - * - Macros to access the peripheral's registers hardware - * - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under BSD 3-Clause license, - * the "License"; You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - * - ****************************************************************************** - */ - -#include "stdint.h" - -#pragma once - -#ifdef __cplusplus - #define __I volatile -#else - #define __I volatile const -#endif -#define __O volatile -#define __IO volatile -#define __IM volatile const -#define __OM volatile -#define __IOM volatile - -/** - * @brief __USB_OTG_Core_register - */ - -typedef struct -{ - __IO uint32_t GOTGCTL; /*!< USB_OTG Control and Status Register Address offset: 000h */ - __IO uint32_t GOTGINT; /*!< USB_OTG Interrupt Register Address offset: 004h */ - __IO uint32_t GAHBCFG; /*!< Core AHB Configuration Register Address offset: 008h */ - __IO uint32_t GUSBCFG; /*!< Core USB Configuration Register Address offset: 00Ch */ - __IO uint32_t GRSTCTL; /*!< Core Reset Register Address offset: 010h */ - __IO uint32_t GINTSTS; /*!< Core Interrupt Register Address offset: 014h */ - __IO uint32_t GINTMSK; /*!< Core Interrupt Mask Register Address offset: 018h */ - __IO uint32_t GRXSTSR; /*!< Receive Sts Q Read Register Address offset: 01Ch */ - __IO uint32_t GRXSTSP; /*!< Receive Sts Q Read & POP Register Address offset: 020h */ - __IO uint32_t GRXFSIZ; /*!< Receive FIFO Size Register Address offset: 024h */ - __IO uint32_t DIEPTXF0_HNPTXFSIZ; /*!< EP0 / Non Periodic Tx FIFO Size Register Address offset: 028h */ - __IO uint32_t HNPTXSTS; /*!< Non Periodic Tx FIFO/Queue Sts reg Address offset: 02Ch */ - uint32_t Reserved30[2]; /*!< Reserved 030h*/ - __IO uint32_t GCCFG; /*!< General Purpose IO Register Address offset: 038h */ - __IO uint32_t CID; /*!< User ID Register 03Ch */ - __IO uint32_t GSNPSID; /* USB_OTG core ID 040h*/ - __IO uint32_t GHWCFG1; /* User HW config1 044h*/ - __IO uint32_t GHWCFG2; /* User HW config2 048h*/ - __IO uint32_t GHWCFG3; /*!< User HW config3 04Ch */ - uint32_t Reserved6; /*!< Reserved 050h */ - __IO uint32_t GLPMCFG; /*!< LPM Register 054h */ - __IO uint32_t GPWRDN; /*!< Power Down Register 058h */ - __IO uint32_t GDFIFOCFG; /*!< DFIFO Software Config Register 05Ch */ - __IO uint32_t GADPCTL; /*!< ADP Timer, Control and Status Register 60Ch */ - uint32_t Reserved43[39]; /*!< Reserved 058h-0FFh */ - __IO uint32_t HPTXFSIZ; /*!< Host Periodic Tx FIFO Size Reg Address offset: 100h */ - __IO uint32_t DIEPTXF[0x0F]; /*!< dev Periodic Transmit FIFO Address offset: 0x104 */ -} USB_OTG_GlobalTypeDef; - - - -/** - * @brief __device_Registers - */ - -typedef struct -{ - __IO uint32_t DCFG; /*!< dev Configuration Register Address offset: 800h*/ - __IO uint32_t DCTL; /*!< dev Control Register Address offset: 804h*/ - __IO uint32_t DSTS; /*!< dev Status Register (RO) Address offset: 808h*/ - uint32_t Reserved0C; /*!< Reserved 80Ch*/ - __IO uint32_t DIEPMSK; /*!< dev IN Endpoint Mask Address offset: 810h*/ - __IO uint32_t DOEPMSK; /*!< dev OUT Endpoint Mask Address offset: 814h*/ - __IO uint32_t DAINT; /*!< dev All Endpoints Itr Reg Address offset: 818h*/ - __IO uint32_t DAINTMSK; /*!< dev All Endpoints Itr Mask Address offset: 81Ch*/ - uint32_t Reserved20; /*!< Reserved 820h*/ - uint32_t Reserved9; /*!< Reserved 824h*/ - __IO uint32_t DVBUSDIS; /*!< dev VBUS discharge Register Address offset: 828h*/ - __IO uint32_t DVBUSPULSE; /*!< dev VBUS Pulse Register Address offset: 82Ch*/ - __IO uint32_t DTHRCTL; /*!< dev thr Address offset: 830h*/ - __IO uint32_t DIEPEMPMSK; /*!< dev empty msk Address offset: 834h*/ - __IO uint32_t DEACHINT; /*!< dedicated EP interrupt Address offset: 838h*/ - __IO uint32_t DEACHMSK; /*!< dedicated EP msk Address offset: 83Ch*/ - uint32_t Reserved40; /*!< dedicated EP mask Address offset: 840h*/ - __IO uint32_t DINEP1MSK; /*!< dedicated EP mask Address offset: 844h*/ - uint32_t Reserved44[15]; /*!< Reserved 844-87Ch*/ - __IO uint32_t DOUTEP1MSK; /*!< dedicated EP msk Address offset: 884h*/ -} USB_OTG_DeviceTypeDef; - -/** - * @brief __IN_Endpoint-Specific_Register - */ - -typedef struct -{ - __IO uint32_t DIEPCTL; /*!< dev IN Endpoint Control Reg 900h + (ep_num * 20h) + 00h*/ - uint32_t Reserved04; /*!< Reserved 900h + (ep_num * 20h) + 04h*/ - __IO uint32_t DIEPINT; /*!< dev IN Endpoint Itr Reg 900h + (ep_num * 20h) + 08h*/ - uint32_t Reserved0C; /*!< Reserved 900h + (ep_num * 20h) + 0Ch*/ - __IO uint32_t DIEPTSIZ; /*!< IN Endpoint Txfer Size 900h + (ep_num * 20h) + 10h*/ - __IO uint32_t DIEPDMA; /*!< IN Endpoint DMA Address Reg 900h + (ep_num * 20h) + 14h*/ - __IO uint32_t DTXFSTS; /*!< IN Endpoint Tx FIFO Status Reg 900h + (ep_num * 20h) + 18h*/ - uint32_t Reserved18; /*!< Reserved 900h+(ep_num*20h)+1Ch-900h+ (ep_num * 20h) + 1Ch*/ -} USB_OTG_INEndpointTypeDef; - -/** - * @brief __OUT_Endpoint-Specific_Registers - */ - -typedef struct -{ - __IO uint32_t DOEPCTL; /*!< dev OUT Endpoint Control Reg B00h + (ep_num * 20h) + 00h*/ - uint32_t Reserved04; /*!< Reserved B00h + (ep_num * 20h) + 04h*/ - __IO uint32_t DOEPINT; /*!< dev OUT Endpoint Itr Reg B00h + (ep_num * 20h) + 08h*/ - uint32_t Reserved0C; /*!< Reserved B00h + (ep_num * 20h) + 0Ch*/ - __IO uint32_t DOEPTSIZ; /*!< dev OUT Endpoint Txfer Size B00h + (ep_num * 20h) + 10h*/ - __IO uint32_t DOEPDMA; /*!< dev OUT Endpoint DMA Address B00h + (ep_num * 20h) + 14h*/ - uint32_t Reserved18[2]; /*!< Reserved B00h + (ep_num * 20h) + 18h - B00h + (ep_num * 20h) + 1Ch*/ -} USB_OTG_OUTEndpointTypeDef; - -/** - * @brief __Host_Mode_Register_Structures - */ - -typedef struct -{ - __IO uint32_t HCFG; /*!< Host Configuration Register 400h*/ - __IO uint32_t HFIR; /*!< Host Frame Interval Register 404h*/ - __IO uint32_t HFNUM; /*!< Host Frame Nbr/Frame Remaining 408h*/ - uint32_t Reserved40C; /*!< Reserved 40Ch*/ - __IO uint32_t HPTXSTS; /*!< Host Periodic Tx FIFO/ Queue Status 410h*/ - __IO uint32_t HAINT; /*!< Host All Channels Interrupt Register 414h*/ - __IO uint32_t HAINTMSK; /*!< Host All Channels Interrupt Mask 418h*/ -} USB_OTG_HostTypeDef; - -/** - * @brief __Host_Channel_Specific_Registers - */ - -typedef struct -{ - __IO uint32_t HCCHAR; - __IO uint32_t HCSPLT; - __IO uint32_t HCINT; - __IO uint32_t HCINTMSK; - __IO uint32_t HCTSIZ; - __IO uint32_t HCDMA; - uint32_t Reserved[2]; -} USB_OTG_HostChannelTypeDef; - -/*!< USB registers base address */ -#define USB_OTG_FS_PERIPH_BASE 0x50000000UL - -// #define USB_OTG_GLOBAL_BASE 0x00000000UL -// #define USB_OTG_DEVICE_BASE 0x00000800UL -#define USB_OTG_IN_ENDPOINT_BASE 0x00000900UL -#define USB_OTG_OUT_ENDPOINT_BASE 0x00000B00UL -#define USB_OTG_EP_REG_SIZE 0x00000020UL -// #define USB_OTG_HOST_BASE 0x00000400UL -#define USB_OTG_HOST_PORT_BASE 0x00000440UL -#define USB_OTG_HOST_CHANNEL_BASE 0x00000500UL -#define USB_OTG_HOST_CHANNEL_SIZE 0x00000020UL -#define USB_OTG_PCGCCTL_BASE 0x00000E00UL -#define USB_OTG_FIFO_BASE 0x00001000UL -#define USB_OTG_FIFO_SIZE 0x00001000UL - -/******************************************************************************/ -/* */ -/* USB_OTG */ -/* */ -/******************************************************************************/ -/******************** Bit definition for USB_OTG_GOTGCTL register ***********/ -#define USB_OTG_GOTGCTL_SRQSCS_Pos (0U) -#define USB_OTG_GOTGCTL_SRQSCS_Msk (0x1UL << USB_OTG_GOTGCTL_SRQSCS_Pos) /*!< 0x00000001 */ -#define USB_OTG_GOTGCTL_SRQSCS USB_OTG_GOTGCTL_SRQSCS_Msk /*!< Session request success */ -#define USB_OTG_GOTGCTL_SRQ_Pos (1U) -#define USB_OTG_GOTGCTL_SRQ_Msk (0x1UL << USB_OTG_GOTGCTL_SRQ_Pos) /*!< 0x00000002 */ -#define USB_OTG_GOTGCTL_SRQ USB_OTG_GOTGCTL_SRQ_Msk /*!< Session request */ -#define USB_OTG_GOTGCTL_HNGSCS_Pos (8U) -#define USB_OTG_GOTGCTL_HNGSCS_Msk (0x1UL << USB_OTG_GOTGCTL_HNGSCS_Pos) /*!< 0x00000100 */ -#define USB_OTG_GOTGCTL_HNGSCS USB_OTG_GOTGCTL_HNGSCS_Msk /*!< Host set HNP enable */ -#define USB_OTG_GOTGCTL_HNPRQ_Pos (9U) -#define USB_OTG_GOTGCTL_HNPRQ_Msk (0x1UL << USB_OTG_GOTGCTL_HNPRQ_Pos) /*!< 0x00000200 */ -#define USB_OTG_GOTGCTL_HNPRQ USB_OTG_GOTGCTL_HNPRQ_Msk /*!< HNP request */ -#define USB_OTG_GOTGCTL_HSHNPEN_Pos (10U) -#define USB_OTG_GOTGCTL_HSHNPEN_Msk (0x1UL << USB_OTG_GOTGCTL_HSHNPEN_Pos) /*!< 0x00000400 */ -#define USB_OTG_GOTGCTL_HSHNPEN USB_OTG_GOTGCTL_HSHNPEN_Msk /*!< Host set HNP enable */ -#define USB_OTG_GOTGCTL_DHNPEN_Pos (11U) -#define USB_OTG_GOTGCTL_DHNPEN_Msk (0x1UL << USB_OTG_GOTGCTL_DHNPEN_Pos) /*!< 0x00000800 */ -#define USB_OTG_GOTGCTL_DHNPEN USB_OTG_GOTGCTL_DHNPEN_Msk /*!< Device HNP enabled */ -#define USB_OTG_GOTGCTL_CIDSTS_Pos (16U) -#define USB_OTG_GOTGCTL_CIDSTS_Msk (0x1UL << USB_OTG_GOTGCTL_CIDSTS_Pos) /*!< 0x00010000 */ -#define USB_OTG_GOTGCTL_CIDSTS USB_OTG_GOTGCTL_CIDSTS_Msk /*!< Connector ID status */ -#define USB_OTG_GOTGCTL_DBCT_Pos (17U) -#define USB_OTG_GOTGCTL_DBCT_Msk (0x1UL << USB_OTG_GOTGCTL_DBCT_Pos) /*!< 0x00020000 */ -#define USB_OTG_GOTGCTL_DBCT USB_OTG_GOTGCTL_DBCT_Msk /*!< Long/short debounce time */ -#define USB_OTG_GOTGCTL_ASVLD_Pos (18U) -#define USB_OTG_GOTGCTL_ASVLD_Msk (0x1UL << USB_OTG_GOTGCTL_ASVLD_Pos) /*!< 0x00040000 */ -#define USB_OTG_GOTGCTL_ASVLD USB_OTG_GOTGCTL_ASVLD_Msk /*!< A-session valid */ -#define USB_OTG_GOTGCTL_BSVLD_Pos (19U) -#define USB_OTG_GOTGCTL_BSVLD_Msk (0x1UL << USB_OTG_GOTGCTL_BSVLD_Pos) /*!< 0x00080000 */ -#define USB_OTG_GOTGCTL_BSVLD USB_OTG_GOTGCTL_BSVLD_Msk /*!< B-session valid */ - -/******************** Bit definition for USB_OTG_HCFG register ********************/ - -#define USB_OTG_HCFG_FSLSPCS_Pos (0U) -#define USB_OTG_HCFG_FSLSPCS_Msk (0x3UL << USB_OTG_HCFG_FSLSPCS_Pos) /*!< 0x00000003 */ -#define USB_OTG_HCFG_FSLSPCS USB_OTG_HCFG_FSLSPCS_Msk /*!< FS/LS PHY clock select */ -#define USB_OTG_HCFG_FSLSPCS_0 (0x1UL << USB_OTG_HCFG_FSLSPCS_Pos) /*!< 0x00000001 */ -#define USB_OTG_HCFG_FSLSPCS_1 (0x2UL << USB_OTG_HCFG_FSLSPCS_Pos) /*!< 0x00000002 */ -#define USB_OTG_HCFG_FSLSS_Pos (2U) -#define USB_OTG_HCFG_FSLSS_Msk (0x1UL << USB_OTG_HCFG_FSLSS_Pos) /*!< 0x00000004 */ -#define USB_OTG_HCFG_FSLSS USB_OTG_HCFG_FSLSS_Msk /*!< FS- and LS-only support */ - -/******************** Bit definition for USB_OTG_DCFG register ********************/ - -#define USB_OTG_DCFG_DSPD_Pos (0U) -#define USB_OTG_DCFG_DSPD_Msk (0x3UL << USB_OTG_DCFG_DSPD_Pos) /*!< 0x00000003 */ -#define USB_OTG_DCFG_DSPD USB_OTG_DCFG_DSPD_Msk /*!< Device speed */ -#define USB_OTG_DCFG_DSPD_0 (0x1UL << USB_OTG_DCFG_DSPD_Pos) /*!< 0x00000001 */ -#define USB_OTG_DCFG_DSPD_1 (0x2UL << USB_OTG_DCFG_DSPD_Pos) /*!< 0x00000002 */ -#define USB_OTG_DCFG_NZLSOHSK_Pos (2U) -#define USB_OTG_DCFG_NZLSOHSK_Msk (0x1UL << USB_OTG_DCFG_NZLSOHSK_Pos) /*!< 0x00000004 */ -#define USB_OTG_DCFG_NZLSOHSK USB_OTG_DCFG_NZLSOHSK_Msk /*!< Nonzero-length status OUT handshake */ - -#define USB_OTG_DCFG_DAD_Pos (4U) -#define USB_OTG_DCFG_DAD_Msk (0x7FUL << USB_OTG_DCFG_DAD_Pos) /*!< 0x000007F0 */ -#define USB_OTG_DCFG_DAD USB_OTG_DCFG_DAD_Msk /*!< Device address */ -#define USB_OTG_DCFG_DAD_0 (0x01UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000010 */ -#define USB_OTG_DCFG_DAD_1 (0x02UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000020 */ -#define USB_OTG_DCFG_DAD_2 (0x04UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000040 */ -#define USB_OTG_DCFG_DAD_3 (0x08UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000080 */ -#define USB_OTG_DCFG_DAD_4 (0x10UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000100 */ -#define USB_OTG_DCFG_DAD_5 (0x20UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000200 */ -#define USB_OTG_DCFG_DAD_6 (0x40UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000400 */ - -#define USB_OTG_DCFG_PFIVL_Pos (11U) -#define USB_OTG_DCFG_PFIVL_Msk (0x3UL << USB_OTG_DCFG_PFIVL_Pos) /*!< 0x00001800 */ -#define USB_OTG_DCFG_PFIVL USB_OTG_DCFG_PFIVL_Msk /*!< Periodic (micro)frame interval */ -#define USB_OTG_DCFG_PFIVL_0 (0x1UL << USB_OTG_DCFG_PFIVL_Pos) /*!< 0x00000800 */ -#define USB_OTG_DCFG_PFIVL_1 (0x2UL << USB_OTG_DCFG_PFIVL_Pos) /*!< 0x00001000 */ - -#define USB_OTG_DCFG_PERSCHIVL_Pos (24U) -#define USB_OTG_DCFG_PERSCHIVL_Msk (0x3UL << USB_OTG_DCFG_PERSCHIVL_Pos) /*!< 0x03000000 */ -#define USB_OTG_DCFG_PERSCHIVL USB_OTG_DCFG_PERSCHIVL_Msk /*!< Periodic scheduling interval */ -#define USB_OTG_DCFG_PERSCHIVL_0 (0x1UL << USB_OTG_DCFG_PERSCHIVL_Pos) /*!< 0x01000000 */ -#define USB_OTG_DCFG_PERSCHIVL_1 (0x2UL << USB_OTG_DCFG_PERSCHIVL_Pos) /*!< 0x02000000 */ - -/******************** Bit definition for USB_OTG_PCGCR register ********************/ -#define USB_OTG_PCGCR_STPPCLK_Pos (0U) -#define USB_OTG_PCGCR_STPPCLK_Msk (0x1UL << USB_OTG_PCGCR_STPPCLK_Pos) /*!< 0x00000001 */ -#define USB_OTG_PCGCR_STPPCLK USB_OTG_PCGCR_STPPCLK_Msk /*!< Stop PHY clock */ -#define USB_OTG_PCGCR_GATEHCLK_Pos (1U) -#define USB_OTG_PCGCR_GATEHCLK_Msk (0x1UL << USB_OTG_PCGCR_GATEHCLK_Pos) /*!< 0x00000002 */ -#define USB_OTG_PCGCR_GATEHCLK USB_OTG_PCGCR_GATEHCLK_Msk /*!< Gate HCLK */ -#define USB_OTG_PCGCR_PHYSUSP_Pos (4U) -#define USB_OTG_PCGCR_PHYSUSP_Msk (0x1UL << USB_OTG_PCGCR_PHYSUSP_Pos) /*!< 0x00000010 */ -#define USB_OTG_PCGCR_PHYSUSP USB_OTG_PCGCR_PHYSUSP_Msk /*!< PHY suspended */ - -/******************** Bit definition for USB_OTG_GOTGINT register ********************/ -#define USB_OTG_GOTGINT_SEDET_Pos (2U) -#define USB_OTG_GOTGINT_SEDET_Msk (0x1UL << USB_OTG_GOTGINT_SEDET_Pos) /*!< 0x00000004 */ -#define USB_OTG_GOTGINT_SEDET USB_OTG_GOTGINT_SEDET_Msk /*!< Session end detected */ -#define USB_OTG_GOTGINT_SRSSCHG_Pos (8U) -#define USB_OTG_GOTGINT_SRSSCHG_Msk (0x1UL << USB_OTG_GOTGINT_SRSSCHG_Pos) /*!< 0x00000100 */ -#define USB_OTG_GOTGINT_SRSSCHG USB_OTG_GOTGINT_SRSSCHG_Msk /*!< Session request success status change */ -#define USB_OTG_GOTGINT_HNSSCHG_Pos (9U) -#define USB_OTG_GOTGINT_HNSSCHG_Msk (0x1UL << USB_OTG_GOTGINT_HNSSCHG_Pos) /*!< 0x00000200 */ -#define USB_OTG_GOTGINT_HNSSCHG USB_OTG_GOTGINT_HNSSCHG_Msk /*!< Host negotiation success status change */ -#define USB_OTG_GOTGINT_HNGDET_Pos (17U) -#define USB_OTG_GOTGINT_HNGDET_Msk (0x1UL << USB_OTG_GOTGINT_HNGDET_Pos) /*!< 0x00020000 */ -#define USB_OTG_GOTGINT_HNGDET USB_OTG_GOTGINT_HNGDET_Msk /*!< Host negotiation detected */ -#define USB_OTG_GOTGINT_ADTOCHG_Pos (18U) -#define USB_OTG_GOTGINT_ADTOCHG_Msk (0x1UL << USB_OTG_GOTGINT_ADTOCHG_Pos) /*!< 0x00040000 */ -#define USB_OTG_GOTGINT_ADTOCHG USB_OTG_GOTGINT_ADTOCHG_Msk /*!< A-device timeout change */ -#define USB_OTG_GOTGINT_DBCDNE_Pos (19U) -#define USB_OTG_GOTGINT_DBCDNE_Msk (0x1UL << USB_OTG_GOTGINT_DBCDNE_Pos) /*!< 0x00080000 */ -#define USB_OTG_GOTGINT_DBCDNE USB_OTG_GOTGINT_DBCDNE_Msk /*!< Debounce done */ - -/******************** Bit definition for USB_OTG_DCTL register ********************/ -#define USB_OTG_DCTL_RWUSIG_Pos (0U) -#define USB_OTG_DCTL_RWUSIG_Msk (0x1UL << USB_OTG_DCTL_RWUSIG_Pos) /*!< 0x00000001 */ -#define USB_OTG_DCTL_RWUSIG USB_OTG_DCTL_RWUSIG_Msk /*!< Remote wakeup signaling */ -#define USB_OTG_DCTL_SDIS_Pos (1U) -#define USB_OTG_DCTL_SDIS_Msk (0x1UL << USB_OTG_DCTL_SDIS_Pos) /*!< 0x00000002 */ -#define USB_OTG_DCTL_SDIS USB_OTG_DCTL_SDIS_Msk /*!< Soft disconnect */ -#define USB_OTG_DCTL_GINSTS_Pos (2U) -#define USB_OTG_DCTL_GINSTS_Msk (0x1UL << USB_OTG_DCTL_GINSTS_Pos) /*!< 0x00000004 */ -#define USB_OTG_DCTL_GINSTS USB_OTG_DCTL_GINSTS_Msk /*!< Global IN NAK status */ -#define USB_OTG_DCTL_GONSTS_Pos (3U) -#define USB_OTG_DCTL_GONSTS_Msk (0x1UL << USB_OTG_DCTL_GONSTS_Pos) /*!< 0x00000008 */ -#define USB_OTG_DCTL_GONSTS USB_OTG_DCTL_GONSTS_Msk /*!< Global OUT NAK status */ - -#define USB_OTG_DCTL_TCTL_Pos (4U) -#define USB_OTG_DCTL_TCTL_Msk (0x7UL << USB_OTG_DCTL_TCTL_Pos) /*!< 0x00000070 */ -#define USB_OTG_DCTL_TCTL USB_OTG_DCTL_TCTL_Msk /*!< Test control */ -#define USB_OTG_DCTL_TCTL_0 (0x1UL << USB_OTG_DCTL_TCTL_Pos) /*!< 0x00000010 */ -#define USB_OTG_DCTL_TCTL_1 (0x2UL << USB_OTG_DCTL_TCTL_Pos) /*!< 0x00000020 */ -#define USB_OTG_DCTL_TCTL_2 (0x4UL << USB_OTG_DCTL_TCTL_Pos) /*!< 0x00000040 */ -#define USB_OTG_DCTL_SGINAK_Pos (7U) -#define USB_OTG_DCTL_SGINAK_Msk (0x1UL << USB_OTG_DCTL_SGINAK_Pos) /*!< 0x00000080 */ -#define USB_OTG_DCTL_SGINAK USB_OTG_DCTL_SGINAK_Msk /*!< Set global IN NAK */ -#define USB_OTG_DCTL_CGINAK_Pos (8U) -#define USB_OTG_DCTL_CGINAK_Msk (0x1UL << USB_OTG_DCTL_CGINAK_Pos) /*!< 0x00000100 */ -#define USB_OTG_DCTL_CGINAK USB_OTG_DCTL_CGINAK_Msk /*!< Clear global IN NAK */ -#define USB_OTG_DCTL_SGONAK_Pos (9U) -#define USB_OTG_DCTL_SGONAK_Msk (0x1UL << USB_OTG_DCTL_SGONAK_Pos) /*!< 0x00000200 */ -#define USB_OTG_DCTL_SGONAK USB_OTG_DCTL_SGONAK_Msk /*!< Set global OUT NAK */ -#define USB_OTG_DCTL_CGONAK_Pos (10U) -#define USB_OTG_DCTL_CGONAK_Msk (0x1UL << USB_OTG_DCTL_CGONAK_Pos) /*!< 0x00000400 */ -#define USB_OTG_DCTL_CGONAK USB_OTG_DCTL_CGONAK_Msk /*!< Clear global OUT NAK */ -#define USB_OTG_DCTL_POPRGDNE_Pos (11U) -#define USB_OTG_DCTL_POPRGDNE_Msk (0x1UL << USB_OTG_DCTL_POPRGDNE_Pos) /*!< 0x00000800 */ -#define USB_OTG_DCTL_POPRGDNE USB_OTG_DCTL_POPRGDNE_Msk /*!< Power-on programming done */ - -/******************** Bit definition for USB_OTG_HFIR register ********************/ -#define USB_OTG_HFIR_FRIVL_Pos (0U) -#define USB_OTG_HFIR_FRIVL_Msk (0xFFFFUL << USB_OTG_HFIR_FRIVL_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_HFIR_FRIVL USB_OTG_HFIR_FRIVL_Msk /*!< Frame interval */ - -/******************** Bit definition for USB_OTG_HFNUM register ********************/ -#define USB_OTG_HFNUM_FRNUM_Pos (0U) -#define USB_OTG_HFNUM_FRNUM_Msk (0xFFFFUL << USB_OTG_HFNUM_FRNUM_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_HFNUM_FRNUM USB_OTG_HFNUM_FRNUM_Msk /*!< Frame number */ -#define USB_OTG_HFNUM_FTREM_Pos (16U) -#define USB_OTG_HFNUM_FTREM_Msk (0xFFFFUL << USB_OTG_HFNUM_FTREM_Pos) /*!< 0xFFFF0000 */ -#define USB_OTG_HFNUM_FTREM USB_OTG_HFNUM_FTREM_Msk /*!< Frame time remaining */ - -/******************** Bit definition for USB_OTG_DSTS register ********************/ -#define USB_OTG_DSTS_SUSPSTS_Pos (0U) -#define USB_OTG_DSTS_SUSPSTS_Msk (0x1UL << USB_OTG_DSTS_SUSPSTS_Pos) /*!< 0x00000001 */ -#define USB_OTG_DSTS_SUSPSTS USB_OTG_DSTS_SUSPSTS_Msk /*!< Suspend status */ - -#define USB_OTG_DSTS_ENUMSPD_Pos (1U) -#define USB_OTG_DSTS_ENUMSPD_Msk (0x3UL << USB_OTG_DSTS_ENUMSPD_Pos) /*!< 0x00000006 */ -#define USB_OTG_DSTS_ENUMSPD USB_OTG_DSTS_ENUMSPD_Msk /*!< Enumerated speed */ -#define USB_OTG_DSTS_ENUMSPD_0 (0x1UL << USB_OTG_DSTS_ENUMSPD_Pos) /*!< 0x00000002 */ -#define USB_OTG_DSTS_ENUMSPD_1 (0x2UL << USB_OTG_DSTS_ENUMSPD_Pos) /*!< 0x00000004 */ -#define USB_OTG_DSTS_EERR_Pos (3U) -#define USB_OTG_DSTS_EERR_Msk (0x1UL << USB_OTG_DSTS_EERR_Pos) /*!< 0x00000008 */ -#define USB_OTG_DSTS_EERR USB_OTG_DSTS_EERR_Msk /*!< Erratic error */ -#define USB_OTG_DSTS_FNSOF_Pos (8U) -#define USB_OTG_DSTS_FNSOF_Msk (0x3FFFUL << USB_OTG_DSTS_FNSOF_Pos) /*!< 0x003FFF00 */ -#define USB_OTG_DSTS_FNSOF USB_OTG_DSTS_FNSOF_Msk /*!< Frame number of the received SOF */ - -/******************** Bit definition for USB_OTG_GAHBCFG register ********************/ -#define USB_OTG_GAHBCFG_GINT_Pos (0U) -#define USB_OTG_GAHBCFG_GINT_Msk (0x1UL << USB_OTG_GAHBCFG_GINT_Pos) /*!< 0x00000001 */ -#define USB_OTG_GAHBCFG_GINT USB_OTG_GAHBCFG_GINT_Msk /*!< Global interrupt mask */ -#define USB_OTG_GAHBCFG_HBSTLEN_Pos (1U) -#define USB_OTG_GAHBCFG_HBSTLEN_Msk (0xFUL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< 0x0000001E */ -#define USB_OTG_GAHBCFG_HBSTLEN USB_OTG_GAHBCFG_HBSTLEN_Msk /*!< Burst length/type */ -#define USB_OTG_GAHBCFG_HBSTLEN_0 (0x0UL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< Single */ -#define USB_OTG_GAHBCFG_HBSTLEN_1 (0x1UL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< INCR */ -#define USB_OTG_GAHBCFG_HBSTLEN_2 (0x3UL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< INCR4 */ -#define USB_OTG_GAHBCFG_HBSTLEN_3 (0x5UL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< INCR8 */ -#define USB_OTG_GAHBCFG_HBSTLEN_4 (0x7UL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< INCR16 */ -#define USB_OTG_GAHBCFG_DMAEN_Pos (5U) -#define USB_OTG_GAHBCFG_DMAEN_Msk (0x1UL << USB_OTG_GAHBCFG_DMAEN_Pos) /*!< 0x00000020 */ -#define USB_OTG_GAHBCFG_DMAEN USB_OTG_GAHBCFG_DMAEN_Msk /*!< DMA enable */ -#define USB_OTG_GAHBCFG_TXFELVL_Pos (7U) -#define USB_OTG_GAHBCFG_TXFELVL_Msk (0x1UL << USB_OTG_GAHBCFG_TXFELVL_Pos) /*!< 0x00000080 */ -#define USB_OTG_GAHBCFG_TXFELVL USB_OTG_GAHBCFG_TXFELVL_Msk /*!< TxFIFO empty level */ -#define USB_OTG_GAHBCFG_PTXFELVL_Pos (8U) -#define USB_OTG_GAHBCFG_PTXFELVL_Msk (0x1UL << USB_OTG_GAHBCFG_PTXFELVL_Pos) /*!< 0x00000100 */ -#define USB_OTG_GAHBCFG_PTXFELVL USB_OTG_GAHBCFG_PTXFELVL_Msk /*!< Periodic TxFIFO empty level */ - -/******************** Bit definition for USB_OTG_GUSBCFG register ********************/ - -#define USB_OTG_GUSBCFG_TOCAL_Pos (0U) -#define USB_OTG_GUSBCFG_TOCAL_Msk (0x7UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000007 */ -#define USB_OTG_GUSBCFG_TOCAL USB_OTG_GUSBCFG_TOCAL_Msk /*!< FS timeout calibration */ -#define USB_OTG_GUSBCFG_TOCAL_0 (0x1UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000001 */ -#define USB_OTG_GUSBCFG_TOCAL_1 (0x2UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000002 */ -#define USB_OTG_GUSBCFG_TOCAL_2 (0x4UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000004 */ -#define USB_OTG_GUSBCFG_PHYSEL_Pos (6U) -#define USB_OTG_GUSBCFG_PHYSEL_Msk (0x1UL << USB_OTG_GUSBCFG_PHYSEL_Pos) /*!< 0x00000040 */ -#define USB_OTG_GUSBCFG_PHYSEL USB_OTG_GUSBCFG_PHYSEL_Msk /*!< USB 2.0 high-speed ULPI PHY or USB 1.1 full-speed serial transceiver select */ -#define USB_OTG_GUSBCFG_SRPCAP_Pos (8U) -#define USB_OTG_GUSBCFG_SRPCAP_Msk (0x1UL << USB_OTG_GUSBCFG_SRPCAP_Pos) /*!< 0x00000100 */ -#define USB_OTG_GUSBCFG_SRPCAP USB_OTG_GUSBCFG_SRPCAP_Msk /*!< SRP-capable */ -#define USB_OTG_GUSBCFG_HNPCAP_Pos (9U) -#define USB_OTG_GUSBCFG_HNPCAP_Msk (0x1UL << USB_OTG_GUSBCFG_HNPCAP_Pos) /*!< 0x00000200 */ -#define USB_OTG_GUSBCFG_HNPCAP USB_OTG_GUSBCFG_HNPCAP_Msk /*!< HNP-capable */ -#define USB_OTG_GUSBCFG_TRDT_Pos (10U) -#define USB_OTG_GUSBCFG_TRDT_Msk (0xFUL << USB_OTG_GUSBCFG_TRDT_Pos) /*!< 0x00003C00 */ -#define USB_OTG_GUSBCFG_TRDT USB_OTG_GUSBCFG_TRDT_Msk /*!< USB turnaround time */ -#define USB_OTG_GUSBCFG_TRDT_0 (0x1UL << USB_OTG_GUSBCFG_TRDT_Pos) /*!< 0x00000400 */ -#define USB_OTG_GUSBCFG_TRDT_1 (0x2UL << USB_OTG_GUSBCFG_TRDT_Pos) /*!< 0x00000800 */ -#define USB_OTG_GUSBCFG_TRDT_2 (0x4UL << USB_OTG_GUSBCFG_TRDT_Pos) /*!< 0x00001000 */ -#define USB_OTG_GUSBCFG_TRDT_3 (0x8UL << USB_OTG_GUSBCFG_TRDT_Pos) /*!< 0x00002000 */ -#define USB_OTG_GUSBCFG_PHYLPCS_Pos (15U) -#define USB_OTG_GUSBCFG_PHYLPCS_Msk (0x1UL << USB_OTG_GUSBCFG_PHYLPCS_Pos) /*!< 0x00008000 */ -#define USB_OTG_GUSBCFG_PHYLPCS USB_OTG_GUSBCFG_PHYLPCS_Msk /*!< PHY Low-power clock select */ -#define USB_OTG_GUSBCFG_ULPIFSLS_Pos (17U) -#define USB_OTG_GUSBCFG_ULPIFSLS_Msk (0x1UL << USB_OTG_GUSBCFG_ULPIFSLS_Pos) /*!< 0x00020000 */ -#define USB_OTG_GUSBCFG_ULPIFSLS USB_OTG_GUSBCFG_ULPIFSLS_Msk /*!< ULPI FS/LS select */ -#define USB_OTG_GUSBCFG_ULPIAR_Pos (18U) -#define USB_OTG_GUSBCFG_ULPIAR_Msk (0x1UL << USB_OTG_GUSBCFG_ULPIAR_Pos) /*!< 0x00040000 */ -#define USB_OTG_GUSBCFG_ULPIAR USB_OTG_GUSBCFG_ULPIAR_Msk /*!< ULPI Auto-resume */ -#define USB_OTG_GUSBCFG_ULPICSM_Pos (19U) -#define USB_OTG_GUSBCFG_ULPICSM_Msk (0x1UL << USB_OTG_GUSBCFG_ULPICSM_Pos) /*!< 0x00080000 */ -#define USB_OTG_GUSBCFG_ULPICSM USB_OTG_GUSBCFG_ULPICSM_Msk /*!< ULPI Clock SuspendM */ -#define USB_OTG_GUSBCFG_ULPIEVBUSD_Pos (20U) -#define USB_OTG_GUSBCFG_ULPIEVBUSD_Msk (0x1UL << USB_OTG_GUSBCFG_ULPIEVBUSD_Pos) /*!< 0x00100000 */ -#define USB_OTG_GUSBCFG_ULPIEVBUSD USB_OTG_GUSBCFG_ULPIEVBUSD_Msk /*!< ULPI External VBUS Drive */ -#define USB_OTG_GUSBCFG_ULPIEVBUSI_Pos (21U) -#define USB_OTG_GUSBCFG_ULPIEVBUSI_Msk (0x1UL << USB_OTG_GUSBCFG_ULPIEVBUSI_Pos) /*!< 0x00200000 */ -#define USB_OTG_GUSBCFG_ULPIEVBUSI USB_OTG_GUSBCFG_ULPIEVBUSI_Msk /*!< ULPI external VBUS indicator */ -#define USB_OTG_GUSBCFG_TSDPS_Pos (22U) -#define USB_OTG_GUSBCFG_TSDPS_Msk (0x1UL << USB_OTG_GUSBCFG_TSDPS_Pos) /*!< 0x00400000 */ -#define USB_OTG_GUSBCFG_TSDPS USB_OTG_GUSBCFG_TSDPS_Msk /*!< TermSel DLine pulsing selection */ -#define USB_OTG_GUSBCFG_PCCI_Pos (23U) -#define USB_OTG_GUSBCFG_PCCI_Msk (0x1UL << USB_OTG_GUSBCFG_PCCI_Pos) /*!< 0x00800000 */ -#define USB_OTG_GUSBCFG_PCCI USB_OTG_GUSBCFG_PCCI_Msk /*!< Indicator complement */ -#define USB_OTG_GUSBCFG_PTCI_Pos (24U) -#define USB_OTG_GUSBCFG_PTCI_Msk (0x1UL << USB_OTG_GUSBCFG_PTCI_Pos) /*!< 0x01000000 */ -#define USB_OTG_GUSBCFG_PTCI USB_OTG_GUSBCFG_PTCI_Msk /*!< Indicator pass through */ -#define USB_OTG_GUSBCFG_ULPIIPD_Pos (25U) -#define USB_OTG_GUSBCFG_ULPIIPD_Msk (0x1UL << USB_OTG_GUSBCFG_ULPIIPD_Pos) /*!< 0x02000000 */ -#define USB_OTG_GUSBCFG_ULPIIPD USB_OTG_GUSBCFG_ULPIIPD_Msk /*!< ULPI interface protect disable */ -#define USB_OTG_GUSBCFG_FHMOD_Pos (29U) -#define USB_OTG_GUSBCFG_FHMOD_Msk (0x1UL << USB_OTG_GUSBCFG_FHMOD_Pos) /*!< 0x20000000 */ -#define USB_OTG_GUSBCFG_FHMOD USB_OTG_GUSBCFG_FHMOD_Msk /*!< Forced host mode */ -#define USB_OTG_GUSBCFG_FDMOD_Pos (30U) -#define USB_OTG_GUSBCFG_FDMOD_Msk (0x1UL << USB_OTG_GUSBCFG_FDMOD_Pos) /*!< 0x40000000 */ -#define USB_OTG_GUSBCFG_FDMOD USB_OTG_GUSBCFG_FDMOD_Msk /*!< Forced peripheral mode */ -#define USB_OTG_GUSBCFG_CTXPKT_Pos (31U) -#define USB_OTG_GUSBCFG_CTXPKT_Msk (0x1UL << USB_OTG_GUSBCFG_CTXPKT_Pos) /*!< 0x80000000 */ -#define USB_OTG_GUSBCFG_CTXPKT USB_OTG_GUSBCFG_CTXPKT_Msk /*!< Corrupt Tx packet */ - -/******************** Bit definition for USB_OTG_GRSTCTL register ********************/ -#define USB_OTG_GRSTCTL_CSRST_Pos (0U) -#define USB_OTG_GRSTCTL_CSRST_Msk (0x1UL << USB_OTG_GRSTCTL_CSRST_Pos) /*!< 0x00000001 */ -#define USB_OTG_GRSTCTL_CSRST USB_OTG_GRSTCTL_CSRST_Msk /*!< Core soft reset */ -#define USB_OTG_GRSTCTL_HSRST_Pos (1U) -#define USB_OTG_GRSTCTL_HSRST_Msk (0x1UL << USB_OTG_GRSTCTL_HSRST_Pos) /*!< 0x00000002 */ -#define USB_OTG_GRSTCTL_HSRST USB_OTG_GRSTCTL_HSRST_Msk /*!< HCLK soft reset */ -#define USB_OTG_GRSTCTL_FCRST_Pos (2U) -#define USB_OTG_GRSTCTL_FCRST_Msk (0x1UL << USB_OTG_GRSTCTL_FCRST_Pos) /*!< 0x00000004 */ -#define USB_OTG_GRSTCTL_FCRST USB_OTG_GRSTCTL_FCRST_Msk /*!< Host frame counter reset */ -#define USB_OTG_GRSTCTL_RXFFLSH_Pos (4U) -#define USB_OTG_GRSTCTL_RXFFLSH_Msk (0x1UL << USB_OTG_GRSTCTL_RXFFLSH_Pos) /*!< 0x00000010 */ -#define USB_OTG_GRSTCTL_RXFFLSH USB_OTG_GRSTCTL_RXFFLSH_Msk /*!< RxFIFO flush */ -#define USB_OTG_GRSTCTL_TXFFLSH_Pos (5U) -#define USB_OTG_GRSTCTL_TXFFLSH_Msk (0x1UL << USB_OTG_GRSTCTL_TXFFLSH_Pos) /*!< 0x00000020 */ -#define USB_OTG_GRSTCTL_TXFFLSH USB_OTG_GRSTCTL_TXFFLSH_Msk /*!< TxFIFO flush */ - - -#define USB_OTG_GRSTCTL_TXFNUM_Pos (6U) -#define USB_OTG_GRSTCTL_TXFNUM_Msk (0x1FUL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x000007C0 */ -#define USB_OTG_GRSTCTL_TXFNUM USB_OTG_GRSTCTL_TXFNUM_Msk /*!< TxFIFO number */ -#define USB_OTG_GRSTCTL_TXFNUM_0 (0x01UL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x00000040 */ -#define USB_OTG_GRSTCTL_TXFNUM_1 (0x02UL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x00000080 */ -#define USB_OTG_GRSTCTL_TXFNUM_2 (0x04UL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x00000100 */ -#define USB_OTG_GRSTCTL_TXFNUM_3 (0x08UL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x00000200 */ -#define USB_OTG_GRSTCTL_TXFNUM_4 (0x10UL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x00000400 */ -#define USB_OTG_GRSTCTL_DMAREQ_Pos (30U) -#define USB_OTG_GRSTCTL_DMAREQ_Msk (0x1UL << USB_OTG_GRSTCTL_DMAREQ_Pos) /*!< 0x40000000 */ -#define USB_OTG_GRSTCTL_DMAREQ USB_OTG_GRSTCTL_DMAREQ_Msk /*!< DMA request signal */ -#define USB_OTG_GRSTCTL_AHBIDL_Pos (31U) -#define USB_OTG_GRSTCTL_AHBIDL_Msk (0x1UL << USB_OTG_GRSTCTL_AHBIDL_Pos) /*!< 0x80000000 */ -#define USB_OTG_GRSTCTL_AHBIDL USB_OTG_GRSTCTL_AHBIDL_Msk /*!< AHB master idle */ - -/******************** Bit definition for USB_OTG_DIEPMSK register ********************/ -#define USB_OTG_DIEPMSK_XFRCM_Pos (0U) -#define USB_OTG_DIEPMSK_XFRCM_Msk (0x1UL << USB_OTG_DIEPMSK_XFRCM_Pos) /*!< 0x00000001 */ -#define USB_OTG_DIEPMSK_XFRCM USB_OTG_DIEPMSK_XFRCM_Msk /*!< Transfer completed interrupt mask */ -#define USB_OTG_DIEPMSK_EPDM_Pos (1U) -#define USB_OTG_DIEPMSK_EPDM_Msk (0x1UL << USB_OTG_DIEPMSK_EPDM_Pos) /*!< 0x00000002 */ -#define USB_OTG_DIEPMSK_EPDM USB_OTG_DIEPMSK_EPDM_Msk /*!< Endpoint disabled interrupt mask */ -#define USB_OTG_DIEPMSK_TOM_Pos (3U) -#define USB_OTG_DIEPMSK_TOM_Msk (0x1UL << USB_OTG_DIEPMSK_TOM_Pos) /*!< 0x00000008 */ -#define USB_OTG_DIEPMSK_TOM USB_OTG_DIEPMSK_TOM_Msk /*!< Timeout condition mask (nonisochronous endpoints) */ -#define USB_OTG_DIEPMSK_ITTXFEMSK_Pos (4U) -#define USB_OTG_DIEPMSK_ITTXFEMSK_Msk (0x1UL << USB_OTG_DIEPMSK_ITTXFEMSK_Pos) /*!< 0x00000010 */ -#define USB_OTG_DIEPMSK_ITTXFEMSK USB_OTG_DIEPMSK_ITTXFEMSK_Msk /*!< IN token received when TxFIFO empty mask */ -#define USB_OTG_DIEPMSK_INEPNMM_Pos (5U) -#define USB_OTG_DIEPMSK_INEPNMM_Msk (0x1UL << USB_OTG_DIEPMSK_INEPNMM_Pos) /*!< 0x00000020 */ -#define USB_OTG_DIEPMSK_INEPNMM USB_OTG_DIEPMSK_INEPNMM_Msk /*!< IN token received with EP mismatch mask */ -#define USB_OTG_DIEPMSK_INEPNEM_Pos (6U) -#define USB_OTG_DIEPMSK_INEPNEM_Msk (0x1UL << USB_OTG_DIEPMSK_INEPNEM_Pos) /*!< 0x00000040 */ -#define USB_OTG_DIEPMSK_INEPNEM USB_OTG_DIEPMSK_INEPNEM_Msk /*!< IN endpoint NAK effective mask */ -#define USB_OTG_DIEPMSK_TXFURM_Pos (8U) -#define USB_OTG_DIEPMSK_TXFURM_Msk (0x1UL << USB_OTG_DIEPMSK_TXFURM_Pos) /*!< 0x00000100 */ -#define USB_OTG_DIEPMSK_TXFURM USB_OTG_DIEPMSK_TXFURM_Msk /*!< FIFO underrun mask */ -#define USB_OTG_DIEPMSK_BIM_Pos (9U) -#define USB_OTG_DIEPMSK_BIM_Msk (0x1UL << USB_OTG_DIEPMSK_BIM_Pos) /*!< 0x00000200 */ -#define USB_OTG_DIEPMSK_BIM USB_OTG_DIEPMSK_BIM_Msk /*!< BNA interrupt mask */ - -/******************** Bit definition for USB_OTG_HPTXSTS register ********************/ -#define USB_OTG_HPTXSTS_PTXFSAVL_Pos (0U) -#define USB_OTG_HPTXSTS_PTXFSAVL_Msk (0xFFFFUL << USB_OTG_HPTXSTS_PTXFSAVL_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_HPTXSTS_PTXFSAVL USB_OTG_HPTXSTS_PTXFSAVL_Msk /*!< Periodic transmit data FIFO space available */ -#define USB_OTG_HPTXSTS_PTXQSAV_Pos (16U) -#define USB_OTG_HPTXSTS_PTXQSAV_Msk (0xFFUL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00FF0000 */ -#define USB_OTG_HPTXSTS_PTXQSAV USB_OTG_HPTXSTS_PTXQSAV_Msk /*!< Periodic transmit request queue space available */ -#define USB_OTG_HPTXSTS_PTXQSAV_0 (0x01UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00010000 */ -#define USB_OTG_HPTXSTS_PTXQSAV_1 (0x02UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00020000 */ -#define USB_OTG_HPTXSTS_PTXQSAV_2 (0x04UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00040000 */ -#define USB_OTG_HPTXSTS_PTXQSAV_3 (0x08UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00080000 */ -#define USB_OTG_HPTXSTS_PTXQSAV_4 (0x10UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00100000 */ -#define USB_OTG_HPTXSTS_PTXQSAV_5 (0x20UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00200000 */ -#define USB_OTG_HPTXSTS_PTXQSAV_6 (0x40UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00400000 */ -#define USB_OTG_HPTXSTS_PTXQSAV_7 (0x80UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00800000 */ - -#define USB_OTG_HPTXSTS_PTXQTOP_Pos (24U) -#define USB_OTG_HPTXSTS_PTXQTOP_Msk (0xFFUL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0xFF000000 */ -#define USB_OTG_HPTXSTS_PTXQTOP USB_OTG_HPTXSTS_PTXQTOP_Msk /*!< Top of the periodic transmit request queue */ -#define USB_OTG_HPTXSTS_PTXQTOP_0 (0x01UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x01000000 */ -#define USB_OTG_HPTXSTS_PTXQTOP_1 (0x02UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x02000000 */ -#define USB_OTG_HPTXSTS_PTXQTOP_2 (0x04UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x04000000 */ -#define USB_OTG_HPTXSTS_PTXQTOP_3 (0x08UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x08000000 */ -#define USB_OTG_HPTXSTS_PTXQTOP_4 (0x10UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x10000000 */ -#define USB_OTG_HPTXSTS_PTXQTOP_5 (0x20UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x20000000 */ -#define USB_OTG_HPTXSTS_PTXQTOP_6 (0x40UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x40000000 */ -#define USB_OTG_HPTXSTS_PTXQTOP_7 (0x80UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x80000000 */ - -/******************** Bit definition for USB_OTG_HAINT register ********************/ -#define USB_OTG_HAINT_HAINT_Pos (0U) -#define USB_OTG_HAINT_HAINT_Msk (0xFFFFUL << USB_OTG_HAINT_HAINT_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_HAINT_HAINT USB_OTG_HAINT_HAINT_Msk /*!< Channel interrupts */ - -/******************** Bit definition for USB_OTG_DOEPMSK register ********************/ -#define USB_OTG_DOEPMSK_XFRCM_Pos (0U) -#define USB_OTG_DOEPMSK_XFRCM_Msk (0x1UL << USB_OTG_DOEPMSK_XFRCM_Pos) /*!< 0x00000001 */ -#define USB_OTG_DOEPMSK_XFRCM USB_OTG_DOEPMSK_XFRCM_Msk /*!< Transfer completed interrupt mask */ -#define USB_OTG_DOEPMSK_EPDM_Pos (1U) -#define USB_OTG_DOEPMSK_EPDM_Msk (0x1UL << USB_OTG_DOEPMSK_EPDM_Pos) /*!< 0x00000002 */ -#define USB_OTG_DOEPMSK_EPDM USB_OTG_DOEPMSK_EPDM_Msk /*!< Endpoint disabled interrupt mask */ -#define USB_OTG_DOEPMSK_AHBERRM_Pos (2U) -#define USB_OTG_DOEPMSK_AHBERRM_Msk (0x1UL << USB_OTG_DOEPMSK_AHBERRM_Pos) /*!< 0x00000004 */ -#define USB_OTG_DOEPMSK_AHBERRM USB_OTG_DOEPMSK_AHBERRM_Msk /*!< OUT transaction AHB Error interrupt mask */ -#define USB_OTG_DOEPMSK_STUPM_Pos (3U) -#define USB_OTG_DOEPMSK_STUPM_Msk (0x1UL << USB_OTG_DOEPMSK_STUPM_Pos) /*!< 0x00000008 */ -#define USB_OTG_DOEPMSK_STUPM USB_OTG_DOEPMSK_STUPM_Msk /*!< SETUP phase done mask */ -#define USB_OTG_DOEPMSK_OTEPDM_Pos (4U) -#define USB_OTG_DOEPMSK_OTEPDM_Msk (0x1UL << USB_OTG_DOEPMSK_OTEPDM_Pos) /*!< 0x00000010 */ -#define USB_OTG_DOEPMSK_OTEPDM USB_OTG_DOEPMSK_OTEPDM_Msk /*!< OUT token received when endpoint disabled mask */ -#define USB_OTG_DOEPMSK_OTEPSPRM_Pos (5U) -#define USB_OTG_DOEPMSK_OTEPSPRM_Msk (0x1UL << USB_OTG_DOEPMSK_OTEPSPRM_Pos) /*!< 0x00000020 */ -#define USB_OTG_DOEPMSK_OTEPSPRM USB_OTG_DOEPMSK_OTEPSPRM_Msk /*!< Status Phase Received mask */ -#define USB_OTG_DOEPMSK_B2BSTUP_Pos (6U) -#define USB_OTG_DOEPMSK_B2BSTUP_Msk (0x1UL << USB_OTG_DOEPMSK_B2BSTUP_Pos) /*!< 0x00000040 */ -#define USB_OTG_DOEPMSK_B2BSTUP USB_OTG_DOEPMSK_B2BSTUP_Msk /*!< Back-to-back SETUP packets received mask */ -#define USB_OTG_DOEPMSK_OPEM_Pos (8U) -#define USB_OTG_DOEPMSK_OPEM_Msk (0x1UL << USB_OTG_DOEPMSK_OPEM_Pos) /*!< 0x00000100 */ -#define USB_OTG_DOEPMSK_OPEM USB_OTG_DOEPMSK_OPEM_Msk /*!< OUT packet error mask */ -#define USB_OTG_DOEPMSK_BOIM_Pos (9U) -#define USB_OTG_DOEPMSK_BOIM_Msk (0x1UL << USB_OTG_DOEPMSK_BOIM_Pos) /*!< 0x00000200 */ -#define USB_OTG_DOEPMSK_BOIM USB_OTG_DOEPMSK_BOIM_Msk /*!< BNA interrupt mask */ -#define USB_OTG_DOEPMSK_BERRM_Pos (12U) -#define USB_OTG_DOEPMSK_BERRM_Msk (0x1UL << USB_OTG_DOEPMSK_BERRM_Pos) /*!< 0x00001000 */ -#define USB_OTG_DOEPMSK_BERRM USB_OTG_DOEPMSK_BERRM_Msk /*!< Babble error interrupt mask */ -#define USB_OTG_DOEPMSK_NAKM_Pos (13U) -#define USB_OTG_DOEPMSK_NAKM_Msk (0x1UL << USB_OTG_DOEPMSK_NAKM_Pos) /*!< 0x00002000 */ -#define USB_OTG_DOEPMSK_NAKM USB_OTG_DOEPMSK_NAKM_Msk /*!< OUT Packet NAK interrupt mask */ -#define USB_OTG_DOEPMSK_NYETM_Pos (14U) -#define USB_OTG_DOEPMSK_NYETM_Msk (0x1UL << USB_OTG_DOEPMSK_NYETM_Pos) /*!< 0x00004000 */ -#define USB_OTG_DOEPMSK_NYETM USB_OTG_DOEPMSK_NYETM_Msk /*!< NYET interrupt mask */ -/******************** Bit definition for USB_OTG_GINTSTS register ********************/ -#define USB_OTG_GINTSTS_CMOD_Pos (0U) -#define USB_OTG_GINTSTS_CMOD_Msk (0x1UL << USB_OTG_GINTSTS_CMOD_Pos) /*!< 0x00000001 */ -#define USB_OTG_GINTSTS_CMOD USB_OTG_GINTSTS_CMOD_Msk /*!< Current mode of operation */ -#define USB_OTG_GINTSTS_MMIS_Pos (1U) -#define USB_OTG_GINTSTS_MMIS_Msk (0x1UL << USB_OTG_GINTSTS_MMIS_Pos) /*!< 0x00000002 */ -#define USB_OTG_GINTSTS_MMIS USB_OTG_GINTSTS_MMIS_Msk /*!< Mode mismatch interrupt */ -#define USB_OTG_GINTSTS_OTGINT_Pos (2U) -#define USB_OTG_GINTSTS_OTGINT_Msk (0x1UL << USB_OTG_GINTSTS_OTGINT_Pos) /*!< 0x00000004 */ -#define USB_OTG_GINTSTS_OTGINT USB_OTG_GINTSTS_OTGINT_Msk /*!< OTG interrupt */ -#define USB_OTG_GINTSTS_SOF_Pos (3U) -#define USB_OTG_GINTSTS_SOF_Msk (0x1UL << USB_OTG_GINTSTS_SOF_Pos) /*!< 0x00000008 */ -#define USB_OTG_GINTSTS_SOF USB_OTG_GINTSTS_SOF_Msk /*!< Start of frame */ -#define USB_OTG_GINTSTS_RXFLVL_Pos (4U) -#define USB_OTG_GINTSTS_RXFLVL_Msk (0x1UL << USB_OTG_GINTSTS_RXFLVL_Pos) /*!< 0x00000010 */ -#define USB_OTG_GINTSTS_RXFLVL USB_OTG_GINTSTS_RXFLVL_Msk /*!< RxFIFO nonempty */ -#define USB_OTG_GINTSTS_NPTXFE_Pos (5U) -#define USB_OTG_GINTSTS_NPTXFE_Msk (0x1UL << USB_OTG_GINTSTS_NPTXFE_Pos) /*!< 0x00000020 */ -#define USB_OTG_GINTSTS_NPTXFE USB_OTG_GINTSTS_NPTXFE_Msk /*!< Nonperiodic TxFIFO empty */ -#define USB_OTG_GINTSTS_GINAKEFF_Pos (6U) -#define USB_OTG_GINTSTS_GINAKEFF_Msk (0x1UL << USB_OTG_GINTSTS_GINAKEFF_Pos) /*!< 0x00000040 */ -#define USB_OTG_GINTSTS_GINAKEFF USB_OTG_GINTSTS_GINAKEFF_Msk /*!< Global IN nonperiodic NAK effective */ -#define USB_OTG_GINTSTS_BOUTNAKEFF_Pos (7U) -#define USB_OTG_GINTSTS_BOUTNAKEFF_Msk (0x1UL << USB_OTG_GINTSTS_BOUTNAKEFF_Pos) /*!< 0x00000080 */ -#define USB_OTG_GINTSTS_BOUTNAKEFF USB_OTG_GINTSTS_BOUTNAKEFF_Msk /*!< Global OUT NAK effective */ -#define USB_OTG_GINTSTS_ESUSP_Pos (10U) -#define USB_OTG_GINTSTS_ESUSP_Msk (0x1UL << USB_OTG_GINTSTS_ESUSP_Pos) /*!< 0x00000400 */ -#define USB_OTG_GINTSTS_ESUSP USB_OTG_GINTSTS_ESUSP_Msk /*!< Early suspend */ -#define USB_OTG_GINTSTS_USBSUSP_Pos (11U) -#define USB_OTG_GINTSTS_USBSUSP_Msk (0x1UL << USB_OTG_GINTSTS_USBSUSP_Pos) /*!< 0x00000800 */ -#define USB_OTG_GINTSTS_USBSUSP USB_OTG_GINTSTS_USBSUSP_Msk /*!< USB suspend */ -#define USB_OTG_GINTSTS_USBRST_Pos (12U) -#define USB_OTG_GINTSTS_USBRST_Msk (0x1UL << USB_OTG_GINTSTS_USBRST_Pos) /*!< 0x00001000 */ -#define USB_OTG_GINTSTS_USBRST USB_OTG_GINTSTS_USBRST_Msk /*!< USB reset */ -#define USB_OTG_GINTSTS_ENUMDNE_Pos (13U) -#define USB_OTG_GINTSTS_ENUMDNE_Msk (0x1UL << USB_OTG_GINTSTS_ENUMDNE_Pos) /*!< 0x00002000 */ -#define USB_OTG_GINTSTS_ENUMDNE USB_OTG_GINTSTS_ENUMDNE_Msk /*!< Enumeration done */ -#define USB_OTG_GINTSTS_ISOODRP_Pos (14U) -#define USB_OTG_GINTSTS_ISOODRP_Msk (0x1UL << USB_OTG_GINTSTS_ISOODRP_Pos) /*!< 0x00004000 */ -#define USB_OTG_GINTSTS_ISOODRP USB_OTG_GINTSTS_ISOODRP_Msk /*!< Isochronous OUT packet dropped interrupt */ -#define USB_OTG_GINTSTS_EOPF_Pos (15U) -#define USB_OTG_GINTSTS_EOPF_Msk (0x1UL << USB_OTG_GINTSTS_EOPF_Pos) /*!< 0x00008000 */ -#define USB_OTG_GINTSTS_EOPF USB_OTG_GINTSTS_EOPF_Msk /*!< End of periodic frame interrupt */ -#define USB_OTG_GINTSTS_IEPINT_Pos (18U) -#define USB_OTG_GINTSTS_IEPINT_Msk (0x1UL << USB_OTG_GINTSTS_IEPINT_Pos) /*!< 0x00040000 */ -#define USB_OTG_GINTSTS_IEPINT USB_OTG_GINTSTS_IEPINT_Msk /*!< IN endpoint interrupt */ -#define USB_OTG_GINTSTS_OEPINT_Pos (19U) -#define USB_OTG_GINTSTS_OEPINT_Msk (0x1UL << USB_OTG_GINTSTS_OEPINT_Pos) /*!< 0x00080000 */ -#define USB_OTG_GINTSTS_OEPINT USB_OTG_GINTSTS_OEPINT_Msk /*!< OUT endpoint interrupt */ -#define USB_OTG_GINTSTS_IISOIXFR_Pos (20U) -#define USB_OTG_GINTSTS_IISOIXFR_Msk (0x1UL << USB_OTG_GINTSTS_IISOIXFR_Pos) /*!< 0x00100000 */ -#define USB_OTG_GINTSTS_IISOIXFR USB_OTG_GINTSTS_IISOIXFR_Msk /*!< Incomplete isochronous IN transfer */ -#define USB_OTG_GINTSTS_PXFR_INCOMPISOOUT_Pos (21U) -#define USB_OTG_GINTSTS_PXFR_INCOMPISOOUT_Msk (0x1UL << USB_OTG_GINTSTS_PXFR_INCOMPISOOUT_Pos) /*!< 0x00200000 */ -#define USB_OTG_GINTSTS_PXFR_INCOMPISOOUT USB_OTG_GINTSTS_PXFR_INCOMPISOOUT_Msk /*!< Incomplete periodic transfer */ -#define USB_OTG_GINTSTS_DATAFSUSP_Pos (22U) -#define USB_OTG_GINTSTS_DATAFSUSP_Msk (0x1UL << USB_OTG_GINTSTS_DATAFSUSP_Pos) /*!< 0x00400000 */ -#define USB_OTG_GINTSTS_DATAFSUSP USB_OTG_GINTSTS_DATAFSUSP_Msk /*!< Data fetch suspended */ -#define USB_OTG_GINTSTS_HPRTINT_Pos (24U) -#define USB_OTG_GINTSTS_HPRTINT_Msk (0x1UL << USB_OTG_GINTSTS_HPRTINT_Pos) /*!< 0x01000000 */ -#define USB_OTG_GINTSTS_HPRTINT USB_OTG_GINTSTS_HPRTINT_Msk /*!< Host port interrupt */ -#define USB_OTG_GINTSTS_HCINT_Pos (25U) -#define USB_OTG_GINTSTS_HCINT_Msk (0x1UL << USB_OTG_GINTSTS_HCINT_Pos) /*!< 0x02000000 */ -#define USB_OTG_GINTSTS_HCINT USB_OTG_GINTSTS_HCINT_Msk /*!< Host channels interrupt */ -#define USB_OTG_GINTSTS_PTXFE_Pos (26U) -#define USB_OTG_GINTSTS_PTXFE_Msk (0x1UL << USB_OTG_GINTSTS_PTXFE_Pos) /*!< 0x04000000 */ -#define USB_OTG_GINTSTS_PTXFE USB_OTG_GINTSTS_PTXFE_Msk /*!< Periodic TxFIFO empty */ -#define USB_OTG_GINTSTS_CIDSCHG_Pos (28U) -#define USB_OTG_GINTSTS_CIDSCHG_Msk (0x1UL << USB_OTG_GINTSTS_CIDSCHG_Pos) /*!< 0x10000000 */ -#define USB_OTG_GINTSTS_CIDSCHG USB_OTG_GINTSTS_CIDSCHG_Msk /*!< Connector ID status change */ -#define USB_OTG_GINTSTS_DISCINT_Pos (29U) -#define USB_OTG_GINTSTS_DISCINT_Msk (0x1UL << USB_OTG_GINTSTS_DISCINT_Pos) /*!< 0x20000000 */ -#define USB_OTG_GINTSTS_DISCINT USB_OTG_GINTSTS_DISCINT_Msk /*!< Disconnect detected interrupt */ -#define USB_OTG_GINTSTS_SRQINT_Pos (30U) -#define USB_OTG_GINTSTS_SRQINT_Msk (0x1UL << USB_OTG_GINTSTS_SRQINT_Pos) /*!< 0x40000000 */ -#define USB_OTG_GINTSTS_SRQINT USB_OTG_GINTSTS_SRQINT_Msk /*!< Session request/new session detected interrupt */ -#define USB_OTG_GINTSTS_WKUINT_Pos (31U) -#define USB_OTG_GINTSTS_WKUINT_Msk (0x1UL << USB_OTG_GINTSTS_WKUINT_Pos) /*!< 0x80000000 */ -#define USB_OTG_GINTSTS_WKUINT USB_OTG_GINTSTS_WKUINT_Msk /*!< Resume/remote wakeup detected interrupt */ - -/******************** Bit definition for USB_OTG_GINTMSK register ********************/ -#define USB_OTG_GINTMSK_MMISM_Pos (1U) -#define USB_OTG_GINTMSK_MMISM_Msk (0x1UL << USB_OTG_GINTMSK_MMISM_Pos) /*!< 0x00000002 */ -#define USB_OTG_GINTMSK_MMISM USB_OTG_GINTMSK_MMISM_Msk /*!< Mode mismatch interrupt mask */ -#define USB_OTG_GINTMSK_OTGINT_Pos (2U) -#define USB_OTG_GINTMSK_OTGINT_Msk (0x1UL << USB_OTG_GINTMSK_OTGINT_Pos) /*!< 0x00000004 */ -#define USB_OTG_GINTMSK_OTGINT USB_OTG_GINTMSK_OTGINT_Msk /*!< OTG interrupt mask */ -#define USB_OTG_GINTMSK_SOFM_Pos (3U) -#define USB_OTG_GINTMSK_SOFM_Msk (0x1UL << USB_OTG_GINTMSK_SOFM_Pos) /*!< 0x00000008 */ -#define USB_OTG_GINTMSK_SOFM USB_OTG_GINTMSK_SOFM_Msk /*!< Start of frame mask */ -#define USB_OTG_GINTMSK_RXFLVLM_Pos (4U) -#define USB_OTG_GINTMSK_RXFLVLM_Msk (0x1UL << USB_OTG_GINTMSK_RXFLVLM_Pos) /*!< 0x00000010 */ -#define USB_OTG_GINTMSK_RXFLVLM USB_OTG_GINTMSK_RXFLVLM_Msk /*!< Receive FIFO nonempty mask */ -#define USB_OTG_GINTMSK_NPTXFEM_Pos (5U) -#define USB_OTG_GINTMSK_NPTXFEM_Msk (0x1UL << USB_OTG_GINTMSK_NPTXFEM_Pos) /*!< 0x00000020 */ -#define USB_OTG_GINTMSK_NPTXFEM USB_OTG_GINTMSK_NPTXFEM_Msk /*!< Nonperiodic TxFIFO empty mask */ -#define USB_OTG_GINTMSK_GINAKEFFM_Pos (6U) -#define USB_OTG_GINTMSK_GINAKEFFM_Msk (0x1UL << USB_OTG_GINTMSK_GINAKEFFM_Pos) /*!< 0x00000040 */ -#define USB_OTG_GINTMSK_GINAKEFFM USB_OTG_GINTMSK_GINAKEFFM_Msk /*!< Global nonperiodic IN NAK effective mask */ -#define USB_OTG_GINTMSK_GONAKEFFM_Pos (7U) -#define USB_OTG_GINTMSK_GONAKEFFM_Msk (0x1UL << USB_OTG_GINTMSK_GONAKEFFM_Pos) /*!< 0x00000080 */ -#define USB_OTG_GINTMSK_GONAKEFFM USB_OTG_GINTMSK_GONAKEFFM_Msk /*!< Global OUT NAK effective mask */ -#define USB_OTG_GINTMSK_ESUSPM_Pos (10U) -#define USB_OTG_GINTMSK_ESUSPM_Msk (0x1UL << USB_OTG_GINTMSK_ESUSPM_Pos) /*!< 0x00000400 */ -#define USB_OTG_GINTMSK_ESUSPM USB_OTG_GINTMSK_ESUSPM_Msk /*!< Early suspend mask */ -#define USB_OTG_GINTMSK_USBSUSPM_Pos (11U) -#define USB_OTG_GINTMSK_USBSUSPM_Msk (0x1UL << USB_OTG_GINTMSK_USBSUSPM_Pos) /*!< 0x00000800 */ -#define USB_OTG_GINTMSK_USBSUSPM USB_OTG_GINTMSK_USBSUSPM_Msk /*!< USB suspend mask */ -#define USB_OTG_GINTMSK_USBRST_Pos (12U) -#define USB_OTG_GINTMSK_USBRST_Msk (0x1UL << USB_OTG_GINTMSK_USBRST_Pos) /*!< 0x00001000 */ -#define USB_OTG_GINTMSK_USBRST USB_OTG_GINTMSK_USBRST_Msk /*!< USB reset mask */ -#define USB_OTG_GINTMSK_ENUMDNEM_Pos (13U) -#define USB_OTG_GINTMSK_ENUMDNEM_Msk (0x1UL << USB_OTG_GINTMSK_ENUMDNEM_Pos) /*!< 0x00002000 */ -#define USB_OTG_GINTMSK_ENUMDNEM USB_OTG_GINTMSK_ENUMDNEM_Msk /*!< Enumeration done mask */ -#define USB_OTG_GINTMSK_ISOODRPM_Pos (14U) -#define USB_OTG_GINTMSK_ISOODRPM_Msk (0x1UL << USB_OTG_GINTMSK_ISOODRPM_Pos) /*!< 0x00004000 */ -#define USB_OTG_GINTMSK_ISOODRPM USB_OTG_GINTMSK_ISOODRPM_Msk /*!< Isochronous OUT packet dropped interrupt mask */ -#define USB_OTG_GINTMSK_EOPFM_Pos (15U) -#define USB_OTG_GINTMSK_EOPFM_Msk (0x1UL << USB_OTG_GINTMSK_EOPFM_Pos) /*!< 0x00008000 */ -#define USB_OTG_GINTMSK_EOPFM USB_OTG_GINTMSK_EOPFM_Msk /*!< End of periodic frame interrupt mask */ -#define USB_OTG_GINTMSK_EPMISM_Pos (17U) -#define USB_OTG_GINTMSK_EPMISM_Msk (0x1UL << USB_OTG_GINTMSK_EPMISM_Pos) /*!< 0x00020000 */ -#define USB_OTG_GINTMSK_EPMISM USB_OTG_GINTMSK_EPMISM_Msk /*!< Endpoint mismatch interrupt mask */ -#define USB_OTG_GINTMSK_IEPINT_Pos (18U) -#define USB_OTG_GINTMSK_IEPINT_Msk (0x1UL << USB_OTG_GINTMSK_IEPINT_Pos) /*!< 0x00040000 */ -#define USB_OTG_GINTMSK_IEPINT USB_OTG_GINTMSK_IEPINT_Msk /*!< IN endpoints interrupt mask */ -#define USB_OTG_GINTMSK_OEPINT_Pos (19U) -#define USB_OTG_GINTMSK_OEPINT_Msk (0x1UL << USB_OTG_GINTMSK_OEPINT_Pos) /*!< 0x00080000 */ -#define USB_OTG_GINTMSK_OEPINT USB_OTG_GINTMSK_OEPINT_Msk /*!< OUT endpoints interrupt mask */ -#define USB_OTG_GINTMSK_IISOIXFRM_Pos (20U) -#define USB_OTG_GINTMSK_IISOIXFRM_Msk (0x1UL << USB_OTG_GINTMSK_IISOIXFRM_Pos) /*!< 0x00100000 */ -#define USB_OTG_GINTMSK_IISOIXFRM USB_OTG_GINTMSK_IISOIXFRM_Msk /*!< Incomplete isochronous IN transfer mask */ -#define USB_OTG_GINTMSK_PXFRM_IISOOXFRM_Pos (21U) -#define USB_OTG_GINTMSK_PXFRM_IISOOXFRM_Msk (0x1UL << USB_OTG_GINTMSK_PXFRM_IISOOXFRM_Pos) /*!< 0x00200000 */ -#define USB_OTG_GINTMSK_PXFRM_IISOOXFRM USB_OTG_GINTMSK_PXFRM_IISOOXFRM_Msk /*!< Incomplete periodic transfer mask */ -#define USB_OTG_GINTMSK_FSUSPM_Pos (22U) -#define USB_OTG_GINTMSK_FSUSPM_Msk (0x1UL << USB_OTG_GINTMSK_FSUSPM_Pos) /*!< 0x00400000 */ -#define USB_OTG_GINTMSK_FSUSPM USB_OTG_GINTMSK_FSUSPM_Msk /*!< Data fetch suspended mask */ -#define USB_OTG_GINTMSK_PRTIM_Pos (24U) -#define USB_OTG_GINTMSK_PRTIM_Msk (0x1UL << USB_OTG_GINTMSK_PRTIM_Pos) /*!< 0x01000000 */ -#define USB_OTG_GINTMSK_PRTIM USB_OTG_GINTMSK_PRTIM_Msk /*!< Host port interrupt mask */ -#define USB_OTG_GINTMSK_HCIM_Pos (25U) -#define USB_OTG_GINTMSK_HCIM_Msk (0x1UL << USB_OTG_GINTMSK_HCIM_Pos) /*!< 0x02000000 */ -#define USB_OTG_GINTMSK_HCIM USB_OTG_GINTMSK_HCIM_Msk /*!< Host channels interrupt mask */ -#define USB_OTG_GINTMSK_PTXFEM_Pos (26U) -#define USB_OTG_GINTMSK_PTXFEM_Msk (0x1UL << USB_OTG_GINTMSK_PTXFEM_Pos) /*!< 0x04000000 */ -#define USB_OTG_GINTMSK_PTXFEM USB_OTG_GINTMSK_PTXFEM_Msk /*!< Periodic TxFIFO empty mask */ -#define USB_OTG_GINTMSK_CIDSCHGM_Pos (28U) -#define USB_OTG_GINTMSK_CIDSCHGM_Msk (0x1UL << USB_OTG_GINTMSK_CIDSCHGM_Pos) /*!< 0x10000000 */ -#define USB_OTG_GINTMSK_CIDSCHGM USB_OTG_GINTMSK_CIDSCHGM_Msk /*!< Connector ID status change mask */ -#define USB_OTG_GINTMSK_DISCINT_Pos (29U) -#define USB_OTG_GINTMSK_DISCINT_Msk (0x1UL << USB_OTG_GINTMSK_DISCINT_Pos) /*!< 0x20000000 */ -#define USB_OTG_GINTMSK_DISCINT USB_OTG_GINTMSK_DISCINT_Msk /*!< Disconnect detected interrupt mask */ -#define USB_OTG_GINTMSK_SRQIM_Pos (30U) -#define USB_OTG_GINTMSK_SRQIM_Msk (0x1UL << USB_OTG_GINTMSK_SRQIM_Pos) /*!< 0x40000000 */ -#define USB_OTG_GINTMSK_SRQIM USB_OTG_GINTMSK_SRQIM_Msk /*!< Session request/new session detected interrupt mask */ -#define USB_OTG_GINTMSK_WUIM_Pos (31U) -#define USB_OTG_GINTMSK_WUIM_Msk (0x1UL << USB_OTG_GINTMSK_WUIM_Pos) /*!< 0x80000000 */ -#define USB_OTG_GINTMSK_WUIM USB_OTG_GINTMSK_WUIM_Msk /*!< Resume/remote wakeup detected interrupt mask */ - -/******************** Bit definition for USB_OTG_DAINT register ********************/ -#define USB_OTG_DAINT_IEPINT_Pos (0U) -#define USB_OTG_DAINT_IEPINT_Msk (0xFFFFUL << USB_OTG_DAINT_IEPINT_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_DAINT_IEPINT USB_OTG_DAINT_IEPINT_Msk /*!< IN endpoint interrupt bits */ -#define USB_OTG_DAINT_OEPINT_Pos (16U) -#define USB_OTG_DAINT_OEPINT_Msk (0xFFFFUL << USB_OTG_DAINT_OEPINT_Pos) /*!< 0xFFFF0000 */ -#define USB_OTG_DAINT_OEPINT USB_OTG_DAINT_OEPINT_Msk /*!< OUT endpoint interrupt bits */ - -/******************** Bit definition for USB_OTG_HAINTMSK register ********************/ -#define USB_OTG_HAINTMSK_HAINTM_Pos (0U) -#define USB_OTG_HAINTMSK_HAINTM_Msk (0xFFFFUL << USB_OTG_HAINTMSK_HAINTM_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_HAINTMSK_HAINTM USB_OTG_HAINTMSK_HAINTM_Msk /*!< Channel interrupt mask */ - -/******************** Bit definition for USB_OTG_GRXSTSP register ********************/ -#define USB_OTG_GRXSTSP_EPNUM_Pos (0U) -#define USB_OTG_GRXSTSP_EPNUM_Msk (0xFUL << USB_OTG_GRXSTSP_EPNUM_Pos) /*!< 0x0000000F */ -#define USB_OTG_GRXSTSP_EPNUM USB_OTG_GRXSTSP_EPNUM_Msk /*!< IN EP interrupt mask bits */ -#define USB_OTG_GRXSTSP_BCNT_Pos (4U) -#define USB_OTG_GRXSTSP_BCNT_Msk (0x7FFUL << USB_OTG_GRXSTSP_BCNT_Pos) /*!< 0x00007FF0 */ -#define USB_OTG_GRXSTSP_BCNT USB_OTG_GRXSTSP_BCNT_Msk /*!< OUT EP interrupt mask bits */ -#define USB_OTG_GRXSTSP_DPID_Pos (15U) -#define USB_OTG_GRXSTSP_DPID_Msk (0x3UL << USB_OTG_GRXSTSP_DPID_Pos) /*!< 0x00018000 */ -#define USB_OTG_GRXSTSP_DPID USB_OTG_GRXSTSP_DPID_Msk /*!< OUT EP interrupt mask bits */ -#define USB_OTG_GRXSTSP_PKTSTS_Pos (17U) -#define USB_OTG_GRXSTSP_PKTSTS_Msk (0xFUL << USB_OTG_GRXSTSP_PKTSTS_Pos) /*!< 0x001E0000 */ -#define USB_OTG_GRXSTSP_PKTSTS USB_OTG_GRXSTSP_PKTSTS_Msk /*!< OUT EP interrupt mask bits */ - -/******************** Bit definition for USB_OTG_DAINTMSK register ********************/ -#define USB_OTG_DAINTMSK_IEPM_Pos (0U) -#define USB_OTG_DAINTMSK_IEPM_Msk (0xFFFFUL << USB_OTG_DAINTMSK_IEPM_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_DAINTMSK_IEPM USB_OTG_DAINTMSK_IEPM_Msk /*!< IN EP interrupt mask bits */ -#define USB_OTG_DAINTMSK_OEPM_Pos (16U) -#define USB_OTG_DAINTMSK_OEPM_Msk (0xFFFFUL << USB_OTG_DAINTMSK_OEPM_Pos) /*!< 0xFFFF0000 */ -#define USB_OTG_DAINTMSK_OEPM USB_OTG_DAINTMSK_OEPM_Msk /*!< OUT EP interrupt mask bits */ - -/******************** Bit definition for USB_OTG_GRXFSIZ register ********************/ -#define USB_OTG_GRXFSIZ_RXFD_Pos (0U) -#define USB_OTG_GRXFSIZ_RXFD_Msk (0xFFFFUL << USB_OTG_GRXFSIZ_RXFD_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_GRXFSIZ_RXFD USB_OTG_GRXFSIZ_RXFD_Msk /*!< RxFIFO depth */ - -/******************** Bit definition for USB_OTG_DVBUSDIS register ********************/ -#define USB_OTG_DVBUSDIS_VBUSDT_Pos (0U) -#define USB_OTG_DVBUSDIS_VBUSDT_Msk (0xFFFFUL << USB_OTG_DVBUSDIS_VBUSDT_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_DVBUSDIS_VBUSDT USB_OTG_DVBUSDIS_VBUSDT_Msk /*!< Device VBUS discharge time */ - -/******************** Bit definition for OTG register ********************/ -#define USB_OTG_NPTXFSA_Pos (0U) -#define USB_OTG_NPTXFSA_Msk (0xFFFFUL << USB_OTG_NPTXFSA_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_NPTXFSA USB_OTG_NPTXFSA_Msk /*!< Nonperiodic transmit RAM start address */ -#define USB_OTG_NPTXFD_Pos (16U) -#define USB_OTG_NPTXFD_Msk (0xFFFFUL << USB_OTG_NPTXFD_Pos) /*!< 0xFFFF0000 */ -#define USB_OTG_NPTXFD USB_OTG_NPTXFD_Msk /*!< Nonperiodic TxFIFO depth */ -#define USB_OTG_TX0FSA_Pos (0U) -#define USB_OTG_TX0FSA_Msk (0xFFFFUL << USB_OTG_TX0FSA_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_TX0FSA USB_OTG_TX0FSA_Msk /*!< Endpoint 0 transmit RAM start address */ -#define USB_OTG_TX0FD_Pos (16U) -#define USB_OTG_TX0FD_Msk (0xFFFFUL << USB_OTG_TX0FD_Pos) /*!< 0xFFFF0000 */ -#define USB_OTG_TX0FD USB_OTG_TX0FD_Msk /*!< Endpoint 0 TxFIFO depth */ - -/******************** Bit definition for USB_OTG_DVBUSPULSE register ********************/ -#define USB_OTG_DVBUSPULSE_DVBUSP_Pos (0U) -#define USB_OTG_DVBUSPULSE_DVBUSP_Msk (0xFFFUL << USB_OTG_DVBUSPULSE_DVBUSP_Pos) /*!< 0x00000FFF */ -#define USB_OTG_DVBUSPULSE_DVBUSP USB_OTG_DVBUSPULSE_DVBUSP_Msk /*!< Device VBUS pulsing time */ - -/******************** Bit definition for USB_OTG_GNPTXSTS register ********************/ -#define USB_OTG_GNPTXSTS_NPTXFSAV_Pos (0U) -#define USB_OTG_GNPTXSTS_NPTXFSAV_Msk (0xFFFFUL << USB_OTG_GNPTXSTS_NPTXFSAV_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_GNPTXSTS_NPTXFSAV USB_OTG_GNPTXSTS_NPTXFSAV_Msk /*!< Nonperiodic TxFIFO space available */ - -#define USB_OTG_GNPTXSTS_NPTQXSAV_Pos (16U) -#define USB_OTG_GNPTXSTS_NPTQXSAV_Msk (0xFFUL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00FF0000 */ -#define USB_OTG_GNPTXSTS_NPTQXSAV USB_OTG_GNPTXSTS_NPTQXSAV_Msk /*!< Nonperiodic transmit request queue space available */ -#define USB_OTG_GNPTXSTS_NPTQXSAV_0 (0x01UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00010000 */ -#define USB_OTG_GNPTXSTS_NPTQXSAV_1 (0x02UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00020000 */ -#define USB_OTG_GNPTXSTS_NPTQXSAV_2 (0x04UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00040000 */ -#define USB_OTG_GNPTXSTS_NPTQXSAV_3 (0x08UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00080000 */ -#define USB_OTG_GNPTXSTS_NPTQXSAV_4 (0x10UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00100000 */ -#define USB_OTG_GNPTXSTS_NPTQXSAV_5 (0x20UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00200000 */ -#define USB_OTG_GNPTXSTS_NPTQXSAV_6 (0x40UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00400000 */ -#define USB_OTG_GNPTXSTS_NPTQXSAV_7 (0x80UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00800000 */ - -#define USB_OTG_GNPTXSTS_NPTXQTOP_Pos (24U) -#define USB_OTG_GNPTXSTS_NPTXQTOP_Msk (0x7FUL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x7F000000 */ -#define USB_OTG_GNPTXSTS_NPTXQTOP USB_OTG_GNPTXSTS_NPTXQTOP_Msk /*!< Top of the nonperiodic transmit request queue */ -#define USB_OTG_GNPTXSTS_NPTXQTOP_0 (0x01UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x01000000 */ -#define USB_OTG_GNPTXSTS_NPTXQTOP_1 (0x02UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x02000000 */ -#define USB_OTG_GNPTXSTS_NPTXQTOP_2 (0x04UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x04000000 */ -#define USB_OTG_GNPTXSTS_NPTXQTOP_3 (0x08UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x08000000 */ -#define USB_OTG_GNPTXSTS_NPTXQTOP_4 (0x10UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x10000000 */ -#define USB_OTG_GNPTXSTS_NPTXQTOP_5 (0x20UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x20000000 */ -#define USB_OTG_GNPTXSTS_NPTXQTOP_6 (0x40UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x40000000 */ - -/******************** Bit definition for USB_OTG_DTHRCTL register ********************/ -#define USB_OTG_DTHRCTL_NONISOTHREN_Pos (0U) -#define USB_OTG_DTHRCTL_NONISOTHREN_Msk (0x1UL << USB_OTG_DTHRCTL_NONISOTHREN_Pos) /*!< 0x00000001 */ -#define USB_OTG_DTHRCTL_NONISOTHREN USB_OTG_DTHRCTL_NONISOTHREN_Msk /*!< Nonisochronous IN endpoints threshold enable */ -#define USB_OTG_DTHRCTL_ISOTHREN_Pos (1U) -#define USB_OTG_DTHRCTL_ISOTHREN_Msk (0x1UL << USB_OTG_DTHRCTL_ISOTHREN_Pos) /*!< 0x00000002 */ -#define USB_OTG_DTHRCTL_ISOTHREN USB_OTG_DTHRCTL_ISOTHREN_Msk /*!< ISO IN endpoint threshold enable */ - -#define USB_OTG_DTHRCTL_TXTHRLEN_Pos (2U) -#define USB_OTG_DTHRCTL_TXTHRLEN_Msk (0x1FFUL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x000007FC */ -#define USB_OTG_DTHRCTL_TXTHRLEN USB_OTG_DTHRCTL_TXTHRLEN_Msk /*!< Transmit threshold length */ -#define USB_OTG_DTHRCTL_TXTHRLEN_0 (0x001UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000004 */ -#define USB_OTG_DTHRCTL_TXTHRLEN_1 (0x002UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000008 */ -#define USB_OTG_DTHRCTL_TXTHRLEN_2 (0x004UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000010 */ -#define USB_OTG_DTHRCTL_TXTHRLEN_3 (0x008UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000020 */ -#define USB_OTG_DTHRCTL_TXTHRLEN_4 (0x010UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000040 */ -#define USB_OTG_DTHRCTL_TXTHRLEN_5 (0x020UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000080 */ -#define USB_OTG_DTHRCTL_TXTHRLEN_6 (0x040UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000100 */ -#define USB_OTG_DTHRCTL_TXTHRLEN_7 (0x080UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000200 */ -#define USB_OTG_DTHRCTL_TXTHRLEN_8 (0x100UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000400 */ -#define USB_OTG_DTHRCTL_RXTHREN_Pos (16U) -#define USB_OTG_DTHRCTL_RXTHREN_Msk (0x1UL << USB_OTG_DTHRCTL_RXTHREN_Pos) /*!< 0x00010000 */ -#define USB_OTG_DTHRCTL_RXTHREN USB_OTG_DTHRCTL_RXTHREN_Msk /*!< Receive threshold enable */ - -#define USB_OTG_DTHRCTL_RXTHRLEN_Pos (17U) -#define USB_OTG_DTHRCTL_RXTHRLEN_Msk (0x1FFUL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x03FE0000 */ -#define USB_OTG_DTHRCTL_RXTHRLEN USB_OTG_DTHRCTL_RXTHRLEN_Msk /*!< Receive threshold length */ -#define USB_OTG_DTHRCTL_RXTHRLEN_0 (0x001UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00020000 */ -#define USB_OTG_DTHRCTL_RXTHRLEN_1 (0x002UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00040000 */ -#define USB_OTG_DTHRCTL_RXTHRLEN_2 (0x004UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00080000 */ -#define USB_OTG_DTHRCTL_RXTHRLEN_3 (0x008UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00100000 */ -#define USB_OTG_DTHRCTL_RXTHRLEN_4 (0x010UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00200000 */ -#define USB_OTG_DTHRCTL_RXTHRLEN_5 (0x020UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00400000 */ -#define USB_OTG_DTHRCTL_RXTHRLEN_6 (0x040UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00800000 */ -#define USB_OTG_DTHRCTL_RXTHRLEN_7 (0x080UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x01000000 */ -#define USB_OTG_DTHRCTL_RXTHRLEN_8 (0x100UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x02000000 */ -#define USB_OTG_DTHRCTL_ARPEN_Pos (27U) -#define USB_OTG_DTHRCTL_ARPEN_Msk (0x1UL << USB_OTG_DTHRCTL_ARPEN_Pos) /*!< 0x08000000 */ -#define USB_OTG_DTHRCTL_ARPEN USB_OTG_DTHRCTL_ARPEN_Msk /*!< Arbiter parking enable */ - -/******************** Bit definition for USB_OTG_DIEPEMPMSK register ********************/ -#define USB_OTG_DIEPEMPMSK_INEPTXFEM_Pos (0U) -#define USB_OTG_DIEPEMPMSK_INEPTXFEM_Msk (0xFFFFUL << USB_OTG_DIEPEMPMSK_INEPTXFEM_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_DIEPEMPMSK_INEPTXFEM USB_OTG_DIEPEMPMSK_INEPTXFEM_Msk /*!< IN EP Tx FIFO empty interrupt mask bits */ - -/******************** Bit definition for USB_OTG_DEACHINT register ********************/ -#define USB_OTG_DEACHINT_IEP1INT_Pos (1U) -#define USB_OTG_DEACHINT_IEP1INT_Msk (0x1UL << USB_OTG_DEACHINT_IEP1INT_Pos) /*!< 0x00000002 */ -#define USB_OTG_DEACHINT_IEP1INT USB_OTG_DEACHINT_IEP1INT_Msk /*!< IN endpoint 1interrupt bit */ -#define USB_OTG_DEACHINT_OEP1INT_Pos (17U) -#define USB_OTG_DEACHINT_OEP1INT_Msk (0x1UL << USB_OTG_DEACHINT_OEP1INT_Pos) /*!< 0x00020000 */ -#define USB_OTG_DEACHINT_OEP1INT USB_OTG_DEACHINT_OEP1INT_Msk /*!< OUT endpoint 1 interrupt bit */ - -/******************** Bit definition for USB_OTG_GCCFG register ********************/ -#define USB_OTG_GCCFG_PWRDWN_Pos (16U) -#define USB_OTG_GCCFG_PWRDWN_Msk (0x1UL << USB_OTG_GCCFG_PWRDWN_Pos) /*!< 0x00010000 */ -#define USB_OTG_GCCFG_PWRDWN USB_OTG_GCCFG_PWRDWN_Msk /*!< Power down */ -#define USB_OTG_GCCFG_VBUSASEN_Pos (18U) -#define USB_OTG_GCCFG_VBUSASEN_Msk (0x1UL << USB_OTG_GCCFG_VBUSASEN_Pos) /*!< 0x00040000 */ -#define USB_OTG_GCCFG_VBUSASEN USB_OTG_GCCFG_VBUSASEN_Msk /*!< Enable the VBUS sensing device */ -#define USB_OTG_GCCFG_VBUSBSEN_Pos (19U) -#define USB_OTG_GCCFG_VBUSBSEN_Msk (0x1UL << USB_OTG_GCCFG_VBUSBSEN_Pos) /*!< 0x00080000 */ -#define USB_OTG_GCCFG_VBUSBSEN USB_OTG_GCCFG_VBUSBSEN_Msk /*!< Enable the VBUS sensing device */ -#define USB_OTG_GCCFG_SOFOUTEN_Pos (20U) -#define USB_OTG_GCCFG_SOFOUTEN_Msk (0x1UL << USB_OTG_GCCFG_SOFOUTEN_Pos) /*!< 0x00100000 */ -#define USB_OTG_GCCFG_SOFOUTEN USB_OTG_GCCFG_SOFOUTEN_Msk /*!< SOF output enable */ - -/******************** Bit definition for USB_OTG_DEACHINTMSK register ********************/ -#define USB_OTG_DEACHINTMSK_IEP1INTM_Pos (1U) -#define USB_OTG_DEACHINTMSK_IEP1INTM_Msk (0x1UL << USB_OTG_DEACHINTMSK_IEP1INTM_Pos) /*!< 0x00000002 */ -#define USB_OTG_DEACHINTMSK_IEP1INTM USB_OTG_DEACHINTMSK_IEP1INTM_Msk /*!< IN Endpoint 1 interrupt mask bit */ -#define USB_OTG_DEACHINTMSK_OEP1INTM_Pos (17U) -#define USB_OTG_DEACHINTMSK_OEP1INTM_Msk (0x1UL << USB_OTG_DEACHINTMSK_OEP1INTM_Pos) /*!< 0x00020000 */ -#define USB_OTG_DEACHINTMSK_OEP1INTM USB_OTG_DEACHINTMSK_OEP1INTM_Msk /*!< OUT Endpoint 1 interrupt mask bit */ - -/******************** Bit definition for USB_OTG_CID register ********************/ -#define USB_OTG_CID_PRODUCT_ID_Pos (0U) -#define USB_OTG_CID_PRODUCT_ID_Msk (0xFFFFFFFFUL << USB_OTG_CID_PRODUCT_ID_Pos) /*!< 0xFFFFFFFF */ -#define USB_OTG_CID_PRODUCT_ID USB_OTG_CID_PRODUCT_ID_Msk /*!< Product ID field */ - -/******************** Bit definition for USB_OTG_DIEPEACHMSK1 register ********************/ -#define USB_OTG_DIEPEACHMSK1_XFRCM_Pos (0U) -#define USB_OTG_DIEPEACHMSK1_XFRCM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_XFRCM_Pos) /*!< 0x00000001 */ -#define USB_OTG_DIEPEACHMSK1_XFRCM USB_OTG_DIEPEACHMSK1_XFRCM_Msk /*!< Transfer completed interrupt mask */ -#define USB_OTG_DIEPEACHMSK1_EPDM_Pos (1U) -#define USB_OTG_DIEPEACHMSK1_EPDM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_EPDM_Pos) /*!< 0x00000002 */ -#define USB_OTG_DIEPEACHMSK1_EPDM USB_OTG_DIEPEACHMSK1_EPDM_Msk /*!< Endpoint disabled interrupt mask */ -#define USB_OTG_DIEPEACHMSK1_TOM_Pos (3U) -#define USB_OTG_DIEPEACHMSK1_TOM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_TOM_Pos) /*!< 0x00000008 */ -#define USB_OTG_DIEPEACHMSK1_TOM USB_OTG_DIEPEACHMSK1_TOM_Msk /*!< Timeout condition mask (nonisochronous endpoints) */ -#define USB_OTG_DIEPEACHMSK1_ITTXFEMSK_Pos (4U) -#define USB_OTG_DIEPEACHMSK1_ITTXFEMSK_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_ITTXFEMSK_Pos) /*!< 0x00000010 */ -#define USB_OTG_DIEPEACHMSK1_ITTXFEMSK USB_OTG_DIEPEACHMSK1_ITTXFEMSK_Msk /*!< IN token received when TxFIFO empty mask */ -#define USB_OTG_DIEPEACHMSK1_INEPNMM_Pos (5U) -#define USB_OTG_DIEPEACHMSK1_INEPNMM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_INEPNMM_Pos) /*!< 0x00000020 */ -#define USB_OTG_DIEPEACHMSK1_INEPNMM USB_OTG_DIEPEACHMSK1_INEPNMM_Msk /*!< IN token received with EP mismatch mask */ -#define USB_OTG_DIEPEACHMSK1_INEPNEM_Pos (6U) -#define USB_OTG_DIEPEACHMSK1_INEPNEM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_INEPNEM_Pos) /*!< 0x00000040 */ -#define USB_OTG_DIEPEACHMSK1_INEPNEM USB_OTG_DIEPEACHMSK1_INEPNEM_Msk /*!< IN endpoint NAK effective mask */ -#define USB_OTG_DIEPEACHMSK1_TXFURM_Pos (8U) -#define USB_OTG_DIEPEACHMSK1_TXFURM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_TXFURM_Pos) /*!< 0x00000100 */ -#define USB_OTG_DIEPEACHMSK1_TXFURM USB_OTG_DIEPEACHMSK1_TXFURM_Msk /*!< FIFO underrun mask */ -#define USB_OTG_DIEPEACHMSK1_BIM_Pos (9U) -#define USB_OTG_DIEPEACHMSK1_BIM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_BIM_Pos) /*!< 0x00000200 */ -#define USB_OTG_DIEPEACHMSK1_BIM USB_OTG_DIEPEACHMSK1_BIM_Msk /*!< BNA interrupt mask */ -#define USB_OTG_DIEPEACHMSK1_NAKM_Pos (13U) -#define USB_OTG_DIEPEACHMSK1_NAKM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_NAKM_Pos) /*!< 0x00002000 */ -#define USB_OTG_DIEPEACHMSK1_NAKM USB_OTG_DIEPEACHMSK1_NAKM_Msk /*!< NAK interrupt mask */ - -/******************** Bit definition for USB_OTG_HPRT register ********************/ -#define USB_OTG_HPRT_PCSTS_Pos (0U) -#define USB_OTG_HPRT_PCSTS_Msk (0x1UL << USB_OTG_HPRT_PCSTS_Pos) /*!< 0x00000001 */ -#define USB_OTG_HPRT_PCSTS USB_OTG_HPRT_PCSTS_Msk /*!< Port connect status */ -#define USB_OTG_HPRT_PCDET_Pos (1U) -#define USB_OTG_HPRT_PCDET_Msk (0x1UL << USB_OTG_HPRT_PCDET_Pos) /*!< 0x00000002 */ -#define USB_OTG_HPRT_PCDET USB_OTG_HPRT_PCDET_Msk /*!< Port connect detected */ -#define USB_OTG_HPRT_PENA_Pos (2U) -#define USB_OTG_HPRT_PENA_Msk (0x1UL << USB_OTG_HPRT_PENA_Pos) /*!< 0x00000004 */ -#define USB_OTG_HPRT_PENA USB_OTG_HPRT_PENA_Msk /*!< Port enable */ -#define USB_OTG_HPRT_PENCHNG_Pos (3U) -#define USB_OTG_HPRT_PENCHNG_Msk (0x1UL << USB_OTG_HPRT_PENCHNG_Pos) /*!< 0x00000008 */ -#define USB_OTG_HPRT_PENCHNG USB_OTG_HPRT_PENCHNG_Msk /*!< Port enable/disable change */ -#define USB_OTG_HPRT_POCA_Pos (4U) -#define USB_OTG_HPRT_POCA_Msk (0x1UL << USB_OTG_HPRT_POCA_Pos) /*!< 0x00000010 */ -#define USB_OTG_HPRT_POCA USB_OTG_HPRT_POCA_Msk /*!< Port overcurrent active */ -#define USB_OTG_HPRT_POCCHNG_Pos (5U) -#define USB_OTG_HPRT_POCCHNG_Msk (0x1UL << USB_OTG_HPRT_POCCHNG_Pos) /*!< 0x00000020 */ -#define USB_OTG_HPRT_POCCHNG USB_OTG_HPRT_POCCHNG_Msk /*!< Port overcurrent change */ -#define USB_OTG_HPRT_PRES_Pos (6U) -#define USB_OTG_HPRT_PRES_Msk (0x1UL << USB_OTG_HPRT_PRES_Pos) /*!< 0x00000040 */ -#define USB_OTG_HPRT_PRES USB_OTG_HPRT_PRES_Msk /*!< Port resume */ -#define USB_OTG_HPRT_PSUSP_Pos (7U) -#define USB_OTG_HPRT_PSUSP_Msk (0x1UL << USB_OTG_HPRT_PSUSP_Pos) /*!< 0x00000080 */ -#define USB_OTG_HPRT_PSUSP USB_OTG_HPRT_PSUSP_Msk /*!< Port suspend */ -#define USB_OTG_HPRT_PRST_Pos (8U) -#define USB_OTG_HPRT_PRST_Msk (0x1UL << USB_OTG_HPRT_PRST_Pos) /*!< 0x00000100 */ -#define USB_OTG_HPRT_PRST USB_OTG_HPRT_PRST_Msk /*!< Port reset */ - -#define USB_OTG_HPRT_PLSTS_Pos (10U) -#define USB_OTG_HPRT_PLSTS_Msk (0x3UL << USB_OTG_HPRT_PLSTS_Pos) /*!< 0x00000C00 */ -#define USB_OTG_HPRT_PLSTS USB_OTG_HPRT_PLSTS_Msk /*!< Port line status */ -#define USB_OTG_HPRT_PLSTS_0 (0x1UL << USB_OTG_HPRT_PLSTS_Pos) /*!< 0x00000400 */ -#define USB_OTG_HPRT_PLSTS_1 (0x2UL << USB_OTG_HPRT_PLSTS_Pos) /*!< 0x00000800 */ -#define USB_OTG_HPRT_PPWR_Pos (12U) -#define USB_OTG_HPRT_PPWR_Msk (0x1UL << USB_OTG_HPRT_PPWR_Pos) /*!< 0x00001000 */ -#define USB_OTG_HPRT_PPWR USB_OTG_HPRT_PPWR_Msk /*!< Port power */ - -#define USB_OTG_HPRT_PTCTL_Pos (13U) -#define USB_OTG_HPRT_PTCTL_Msk (0xFUL << USB_OTG_HPRT_PTCTL_Pos) /*!< 0x0001E000 */ -#define USB_OTG_HPRT_PTCTL USB_OTG_HPRT_PTCTL_Msk /*!< Port test control */ -#define USB_OTG_HPRT_PTCTL_0 (0x1UL << USB_OTG_HPRT_PTCTL_Pos) /*!< 0x00002000 */ -#define USB_OTG_HPRT_PTCTL_1 (0x2UL << USB_OTG_HPRT_PTCTL_Pos) /*!< 0x00004000 */ -#define USB_OTG_HPRT_PTCTL_2 (0x4UL << USB_OTG_HPRT_PTCTL_Pos) /*!< 0x00008000 */ -#define USB_OTG_HPRT_PTCTL_3 (0x8UL << USB_OTG_HPRT_PTCTL_Pos) /*!< 0x00010000 */ - -#define USB_OTG_HPRT_PSPD_Pos (17U) -#define USB_OTG_HPRT_PSPD_Msk (0x3UL << USB_OTG_HPRT_PSPD_Pos) /*!< 0x00060000 */ -#define USB_OTG_HPRT_PSPD USB_OTG_HPRT_PSPD_Msk /*!< Port speed */ -#define USB_OTG_HPRT_PSPD_0 (0x1UL << USB_OTG_HPRT_PSPD_Pos) /*!< 0x00020000 */ -#define USB_OTG_HPRT_PSPD_1 (0x2UL << USB_OTG_HPRT_PSPD_Pos) /*!< 0x00040000 */ - -/******************** Bit definition for USB_OTG_DOEPEACHMSK1 register ********************/ -#define USB_OTG_DOEPEACHMSK1_XFRCM_Pos (0U) -#define USB_OTG_DOEPEACHMSK1_XFRCM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_XFRCM_Pos) /*!< 0x00000001 */ -#define USB_OTG_DOEPEACHMSK1_XFRCM USB_OTG_DOEPEACHMSK1_XFRCM_Msk /*!< Transfer completed interrupt mask */ -#define USB_OTG_DOEPEACHMSK1_EPDM_Pos (1U) -#define USB_OTG_DOEPEACHMSK1_EPDM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_EPDM_Pos) /*!< 0x00000002 */ -#define USB_OTG_DOEPEACHMSK1_EPDM USB_OTG_DOEPEACHMSK1_EPDM_Msk /*!< Endpoint disabled interrupt mask */ -#define USB_OTG_DOEPEACHMSK1_TOM_Pos (3U) -#define USB_OTG_DOEPEACHMSK1_TOM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_TOM_Pos) /*!< 0x00000008 */ -#define USB_OTG_DOEPEACHMSK1_TOM USB_OTG_DOEPEACHMSK1_TOM_Msk /*!< Timeout condition mask */ -#define USB_OTG_DOEPEACHMSK1_ITTXFEMSK_Pos (4U) -#define USB_OTG_DOEPEACHMSK1_ITTXFEMSK_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_ITTXFEMSK_Pos) /*!< 0x00000010 */ -#define USB_OTG_DOEPEACHMSK1_ITTXFEMSK USB_OTG_DOEPEACHMSK1_ITTXFEMSK_Msk /*!< IN token received when TxFIFO empty mask */ -#define USB_OTG_DOEPEACHMSK1_INEPNMM_Pos (5U) -#define USB_OTG_DOEPEACHMSK1_INEPNMM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_INEPNMM_Pos) /*!< 0x00000020 */ -#define USB_OTG_DOEPEACHMSK1_INEPNMM USB_OTG_DOEPEACHMSK1_INEPNMM_Msk /*!< IN token received with EP mismatch mask */ -#define USB_OTG_DOEPEACHMSK1_INEPNEM_Pos (6U) -#define USB_OTG_DOEPEACHMSK1_INEPNEM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_INEPNEM_Pos) /*!< 0x00000040 */ -#define USB_OTG_DOEPEACHMSK1_INEPNEM USB_OTG_DOEPEACHMSK1_INEPNEM_Msk /*!< IN endpoint NAK effective mask */ -#define USB_OTG_DOEPEACHMSK1_TXFURM_Pos (8U) -#define USB_OTG_DOEPEACHMSK1_TXFURM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_TXFURM_Pos) /*!< 0x00000100 */ -#define USB_OTG_DOEPEACHMSK1_TXFURM USB_OTG_DOEPEACHMSK1_TXFURM_Msk /*!< OUT packet error mask */ -#define USB_OTG_DOEPEACHMSK1_BIM_Pos (9U) -#define USB_OTG_DOEPEACHMSK1_BIM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_BIM_Pos) /*!< 0x00000200 */ -#define USB_OTG_DOEPEACHMSK1_BIM USB_OTG_DOEPEACHMSK1_BIM_Msk /*!< BNA interrupt mask */ -#define USB_OTG_DOEPEACHMSK1_BERRM_Pos (12U) -#define USB_OTG_DOEPEACHMSK1_BERRM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_BERRM_Pos) /*!< 0x00001000 */ -#define USB_OTG_DOEPEACHMSK1_BERRM USB_OTG_DOEPEACHMSK1_BERRM_Msk /*!< Bubble error interrupt mask */ -#define USB_OTG_DOEPEACHMSK1_NAKM_Pos (13U) -#define USB_OTG_DOEPEACHMSK1_NAKM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_NAKM_Pos) /*!< 0x00002000 */ -#define USB_OTG_DOEPEACHMSK1_NAKM USB_OTG_DOEPEACHMSK1_NAKM_Msk /*!< NAK interrupt mask */ -#define USB_OTG_DOEPEACHMSK1_NYETM_Pos (14U) -#define USB_OTG_DOEPEACHMSK1_NYETM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_NYETM_Pos) /*!< 0x00004000 */ -#define USB_OTG_DOEPEACHMSK1_NYETM USB_OTG_DOEPEACHMSK1_NYETM_Msk /*!< NYET interrupt mask */ - -/******************** Bit definition for USB_OTG_HPTXFSIZ register ********************/ -#define USB_OTG_HPTXFSIZ_PTXSA_Pos (0U) -#define USB_OTG_HPTXFSIZ_PTXSA_Msk (0xFFFFUL << USB_OTG_HPTXFSIZ_PTXSA_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_HPTXFSIZ_PTXSA USB_OTG_HPTXFSIZ_PTXSA_Msk /*!< Host periodic TxFIFO start address */ -#define USB_OTG_HPTXFSIZ_PTXFD_Pos (16U) -#define USB_OTG_HPTXFSIZ_PTXFD_Msk (0xFFFFUL << USB_OTG_HPTXFSIZ_PTXFD_Pos) /*!< 0xFFFF0000 */ -#define USB_OTG_HPTXFSIZ_PTXFD USB_OTG_HPTXFSIZ_PTXFD_Msk /*!< Host periodic TxFIFO depth */ - -/******************** Bit definition for USB_OTG_DIEPCTL register ********************/ -#define USB_OTG_DIEPCTL_MPSIZ_Pos (0U) -#define USB_OTG_DIEPCTL_MPSIZ_Msk (0x7FFUL << USB_OTG_DIEPCTL_MPSIZ_Pos) /*!< 0x000007FF */ -#define USB_OTG_DIEPCTL_MPSIZ USB_OTG_DIEPCTL_MPSIZ_Msk /*!< Maximum packet size */ -#define USB_OTG_DIEPCTL_USBAEP_Pos (15U) -#define USB_OTG_DIEPCTL_USBAEP_Msk (0x1UL << USB_OTG_DIEPCTL_USBAEP_Pos) /*!< 0x00008000 */ -#define USB_OTG_DIEPCTL_USBAEP USB_OTG_DIEPCTL_USBAEP_Msk /*!< USB active endpoint */ -#define USB_OTG_DIEPCTL_EONUM_DPID_Pos (16U) -#define USB_OTG_DIEPCTL_EONUM_DPID_Msk (0x1UL << USB_OTG_DIEPCTL_EONUM_DPID_Pos) /*!< 0x00010000 */ -#define USB_OTG_DIEPCTL_EONUM_DPID USB_OTG_DIEPCTL_EONUM_DPID_Msk /*!< Even/odd frame */ -#define USB_OTG_DIEPCTL_NAKSTS_Pos (17U) -#define USB_OTG_DIEPCTL_NAKSTS_Msk (0x1UL << USB_OTG_DIEPCTL_NAKSTS_Pos) /*!< 0x00020000 */ -#define USB_OTG_DIEPCTL_NAKSTS USB_OTG_DIEPCTL_NAKSTS_Msk /*!< NAK status */ - -#define USB_OTG_DIEPCTL_EPTYP_Pos (18U) -#define USB_OTG_DIEPCTL_EPTYP_Msk (0x3UL << USB_OTG_DIEPCTL_EPTYP_Pos) /*!< 0x000C0000 */ -#define USB_OTG_DIEPCTL_EPTYP USB_OTG_DIEPCTL_EPTYP_Msk /*!< Endpoint type */ -#define USB_OTG_DIEPCTL_EPTYP_0 (0x1UL << USB_OTG_DIEPCTL_EPTYP_Pos) /*!< 0x00040000 */ -#define USB_OTG_DIEPCTL_EPTYP_1 (0x2UL << USB_OTG_DIEPCTL_EPTYP_Pos) /*!< 0x00080000 */ -#define USB_OTG_DIEPCTL_STALL_Pos (21U) -#define USB_OTG_DIEPCTL_STALL_Msk (0x1UL << USB_OTG_DIEPCTL_STALL_Pos) /*!< 0x00200000 */ -#define USB_OTG_DIEPCTL_STALL USB_OTG_DIEPCTL_STALL_Msk /*!< STALL handshake */ - -#define USB_OTG_DIEPCTL_TXFNUM_Pos (22U) -#define USB_OTG_DIEPCTL_TXFNUM_Msk (0xFUL << USB_OTG_DIEPCTL_TXFNUM_Pos) /*!< 0x03C00000 */ -#define USB_OTG_DIEPCTL_TXFNUM USB_OTG_DIEPCTL_TXFNUM_Msk /*!< TxFIFO number */ -#define USB_OTG_DIEPCTL_TXFNUM_0 (0x1UL << USB_OTG_DIEPCTL_TXFNUM_Pos) /*!< 0x00400000 */ -#define USB_OTG_DIEPCTL_TXFNUM_1 (0x2UL << USB_OTG_DIEPCTL_TXFNUM_Pos) /*!< 0x00800000 */ -#define USB_OTG_DIEPCTL_TXFNUM_2 (0x4UL << USB_OTG_DIEPCTL_TXFNUM_Pos) /*!< 0x01000000 */ -#define USB_OTG_DIEPCTL_TXFNUM_3 (0x8UL << USB_OTG_DIEPCTL_TXFNUM_Pos) /*!< 0x02000000 */ -#define USB_OTG_DIEPCTL_CNAK_Pos (26U) -#define USB_OTG_DIEPCTL_CNAK_Msk (0x1UL << USB_OTG_DIEPCTL_CNAK_Pos) /*!< 0x04000000 */ -#define USB_OTG_DIEPCTL_CNAK USB_OTG_DIEPCTL_CNAK_Msk /*!< Clear NAK */ -#define USB_OTG_DIEPCTL_SNAK_Pos (27U) -#define USB_OTG_DIEPCTL_SNAK_Msk (0x1UL << USB_OTG_DIEPCTL_SNAK_Pos) /*!< 0x08000000 */ -#define USB_OTG_DIEPCTL_SNAK USB_OTG_DIEPCTL_SNAK_Msk /*!< Set NAK */ -#define USB_OTG_DIEPCTL_SD0PID_SEVNFRM_Pos (28U) -#define USB_OTG_DIEPCTL_SD0PID_SEVNFRM_Msk (0x1UL << USB_OTG_DIEPCTL_SD0PID_SEVNFRM_Pos) /*!< 0x10000000 */ -#define USB_OTG_DIEPCTL_SD0PID_SEVNFRM USB_OTG_DIEPCTL_SD0PID_SEVNFRM_Msk /*!< Set DATA0 PID */ -#define USB_OTG_DIEPCTL_SODDFRM_Pos (29U) -#define USB_OTG_DIEPCTL_SODDFRM_Msk (0x1UL << USB_OTG_DIEPCTL_SODDFRM_Pos) /*!< 0x20000000 */ -#define USB_OTG_DIEPCTL_SODDFRM USB_OTG_DIEPCTL_SODDFRM_Msk /*!< Set odd frame */ -#define USB_OTG_DIEPCTL_EPDIS_Pos (30U) -#define USB_OTG_DIEPCTL_EPDIS_Msk (0x1UL << USB_OTG_DIEPCTL_EPDIS_Pos) /*!< 0x40000000 */ -#define USB_OTG_DIEPCTL_EPDIS USB_OTG_DIEPCTL_EPDIS_Msk /*!< Endpoint disable */ -#define USB_OTG_DIEPCTL_EPENA_Pos (31U) -#define USB_OTG_DIEPCTL_EPENA_Msk (0x1UL << USB_OTG_DIEPCTL_EPENA_Pos) /*!< 0x80000000 */ -#define USB_OTG_DIEPCTL_EPENA USB_OTG_DIEPCTL_EPENA_Msk /*!< Endpoint enable */ - -/******************** Bit definition for USB_OTG_HCCHAR register ********************/ -#define USB_OTG_HCCHAR_MPSIZ_Pos (0U) -#define USB_OTG_HCCHAR_MPSIZ_Msk (0x7FFUL << USB_OTG_HCCHAR_MPSIZ_Pos) /*!< 0x000007FF */ -#define USB_OTG_HCCHAR_MPSIZ USB_OTG_HCCHAR_MPSIZ_Msk /*!< Maximum packet size */ - -#define USB_OTG_HCCHAR_EPNUM_Pos (11U) -#define USB_OTG_HCCHAR_EPNUM_Msk (0xFUL << USB_OTG_HCCHAR_EPNUM_Pos) /*!< 0x00007800 */ -#define USB_OTG_HCCHAR_EPNUM USB_OTG_HCCHAR_EPNUM_Msk /*!< Endpoint number */ -#define USB_OTG_HCCHAR_EPNUM_0 (0x1UL << USB_OTG_HCCHAR_EPNUM_Pos) /*!< 0x00000800 */ -#define USB_OTG_HCCHAR_EPNUM_1 (0x2UL << USB_OTG_HCCHAR_EPNUM_Pos) /*!< 0x00001000 */ -#define USB_OTG_HCCHAR_EPNUM_2 (0x4UL << USB_OTG_HCCHAR_EPNUM_Pos) /*!< 0x00002000 */ -#define USB_OTG_HCCHAR_EPNUM_3 (0x8UL << USB_OTG_HCCHAR_EPNUM_Pos) /*!< 0x00004000 */ -#define USB_OTG_HCCHAR_EPDIR_Pos (15U) -#define USB_OTG_HCCHAR_EPDIR_Msk (0x1UL << USB_OTG_HCCHAR_EPDIR_Pos) /*!< 0x00008000 */ -#define USB_OTG_HCCHAR_EPDIR USB_OTG_HCCHAR_EPDIR_Msk /*!< Endpoint direction */ -#define USB_OTG_HCCHAR_LSDEV_Pos (17U) -#define USB_OTG_HCCHAR_LSDEV_Msk (0x1UL << USB_OTG_HCCHAR_LSDEV_Pos) /*!< 0x00020000 */ -#define USB_OTG_HCCHAR_LSDEV USB_OTG_HCCHAR_LSDEV_Msk /*!< Low-speed device */ - -#define USB_OTG_HCCHAR_EPTYP_Pos (18U) -#define USB_OTG_HCCHAR_EPTYP_Msk (0x3UL << USB_OTG_HCCHAR_EPTYP_Pos) /*!< 0x000C0000 */ -#define USB_OTG_HCCHAR_EPTYP USB_OTG_HCCHAR_EPTYP_Msk /*!< Endpoint type */ -#define USB_OTG_HCCHAR_EPTYP_0 (0x1UL << USB_OTG_HCCHAR_EPTYP_Pos) /*!< 0x00040000 */ -#define USB_OTG_HCCHAR_EPTYP_1 (0x2UL << USB_OTG_HCCHAR_EPTYP_Pos) /*!< 0x00080000 */ - -#define USB_OTG_HCCHAR_MC_Pos (20U) -#define USB_OTG_HCCHAR_MC_Msk (0x3UL << USB_OTG_HCCHAR_MC_Pos) /*!< 0x00300000 */ -#define USB_OTG_HCCHAR_MC USB_OTG_HCCHAR_MC_Msk /*!< Multi Count (MC) / Error Count (EC) */ -#define USB_OTG_HCCHAR_MC_0 (0x1UL << USB_OTG_HCCHAR_MC_Pos) /*!< 0x00100000 */ -#define USB_OTG_HCCHAR_MC_1 (0x2UL << USB_OTG_HCCHAR_MC_Pos) /*!< 0x00200000 */ - -#define USB_OTG_HCCHAR_DAD_Pos (22U) -#define USB_OTG_HCCHAR_DAD_Msk (0x7FUL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x1FC00000 */ -#define USB_OTG_HCCHAR_DAD USB_OTG_HCCHAR_DAD_Msk /*!< Device address */ -#define USB_OTG_HCCHAR_DAD_0 (0x01UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x00400000 */ -#define USB_OTG_HCCHAR_DAD_1 (0x02UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x00800000 */ -#define USB_OTG_HCCHAR_DAD_2 (0x04UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x01000000 */ -#define USB_OTG_HCCHAR_DAD_3 (0x08UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x02000000 */ -#define USB_OTG_HCCHAR_DAD_4 (0x10UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x04000000 */ -#define USB_OTG_HCCHAR_DAD_5 (0x20UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x08000000 */ -#define USB_OTG_HCCHAR_DAD_6 (0x40UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x10000000 */ -#define USB_OTG_HCCHAR_ODDFRM_Pos (29U) -#define USB_OTG_HCCHAR_ODDFRM_Msk (0x1UL << USB_OTG_HCCHAR_ODDFRM_Pos) /*!< 0x20000000 */ -#define USB_OTG_HCCHAR_ODDFRM USB_OTG_HCCHAR_ODDFRM_Msk /*!< Odd frame */ -#define USB_OTG_HCCHAR_CHDIS_Pos (30U) -#define USB_OTG_HCCHAR_CHDIS_Msk (0x1UL << USB_OTG_HCCHAR_CHDIS_Pos) /*!< 0x40000000 */ -#define USB_OTG_HCCHAR_CHDIS USB_OTG_HCCHAR_CHDIS_Msk /*!< Channel disable */ -#define USB_OTG_HCCHAR_CHENA_Pos (31U) -#define USB_OTG_HCCHAR_CHENA_Msk (0x1UL << USB_OTG_HCCHAR_CHENA_Pos) /*!< 0x80000000 */ -#define USB_OTG_HCCHAR_CHENA USB_OTG_HCCHAR_CHENA_Msk /*!< Channel enable */ - -/******************** Bit definition for USB_OTG_HCSPLT register ********************/ - -#define USB_OTG_HCSPLT_PRTADDR_Pos (0U) -#define USB_OTG_HCSPLT_PRTADDR_Msk (0x7FUL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x0000007F */ -#define USB_OTG_HCSPLT_PRTADDR USB_OTG_HCSPLT_PRTADDR_Msk /*!< Port address */ -#define USB_OTG_HCSPLT_PRTADDR_0 (0x01UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000001 */ -#define USB_OTG_HCSPLT_PRTADDR_1 (0x02UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000002 */ -#define USB_OTG_HCSPLT_PRTADDR_2 (0x04UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000004 */ -#define USB_OTG_HCSPLT_PRTADDR_3 (0x08UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000008 */ -#define USB_OTG_HCSPLT_PRTADDR_4 (0x10UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000010 */ -#define USB_OTG_HCSPLT_PRTADDR_5 (0x20UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000020 */ -#define USB_OTG_HCSPLT_PRTADDR_6 (0x40UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000040 */ - -#define USB_OTG_HCSPLT_HUBADDR_Pos (7U) -#define USB_OTG_HCSPLT_HUBADDR_Msk (0x7FUL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00003F80 */ -#define USB_OTG_HCSPLT_HUBADDR USB_OTG_HCSPLT_HUBADDR_Msk /*!< Hub address */ -#define USB_OTG_HCSPLT_HUBADDR_0 (0x01UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00000080 */ -#define USB_OTG_HCSPLT_HUBADDR_1 (0x02UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00000100 */ -#define USB_OTG_HCSPLT_HUBADDR_2 (0x04UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00000200 */ -#define USB_OTG_HCSPLT_HUBADDR_3 (0x08UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00000400 */ -#define USB_OTG_HCSPLT_HUBADDR_4 (0x10UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00000800 */ -#define USB_OTG_HCSPLT_HUBADDR_5 (0x20UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00001000 */ -#define USB_OTG_HCSPLT_HUBADDR_6 (0x40UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00002000 */ - -#define USB_OTG_HCSPLT_XACTPOS_Pos (14U) -#define USB_OTG_HCSPLT_XACTPOS_Msk (0x3UL << USB_OTG_HCSPLT_XACTPOS_Pos) /*!< 0x0000C000 */ -#define USB_OTG_HCSPLT_XACTPOS USB_OTG_HCSPLT_XACTPOS_Msk /*!< XACTPOS */ -#define USB_OTG_HCSPLT_XACTPOS_0 (0x1UL << USB_OTG_HCSPLT_XACTPOS_Pos) /*!< 0x00004000 */ -#define USB_OTG_HCSPLT_XACTPOS_1 (0x2UL << USB_OTG_HCSPLT_XACTPOS_Pos) /*!< 0x00008000 */ -#define USB_OTG_HCSPLT_COMPLSPLT_Pos (16U) -#define USB_OTG_HCSPLT_COMPLSPLT_Msk (0x1UL << USB_OTG_HCSPLT_COMPLSPLT_Pos) /*!< 0x00010000 */ -#define USB_OTG_HCSPLT_COMPLSPLT USB_OTG_HCSPLT_COMPLSPLT_Msk /*!< Do complete split */ -#define USB_OTG_HCSPLT_SPLITEN_Pos (31U) -#define USB_OTG_HCSPLT_SPLITEN_Msk (0x1UL << USB_OTG_HCSPLT_SPLITEN_Pos) /*!< 0x80000000 */ -#define USB_OTG_HCSPLT_SPLITEN USB_OTG_HCSPLT_SPLITEN_Msk /*!< Split enable */ - -/******************** Bit definition for USB_OTG_HCINT register ********************/ -#define USB_OTG_HCINT_XFRC_Pos (0U) -#define USB_OTG_HCINT_XFRC_Msk (0x1UL << USB_OTG_HCINT_XFRC_Pos) /*!< 0x00000001 */ -#define USB_OTG_HCINT_XFRC USB_OTG_HCINT_XFRC_Msk /*!< Transfer completed */ -#define USB_OTG_HCINT_CHH_Pos (1U) -#define USB_OTG_HCINT_CHH_Msk (0x1UL << USB_OTG_HCINT_CHH_Pos) /*!< 0x00000002 */ -#define USB_OTG_HCINT_CHH USB_OTG_HCINT_CHH_Msk /*!< Channel halted */ -#define USB_OTG_HCINT_AHBERR_Pos (2U) -#define USB_OTG_HCINT_AHBERR_Msk (0x1UL << USB_OTG_HCINT_AHBERR_Pos) /*!< 0x00000004 */ -#define USB_OTG_HCINT_AHBERR USB_OTG_HCINT_AHBERR_Msk /*!< AHB error */ -#define USB_OTG_HCINT_STALL_Pos (3U) -#define USB_OTG_HCINT_STALL_Msk (0x1UL << USB_OTG_HCINT_STALL_Pos) /*!< 0x00000008 */ -#define USB_OTG_HCINT_STALL USB_OTG_HCINT_STALL_Msk /*!< STALL response received interrupt */ -#define USB_OTG_HCINT_NAK_Pos (4U) -#define USB_OTG_HCINT_NAK_Msk (0x1UL << USB_OTG_HCINT_NAK_Pos) /*!< 0x00000010 */ -#define USB_OTG_HCINT_NAK USB_OTG_HCINT_NAK_Msk /*!< NAK response received interrupt */ -#define USB_OTG_HCINT_ACK_Pos (5U) -#define USB_OTG_HCINT_ACK_Msk (0x1UL << USB_OTG_HCINT_ACK_Pos) /*!< 0x00000020 */ -#define USB_OTG_HCINT_ACK USB_OTG_HCINT_ACK_Msk /*!< ACK response received/transmitted interrupt */ -#define USB_OTG_HCINT_NYET_Pos (6U) -#define USB_OTG_HCINT_NYET_Msk (0x1UL << USB_OTG_HCINT_NYET_Pos) /*!< 0x00000040 */ -#define USB_OTG_HCINT_NYET USB_OTG_HCINT_NYET_Msk /*!< Response received interrupt */ -#define USB_OTG_HCINT_TXERR_Pos (7U) -#define USB_OTG_HCINT_TXERR_Msk (0x1UL << USB_OTG_HCINT_TXERR_Pos) /*!< 0x00000080 */ -#define USB_OTG_HCINT_TXERR USB_OTG_HCINT_TXERR_Msk /*!< Transaction error */ -#define USB_OTG_HCINT_BBERR_Pos (8U) -#define USB_OTG_HCINT_BBERR_Msk (0x1UL << USB_OTG_HCINT_BBERR_Pos) /*!< 0x00000100 */ -#define USB_OTG_HCINT_BBERR USB_OTG_HCINT_BBERR_Msk /*!< Babble error */ -#define USB_OTG_HCINT_FRMOR_Pos (9U) -#define USB_OTG_HCINT_FRMOR_Msk (0x1UL << USB_OTG_HCINT_FRMOR_Pos) /*!< 0x00000200 */ -#define USB_OTG_HCINT_FRMOR USB_OTG_HCINT_FRMOR_Msk /*!< Frame overrun */ -#define USB_OTG_HCINT_DTERR_Pos (10U) -#define USB_OTG_HCINT_DTERR_Msk (0x1UL << USB_OTG_HCINT_DTERR_Pos) /*!< 0x00000400 */ -#define USB_OTG_HCINT_DTERR USB_OTG_HCINT_DTERR_Msk /*!< Data toggle error */ - -/******************** Bit definition for USB_OTG_DIEPINT register ********************/ -#define USB_OTG_DIEPINT_XFRC_Pos (0U) -#define USB_OTG_DIEPINT_XFRC_Msk (0x1UL << USB_OTG_DIEPINT_XFRC_Pos) /*!< 0x00000001 */ -#define USB_OTG_DIEPINT_XFRC USB_OTG_DIEPINT_XFRC_Msk /*!< Transfer completed interrupt */ -#define USB_OTG_DIEPINT_EPDISD_Pos (1U) -#define USB_OTG_DIEPINT_EPDISD_Msk (0x1UL << USB_OTG_DIEPINT_EPDISD_Pos) /*!< 0x00000002 */ -#define USB_OTG_DIEPINT_EPDISD USB_OTG_DIEPINT_EPDISD_Msk /*!< Endpoint disabled interrupt */ -#define USB_OTG_DIEPINT_AHBERR_Pos (2U) -#define USB_OTG_DIEPINT_AHBERR_Msk (0x1UL << USB_OTG_DIEPINT_AHBERR_Pos) /*!< 0x00000004 */ -#define USB_OTG_DIEPINT_AHBERR USB_OTG_DIEPINT_AHBERR_Msk /*!< AHB Error (AHBErr) during an IN transaction */ -#define USB_OTG_DIEPINT_TOC_Pos (3U) -#define USB_OTG_DIEPINT_TOC_Msk (0x1UL << USB_OTG_DIEPINT_TOC_Pos) /*!< 0x00000008 */ -#define USB_OTG_DIEPINT_TOC USB_OTG_DIEPINT_TOC_Msk /*!< Timeout condition */ -#define USB_OTG_DIEPINT_ITTXFE_Pos (4U) -#define USB_OTG_DIEPINT_ITTXFE_Msk (0x1UL << USB_OTG_DIEPINT_ITTXFE_Pos) /*!< 0x00000010 */ -#define USB_OTG_DIEPINT_ITTXFE USB_OTG_DIEPINT_ITTXFE_Msk /*!< IN token received when TxFIFO is empty */ -#define USB_OTG_DIEPINT_INEPNM_Pos (5U) -#define USB_OTG_DIEPINT_INEPNM_Msk (0x1UL << USB_OTG_DIEPINT_INEPNM_Pos) /*!< 0x00000004 */ -#define USB_OTG_DIEPINT_INEPNM USB_OTG_DIEPINT_INEPNM_Msk /*!< IN token received with EP mismatch */ -#define USB_OTG_DIEPINT_INEPNE_Pos (6U) -#define USB_OTG_DIEPINT_INEPNE_Msk (0x1UL << USB_OTG_DIEPINT_INEPNE_Pos) /*!< 0x00000040 */ -#define USB_OTG_DIEPINT_INEPNE USB_OTG_DIEPINT_INEPNE_Msk /*!< IN endpoint NAK effective */ -#define USB_OTG_DIEPINT_TXFE_Pos (7U) -#define USB_OTG_DIEPINT_TXFE_Msk (0x1UL << USB_OTG_DIEPINT_TXFE_Pos) /*!< 0x00000080 */ -#define USB_OTG_DIEPINT_TXFE USB_OTG_DIEPINT_TXFE_Msk /*!< Transmit FIFO empty */ -#define USB_OTG_DIEPINT_TXFIFOUDRN_Pos (8U) -#define USB_OTG_DIEPINT_TXFIFOUDRN_Msk (0x1UL << USB_OTG_DIEPINT_TXFIFOUDRN_Pos) /*!< 0x00000100 */ -#define USB_OTG_DIEPINT_TXFIFOUDRN USB_OTG_DIEPINT_TXFIFOUDRN_Msk /*!< Transmit Fifo Underrun */ -#define USB_OTG_DIEPINT_BNA_Pos (9U) -#define USB_OTG_DIEPINT_BNA_Msk (0x1UL << USB_OTG_DIEPINT_BNA_Pos) /*!< 0x00000200 */ -#define USB_OTG_DIEPINT_BNA USB_OTG_DIEPINT_BNA_Msk /*!< Buffer not available interrupt */ -#define USB_OTG_DIEPINT_PKTDRPSTS_Pos (11U) -#define USB_OTG_DIEPINT_PKTDRPSTS_Msk (0x1UL << USB_OTG_DIEPINT_PKTDRPSTS_Pos) /*!< 0x00000800 */ -#define USB_OTG_DIEPINT_PKTDRPSTS USB_OTG_DIEPINT_PKTDRPSTS_Msk /*!< Packet dropped status */ -#define USB_OTG_DIEPINT_BERR_Pos (12U) -#define USB_OTG_DIEPINT_BERR_Msk (0x1UL << USB_OTG_DIEPINT_BERR_Pos) /*!< 0x00001000 */ -#define USB_OTG_DIEPINT_BERR USB_OTG_DIEPINT_BERR_Msk /*!< Babble error interrupt */ -#define USB_OTG_DIEPINT_NAK_Pos (13U) -#define USB_OTG_DIEPINT_NAK_Msk (0x1UL << USB_OTG_DIEPINT_NAK_Pos) /*!< 0x00002000 */ -#define USB_OTG_DIEPINT_NAK USB_OTG_DIEPINT_NAK_Msk /*!< NAK interrupt */ - -/******************** Bit definition for USB_OTG_HCINTMSK register ********************/ -#define USB_OTG_HCINTMSK_XFRCM_Pos (0U) -#define USB_OTG_HCINTMSK_XFRCM_Msk (0x1UL << USB_OTG_HCINTMSK_XFRCM_Pos) /*!< 0x00000001 */ -#define USB_OTG_HCINTMSK_XFRCM USB_OTG_HCINTMSK_XFRCM_Msk /*!< Transfer completed mask */ -#define USB_OTG_HCINTMSK_CHHM_Pos (1U) -#define USB_OTG_HCINTMSK_CHHM_Msk (0x1UL << USB_OTG_HCINTMSK_CHHM_Pos) /*!< 0x00000002 */ -#define USB_OTG_HCINTMSK_CHHM USB_OTG_HCINTMSK_CHHM_Msk /*!< Channel halted mask */ -#define USB_OTG_HCINTMSK_AHBERR_Pos (2U) -#define USB_OTG_HCINTMSK_AHBERR_Msk (0x1UL << USB_OTG_HCINTMSK_AHBERR_Pos) /*!< 0x00000004 */ -#define USB_OTG_HCINTMSK_AHBERR USB_OTG_HCINTMSK_AHBERR_Msk /*!< AHB error */ -#define USB_OTG_HCINTMSK_STALLM_Pos (3U) -#define USB_OTG_HCINTMSK_STALLM_Msk (0x1UL << USB_OTG_HCINTMSK_STALLM_Pos) /*!< 0x00000008 */ -#define USB_OTG_HCINTMSK_STALLM USB_OTG_HCINTMSK_STALLM_Msk /*!< STALL response received interrupt mask */ -#define USB_OTG_HCINTMSK_NAKM_Pos (4U) -#define USB_OTG_HCINTMSK_NAKM_Msk (0x1UL << USB_OTG_HCINTMSK_NAKM_Pos) /*!< 0x00000010 */ -#define USB_OTG_HCINTMSK_NAKM USB_OTG_HCINTMSK_NAKM_Msk /*!< NAK response received interrupt mask */ -#define USB_OTG_HCINTMSK_ACKM_Pos (5U) -#define USB_OTG_HCINTMSK_ACKM_Msk (0x1UL << USB_OTG_HCINTMSK_ACKM_Pos) /*!< 0x00000020 */ -#define USB_OTG_HCINTMSK_ACKM USB_OTG_HCINTMSK_ACKM_Msk /*!< ACK response received/transmitted interrupt mask */ -#define USB_OTG_HCINTMSK_NYET_Pos (6U) -#define USB_OTG_HCINTMSK_NYET_Msk (0x1UL << USB_OTG_HCINTMSK_NYET_Pos) /*!< 0x00000040 */ -#define USB_OTG_HCINTMSK_NYET USB_OTG_HCINTMSK_NYET_Msk /*!< response received interrupt mask */ -#define USB_OTG_HCINTMSK_TXERRM_Pos (7U) -#define USB_OTG_HCINTMSK_TXERRM_Msk (0x1UL << USB_OTG_HCINTMSK_TXERRM_Pos) /*!< 0x00000080 */ -#define USB_OTG_HCINTMSK_TXERRM USB_OTG_HCINTMSK_TXERRM_Msk /*!< Transaction error mask */ -#define USB_OTG_HCINTMSK_BBERRM_Pos (8U) -#define USB_OTG_HCINTMSK_BBERRM_Msk (0x1UL << USB_OTG_HCINTMSK_BBERRM_Pos) /*!< 0x00000100 */ -#define USB_OTG_HCINTMSK_BBERRM USB_OTG_HCINTMSK_BBERRM_Msk /*!< Babble error mask */ -#define USB_OTG_HCINTMSK_FRMORM_Pos (9U) -#define USB_OTG_HCINTMSK_FRMORM_Msk (0x1UL << USB_OTG_HCINTMSK_FRMORM_Pos) /*!< 0x00000200 */ -#define USB_OTG_HCINTMSK_FRMORM USB_OTG_HCINTMSK_FRMORM_Msk /*!< Frame overrun mask */ -#define USB_OTG_HCINTMSK_DTERRM_Pos (10U) -#define USB_OTG_HCINTMSK_DTERRM_Msk (0x1UL << USB_OTG_HCINTMSK_DTERRM_Pos) /*!< 0x00000400 */ -#define USB_OTG_HCINTMSK_DTERRM USB_OTG_HCINTMSK_DTERRM_Msk /*!< Data toggle error mask */ - -/******************** Bit definition for USB_OTG_DIEPTSIZ register ********************/ - -#define USB_OTG_DIEPTSIZ_XFRSIZ_Pos (0U) -#define USB_OTG_DIEPTSIZ_XFRSIZ_Msk (0x7FFFFUL << USB_OTG_DIEPTSIZ_XFRSIZ_Pos) /*!< 0x0007FFFF */ -#define USB_OTG_DIEPTSIZ_XFRSIZ USB_OTG_DIEPTSIZ_XFRSIZ_Msk /*!< Transfer size */ -#define USB_OTG_DIEPTSIZ_PKTCNT_Pos (19U) -#define USB_OTG_DIEPTSIZ_PKTCNT_Msk (0x3FFUL << USB_OTG_DIEPTSIZ_PKTCNT_Pos) /*!< 0x1FF80000 */ -#define USB_OTG_DIEPTSIZ_PKTCNT USB_OTG_DIEPTSIZ_PKTCNT_Msk /*!< Packet count */ -#define USB_OTG_DIEPTSIZ_MULCNT_Pos (29U) -#define USB_OTG_DIEPTSIZ_MULCNT_Msk (0x3UL << USB_OTG_DIEPTSIZ_MULCNT_Pos) /*!< 0x60000000 */ -#define USB_OTG_DIEPTSIZ_MULCNT USB_OTG_DIEPTSIZ_MULCNT_Msk /*!< Packet count */ -/******************** Bit definition for USB_OTG_HCTSIZ register ********************/ -#define USB_OTG_HCTSIZ_XFRSIZ_Pos (0U) -#define USB_OTG_HCTSIZ_XFRSIZ_Msk (0x7FFFFUL << USB_OTG_HCTSIZ_XFRSIZ_Pos) /*!< 0x0007FFFF */ -#define USB_OTG_HCTSIZ_XFRSIZ USB_OTG_HCTSIZ_XFRSIZ_Msk /*!< Transfer size */ -#define USB_OTG_HCTSIZ_PKTCNT_Pos (19U) -#define USB_OTG_HCTSIZ_PKTCNT_Msk (0x3FFUL << USB_OTG_HCTSIZ_PKTCNT_Pos) /*!< 0x1FF80000 */ -#define USB_OTG_HCTSIZ_PKTCNT USB_OTG_HCTSIZ_PKTCNT_Msk /*!< Packet count */ -#define USB_OTG_HCTSIZ_DOPING_Pos (31U) -#define USB_OTG_HCTSIZ_DOPING_Msk (0x1UL << USB_OTG_HCTSIZ_DOPING_Pos) /*!< 0x80000000 */ -#define USB_OTG_HCTSIZ_DOPING USB_OTG_HCTSIZ_DOPING_Msk /*!< Do PING */ -#define USB_OTG_HCTSIZ_DPID_Pos (29U) -#define USB_OTG_HCTSIZ_DPID_Msk (0x3UL << USB_OTG_HCTSIZ_DPID_Pos) /*!< 0x60000000 */ -#define USB_OTG_HCTSIZ_DPID USB_OTG_HCTSIZ_DPID_Msk /*!< Data PID */ -#define USB_OTG_HCTSIZ_DPID_0 (0x1UL << USB_OTG_HCTSIZ_DPID_Pos) /*!< 0x20000000 */ -#define USB_OTG_HCTSIZ_DPID_1 (0x2UL << USB_OTG_HCTSIZ_DPID_Pos) /*!< 0x40000000 */ - -/******************** Bit definition for USB_OTG_DIEPDMA register ********************/ -#define USB_OTG_DIEPDMA_DMAADDR_Pos (0U) -#define USB_OTG_DIEPDMA_DMAADDR_Msk (0xFFFFFFFFUL << USB_OTG_DIEPDMA_DMAADDR_Pos) /*!< 0xFFFFFFFF */ -#define USB_OTG_DIEPDMA_DMAADDR USB_OTG_DIEPDMA_DMAADDR_Msk /*!< DMA address */ - -/******************** Bit definition for USB_OTG_HCDMA register ********************/ -#define USB_OTG_HCDMA_DMAADDR_Pos (0U) -#define USB_OTG_HCDMA_DMAADDR_Msk (0xFFFFFFFFUL << USB_OTG_HCDMA_DMAADDR_Pos) /*!< 0xFFFFFFFF */ -#define USB_OTG_HCDMA_DMAADDR USB_OTG_HCDMA_DMAADDR_Msk /*!< DMA address */ - -/******************** Bit definition for USB_OTG_DTXFSTS register ********************/ -#define USB_OTG_DTXFSTS_INEPTFSAV_Pos (0U) -#define USB_OTG_DTXFSTS_INEPTFSAV_Msk (0xFFFFUL << USB_OTG_DTXFSTS_INEPTFSAV_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_DTXFSTS_INEPTFSAV USB_OTG_DTXFSTS_INEPTFSAV_Msk /*!< IN endpoint TxFIFO space available */ - -/******************** Bit definition for USB_OTG_DIEPTXF register ********************/ -#define USB_OTG_DIEPTXF_INEPTXSA_Pos (0U) -#define USB_OTG_DIEPTXF_INEPTXSA_Msk (0xFFFFUL << USB_OTG_DIEPTXF_INEPTXSA_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_DIEPTXF_INEPTXSA USB_OTG_DIEPTXF_INEPTXSA_Msk /*!< IN endpoint FIFOx transmit RAM start address */ -#define USB_OTG_DIEPTXF_INEPTXFD_Pos (16U) -#define USB_OTG_DIEPTXF_INEPTXFD_Msk (0xFFFFUL << USB_OTG_DIEPTXF_INEPTXFD_Pos) /*!< 0xFFFF0000 */ -#define USB_OTG_DIEPTXF_INEPTXFD USB_OTG_DIEPTXF_INEPTXFD_Msk /*!< IN endpoint TxFIFO depth */ - -/******************** Bit definition for USB_OTG_DOEPCTL register ********************/ - -#define USB_OTG_DOEPCTL_MPSIZ_Pos (0U) -#define USB_OTG_DOEPCTL_MPSIZ_Msk (0x7FFUL << USB_OTG_DOEPCTL_MPSIZ_Pos) /*!< 0x000007FF */ -#define USB_OTG_DOEPCTL_MPSIZ USB_OTG_DOEPCTL_MPSIZ_Msk /*!< Maximum packet size */ /*! Date: Mon, 7 Mar 2022 23:03:37 +0700 Subject: [PATCH 208/504] added dcd_sof_enable(), tud_sof_isr_set() make number of interface configurable (default to 8) CFG_TUD_INTERFACE_MAX --- src/device/dcd.h | 15 +++++++++++++++ src/device/usbd.c | 18 ++++++++++++++++-- src/device/usbd.h | 6 ++++++ src/tusb_option.h | 4 ++++ 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/device/dcd.h b/src/device/dcd.h index 8efbc90ef..3eac6711f 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -77,6 +77,11 @@ typedef struct TU_ATTR_ALIGNED(4) tusb_speed_t speed; } bus_reset; + // SOF + struct { + uint32_t frame_count; + }sof; + // SETUP_RECEIVED tusb_control_request_t setup_received; @@ -132,6 +137,9 @@ void dcd_connect(uint8_t rhport) TU_ATTR_WEAK; // Disconnect by disabling internal pull-up resistor on D+/D- void dcd_disconnect(uint8_t rhport) TU_ATTR_WEAK; +// Enable/Disable Start-of-frame interrupt. Default is disabled +void dcd_sof_enable(uint8_t rhport, bool en); + //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ @@ -185,6 +193,13 @@ extern void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool // helper to send transfer complete event extern void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr); +static inline void dcd_event_sof(uint8_t rhport, uint32_t frame_count, bool in_isr) +{ + dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SOF }; + event.sof.frame_count = frame_count; + dcd_event_handler(&event, in_isr); +} + #ifdef __cplusplus } #endif diff --git a/src/device/usbd.c b/src/device/usbd.c index 7926689b7..8662d5b84 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -67,7 +67,7 @@ typedef struct volatile uint8_t cfg_num; // current active configuration (0x00 is not configured) uint8_t speed; - uint8_t itf2drv[16]; // map interface number to driver (0xff is invalid) + uint8_t itf2drv[CFG_TUD_INTERFACE_MAX]; // map interface number to driver (0xff is invalid) uint8_t ep2drv[CFG_TUD_ENDPPOINT_MAX][2]; // map endpoint to driver ( 0xff is invalid ) struct TU_ATTR_PACKED @@ -269,6 +269,8 @@ static inline usbd_class_driver_t const * get_driver(uint8_t drvid) // DCD Event //--------------------------------------------------------------------+ +static tud_sof_isr_t _sof_isr = NULL; + enum { RHPORT_INVALID = 0xFFu }; static uint8_t _usbd_rhport = RHPORT_INVALID; @@ -393,6 +395,12 @@ bool tud_connect(void) return true; } +void tud_sof_isr_set(tud_sof_isr_t sof_isr) +{ + _sof_isr = sof_isr; + dcd_sof_enable(_usbd_rhport, _sof_isr != NULL); +} + //--------------------------------------------------------------------+ // USBD Task //--------------------------------------------------------------------+ @@ -435,11 +443,13 @@ bool tud_init (uint8_t rhport) driver->init(); } + _usbd_rhport = rhport; + _sof_isr = NULL; + // Init device controller driver dcd_init(rhport); dcd_int_enable(rhport); - _usbd_rhport = rhport; return true; } @@ -1121,11 +1131,15 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr) break; case DCD_EVENT_SOF: + // SOF Handler + if (_sof_isr) _sof_isr(event->sof.frame_count); + // Some MCUs after running dcd_remote_wakeup() does not have way to detect the end of remote wakeup // which last 1-15 ms. DCD can use SOF as a clear indicator that bus is back to operational if ( _usbd_dev.suspended ) { _usbd_dev.suspended = 0; + dcd_event_t const event_resume = { .rhport = event->rhport, .event_id = DCD_EVENT_RESUME }; osal_queue_send(_usbd_q, &event_resume, in_isr); } diff --git a/src/device/usbd.h b/src/device/usbd.h index b2bf8ba9d..72401a7e9 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -33,6 +33,8 @@ extern "C" { #endif +typedef void (*tud_sof_isr_t) (uint32_t frame_count); + //--------------------------------------------------------------------+ // Application API //--------------------------------------------------------------------+ @@ -84,6 +86,10 @@ bool tud_disconnect(void); // Return false on unsupported MCUs bool tud_connect(void); +// Set Start-of-frame (1ms interval) IRQ handler +// NULL means disabled, frame_count may not be supported on mcus +void tud_sof_isr_set(tud_sof_isr_t sof_isr); + // Carry out Data and Status stage of control transfer // - If len = 0, it is equivalent to sending status only // - If len > wLength : it will be truncated diff --git a/src/tusb_option.h b/src/tusb_option.h index 25e536787..9c8c274b1 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -287,6 +287,10 @@ #define CFG_TUD_ENDPOINT0_SIZE 64 #endif +#ifndef CFG_TUD_INTERFACE_MAX + #define CFG_TUD_INTERFACE_MAX 8 +#endif + #ifndef CFG_TUD_CDC #define CFG_TUD_CDC 0 #endif From 85dbcf5473f8f5d914c4c468715c5381ab2a6603 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 7 Mar 2022 23:04:47 +0700 Subject: [PATCH 209/504] implement dcd_sof_enable() for rp2040 --- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 23 ++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index 915822798..f7b105b6e 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -247,6 +247,12 @@ static void dcd_rp2040_irq(void) uint32_t const status = usb_hw->ints; uint32_t handled = 0; + if (status & USB_INTF_DEV_SOF_BITS) + { + handled |= USB_INTF_DEV_SOF_BITS; + dcd_event_sof(0, usb_hw->sof_rd & USB_SOF_RD_BITS, true); + } + // xfer events are handled before setup req. So if a transfer completes immediately // before closing the EP, the events will be delivered in same order. if (status & USB_INTS_BUFF_STATUS_BITS) @@ -424,6 +430,23 @@ void dcd_connect(__unused uint8_t rhport) usb_hw_set->sie_ctrl = USB_SIE_CTRL_PULLUP_EN_BITS; } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + + uint32_t inte = usb_hw->inte; + + if (en) + { + inte |= USB_INTS_DEV_SOF_BITS; + }else + { + inte &= ~USB_INTS_DEV_SOF_BITS; + } + + usb_hw->inte = inte; +} + /*------------------------------------------------------------------*/ /* DCD Endpoint port *------------------------------------------------------------------*/ From 606f932d92322a71960f51148ecc91eaf29bf507 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 7 Mar 2022 23:05:05 +0700 Subject: [PATCH 210/504] added dcd_sof_enable() stubs for all other ports --- src/portable/bridgetek/ft9xx/dcd_ft9xx.c | 7 +++++++ src/portable/chipidea/ci_hs/dcd_ci_hs.c | 8 ++++++++ src/portable/dialog/da146xx/dcd_da146xx.c | 8 ++++++++ src/portable/espressif/esp32sx/dcd_esp32sx.c | 8 ++++++++ src/portable/mentor/musb/dcd_musb.c | 8 ++++++++ src/portable/microchip/pic32mz/dcd_pic32mz.c | 8 ++++++++ src/portable/microchip/samd/dcd_samd.c | 8 ++++++++ src/portable/microchip/samg/dcd_samg.c | 8 ++++++++ src/portable/microchip/samx7x/dcd_samx7x.c | 8 ++++++++ src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c | 8 ++++++++ src/portable/nordic/nrf5x/dcd_nrf5x.c | 8 ++++++++ src/portable/nuvoton/nuc120/dcd_nuc120.c | 8 ++++++++ src/portable/nuvoton/nuc121/dcd_nuc121.c | 8 ++++++++ src/portable/nuvoton/nuc505/dcd_nuc505.c | 8 ++++++++ src/portable/nxp/khci/dcd_khci.c | 8 ++++++++ src/portable/nxp/lpc17_40/dcd_lpc17_40.c | 8 ++++++++ src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c | 8 ++++++++ src/portable/nxp/transdimension/dcd_transdimension.c | 8 ++++++++ src/portable/renesas/usba/dcd_usba.c | 8 ++++++++ src/portable/sony/cxd56/dcd_cxd56.c | 8 ++++++++ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 8 ++++++++ src/portable/st/synopsys/dcd_synopsys.c | 7 +++++++ src/portable/sunxi/dcd_sunxi_musb.c | 8 ++++++++ src/portable/synopsys/dwc2/dcd_dwc2.c | 7 +++++++ src/portable/template/dcd_template.c | 8 ++++++++ src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 8 ++++++++ src/portable/valentyusb/eptri/dcd_eptri.c | 7 +++++++ 27 files changed, 212 insertions(+) diff --git a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c index 791f6cf60..3c3cb63b8 100644 --- a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c +++ b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c @@ -649,6 +649,13 @@ void dcd_disconnect(uint8_t rhport) _ft90x_phy_enable(false); } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} //--------------------------------------------------------------------+ // Endpoint API diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c index 32c2fc029..41d2f1870 100644 --- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c @@ -266,6 +266,14 @@ void dcd_disconnect(uint8_t rhport) dcd_reg->USBCMD &= ~USBCMD_RUN_STOP; } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + //--------------------------------------------------------------------+ // HELPER //--------------------------------------------------------------------+ diff --git a/src/portable/dialog/da146xx/dcd_da146xx.c b/src/portable/dialog/da146xx/dcd_da146xx.c index 919249a09..0bb8b6e41 100644 --- a/src/portable/dialog/da146xx/dcd_da146xx.c +++ b/src/portable/dialog/da146xx/dcd_da146xx.c @@ -882,6 +882,14 @@ void dcd_disconnect(uint8_t rhport) REG_CLR_BIT(USB_MCTRL_REG, USB_NAT); } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + TU_ATTR_ALWAYS_INLINE static inline bool is_in_isr(void) { return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) != 0; diff --git a/src/portable/espressif/esp32sx/dcd_esp32sx.c b/src/portable/espressif/esp32sx/dcd_esp32sx.c index bd8805dd3..a30fca0d8 100644 --- a/src/portable/espressif/esp32sx/dcd_esp32sx.c +++ b/src/portable/espressif/esp32sx/dcd_esp32sx.c @@ -240,6 +240,14 @@ void dcd_disconnect(uint8_t rhport) USB0.dctl |= USB_SFTDISCON_M; } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + /*------------------------------------------------------------------*/ /* DCD Endpoint port *------------------------------------------------------------------*/ diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index d36585592..0ba53d4d0 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -648,6 +648,14 @@ void dcd_disconnect(uint8_t rhport) USB0->POWER &= ~USB_POWER_SOFTCONN; } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ diff --git a/src/portable/microchip/pic32mz/dcd_pic32mz.c b/src/portable/microchip/pic32mz/dcd_pic32mz.c index 7d48f755b..db93644b1 100644 --- a/src/portable/microchip/pic32mz/dcd_pic32mz.c +++ b/src/portable/microchip/pic32mz/dcd_pic32mz.c @@ -186,6 +186,14 @@ void dcd_disconnect(uint8_t rhport) USB_REGS->POWERbits.SOFTCONN = 1; } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + TU_ATTR_ALWAYS_INLINE static inline bool is_in_isr(void) { return (_CP0_GET_STATUS() & (_CP0_STATUS_EXL_MASK | _CP0_STATUS_IPL_MASK)) != 0; diff --git a/src/portable/microchip/samd/dcd_samd.c b/src/portable/microchip/samd/dcd_samd.c index c4ee6f2f5..5ae5a554b 100644 --- a/src/portable/microchip/samd/dcd_samd.c +++ b/src/portable/microchip/samd/dcd_samd.c @@ -180,6 +180,14 @@ void dcd_connect(uint8_t rhport) USB->DEVICE.CTRLB.reg &= ~USB_DEVICE_CTRLB_DETACH; } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + /*------------------------------------------------------------------*/ /* DCD Endpoint port *------------------------------------------------------------------*/ diff --git a/src/portable/microchip/samg/dcd_samg.c b/src/portable/microchip/samg/dcd_samg.c index 2e9854153..814e680fb 100644 --- a/src/portable/microchip/samg/dcd_samg.c +++ b/src/portable/microchip/samg/dcd_samg.c @@ -210,6 +210,14 @@ void dcd_disconnect(uint8_t rhport) UDP->UDP_TXVC = UDP_TXVC_TXVDIS_Msk; } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ diff --git a/src/portable/microchip/samx7x/dcd_samx7x.c b/src/portable/microchip/samx7x/dcd_samx7x.c index a82f29a88..7507c0f69 100644 --- a/src/portable/microchip/samx7x/dcd_samx7x.c +++ b/src/portable/microchip/samx7x/dcd_samx7x.c @@ -191,6 +191,14 @@ void dcd_disconnect(uint8_t rhport) USB_REG->DEVCTRL &=~(DEVCTRL_ADDEN | DEVCTRL_UADD); } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + static tusb_speed_t get_speed(void) { switch (USB_REG->SR & SR_SPEED) { diff --git a/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c b/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c index 1edcd8458..39b09db68 100644 --- a/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c +++ b/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c @@ -305,6 +305,14 @@ void dcd_disconnect(uint8_t rhport) USB_OTG_FS->CTL = 0; } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index bc145eaa4..430d8eded 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -307,6 +307,14 @@ void dcd_connect(uint8_t rhport) NRF_USBD->USBPULLUP = 1; } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ diff --git a/src/portable/nuvoton/nuc120/dcd_nuc120.c b/src/portable/nuvoton/nuc120/dcd_nuc120.c index 694766613..2fdc05f36 100644 --- a/src/portable/nuvoton/nuc120/dcd_nuc120.c +++ b/src/portable/nuvoton/nuc120/dcd_nuc120.c @@ -497,4 +497,12 @@ void dcd_connect(uint8_t rhport) usb_attach(); } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + #endif diff --git a/src/portable/nuvoton/nuc121/dcd_nuc121.c b/src/portable/nuvoton/nuc121/dcd_nuc121.c index 88d514bce..a56b5f8e8 100644 --- a/src/portable/nuvoton/nuc121/dcd_nuc121.c +++ b/src/portable/nuvoton/nuc121/dcd_nuc121.c @@ -551,4 +551,12 @@ void dcd_connect(uint8_t rhport) usb_attach(); } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + #endif diff --git a/src/portable/nuvoton/nuc505/dcd_nuc505.c b/src/portable/nuvoton/nuc505/dcd_nuc505.c index 498977561..886720e33 100644 --- a/src/portable/nuvoton/nuc505/dcd_nuc505.c +++ b/src/portable/nuvoton/nuc505/dcd_nuc505.c @@ -720,4 +720,12 @@ void dcd_connect(uint8_t rhport) usb_attach(); } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + #endif diff --git a/src/portable/nxp/khci/dcd_khci.c b/src/portable/nxp/khci/dcd_khci.c index 4c7737103..13eb105cd 100644 --- a/src/portable/nxp/khci/dcd_khci.c +++ b/src/portable/nxp/khci/dcd_khci.c @@ -328,6 +328,14 @@ void dcd_disconnect(uint8_t rhport) KHCI->CONTROL &= ~USB_CONTROL_DPPULLUPNONOTG_MASK; } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ diff --git a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c index d2cce2db3..0894a5eeb 100644 --- a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c +++ b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c @@ -228,6 +228,14 @@ void dcd_disconnect(uint8_t rhport) sie_write(SIE_CMDCODE_DEVICE_STATUS, 1, 0); } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + //--------------------------------------------------------------------+ // CONTROL HELPER //--------------------------------------------------------------------+ diff --git a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c index 55d872dc0..09ebf3b0d 100644 --- a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c +++ b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c @@ -277,6 +277,14 @@ void dcd_disconnect(uint8_t rhport) dcd_reg->DEVCMDSTAT &= ~CMDSTAT_DEVICE_CONNECT_MASK; } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + //--------------------------------------------------------------------+ // DCD Endpoint Port //--------------------------------------------------------------------+ diff --git a/src/portable/nxp/transdimension/dcd_transdimension.c b/src/portable/nxp/transdimension/dcd_transdimension.c index 108baf99d..2347e1dae 100644 --- a/src/portable/nxp/transdimension/dcd_transdimension.c +++ b/src/portable/nxp/transdimension/dcd_transdimension.c @@ -294,6 +294,14 @@ void dcd_disconnect(uint8_t rhport) dcd_reg->USBCMD &= ~USBCMD_RUN_STOP; } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + //--------------------------------------------------------------------+ // HELPER //--------------------------------------------------------------------+ diff --git a/src/portable/renesas/usba/dcd_usba.c b/src/portable/renesas/usba/dcd_usba.c index 330f65348..fa87c9f4d 100644 --- a/src/portable/renesas/usba/dcd_usba.c +++ b/src/portable/renesas/usba/dcd_usba.c @@ -687,6 +687,14 @@ void dcd_disconnect(uint8_t rhport) USB0.SYSCFG.BIT.DPRPU = 0; } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ diff --git a/src/portable/sony/cxd56/dcd_cxd56.c b/src/portable/sony/cxd56/dcd_cxd56.c index fbea03b1d..6aa0efb21 100644 --- a/src/portable/sony/cxd56/dcd_cxd56.c +++ b/src/portable/sony/cxd56/dcd_cxd56.c @@ -247,6 +247,14 @@ void dcd_disconnect(uint8_t rhport) DEV_DISCONNECT(usbdev); } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index f201a02cf..836711974 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -287,6 +287,14 @@ void dcd_connect(uint8_t rhport) } #endif +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + // Enable device interrupt void dcd_int_enable (uint8_t rhport) { diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index d7f659340..2fc3adb4f 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -602,6 +602,13 @@ void dcd_disconnect(uint8_t rhport) dev->DCTL |= USB_OTG_DCTL_SDIS; } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} /*------------------------------------------------------------------*/ /* DCD Endpoint port diff --git a/src/portable/sunxi/dcd_sunxi_musb.c b/src/portable/sunxi/dcd_sunxi_musb.c index 27514339b..a0be846a5 100644 --- a/src/portable/sunxi/dcd_sunxi_musb.c +++ b/src/portable/sunxi/dcd_sunxi_musb.c @@ -909,6 +909,14 @@ void dcd_disconnect(uint8_t rhport) USBC_REG_clear_bit_b(USBC_BP_POWER_D_SOFT_CONNECT, USBC_REG_PCTL(USBC0_BASE)); } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + void dcd_int_enable(uint8_t rhport) { (void)rhport; diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index c71f38d2d..37712d2d9 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -588,6 +588,13 @@ void dcd_disconnect(uint8_t rhport) dwc2->dctl |= DCTL_SDIS; } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} /*------------------------------------------------------------------*/ /* DCD Endpoint port diff --git a/src/portable/template/dcd_template.c b/src/portable/template/dcd_template.c index 977369300..26b5dce9d 100644 --- a/src/portable/template/dcd_template.c +++ b/src/portable/template/dcd_template.c @@ -82,6 +82,14 @@ void dcd_disconnect(uint8_t rhport) (void) rhport; } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index c3b3b2403..605c13b4a 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -222,6 +222,14 @@ void dcd_disconnect(uint8_t rhport) dcd_int_enable(rhport); } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + /*------------------------------------------------------------------*/ /* DCD Endpoint port *------------------------------------------------------------------*/ diff --git a/src/portable/valentyusb/eptri/dcd_eptri.c b/src/portable/valentyusb/eptri/dcd_eptri.c index dfadfdcb3..e368b5f39 100644 --- a/src/portable/valentyusb/eptri/dcd_eptri.c +++ b/src/portable/valentyusb/eptri/dcd_eptri.c @@ -401,6 +401,13 @@ void dcd_disconnect(uint8_t rhport) usb_pullup_out_write(0); } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} //--------------------------------------------------------------------+ // DCD Endpoint Port From 6b2ea2bd1dbf05ae9fb04546b532df293521ccfb Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 8 Mar 2022 13:52:20 +0700 Subject: [PATCH 211/504] fix issue 1359 --- src/tusb_option.h | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/tusb_option.h b/src/tusb_option.h index 25e536787..b613eec44 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -207,18 +207,23 @@ //------------- Roothub as Device -------------// #if (CFG_TUSB_RHPORT0_MODE) & OPT_MODE_DEVICE - #define TUD_RHPORT_MODE (CFG_TUSB_RHPORT0_MODE) - #define TUD_OPT_RHPORT 0 + #define TUD_RHPORT_MODE (CFG_TUSB_RHPORT0_MODE) + #define TUD_OPT_RHPORT 0 #elif (CFG_TUSB_RHPORT1_MODE) & OPT_MODE_DEVICE - #define TUD_RHPORT_MODE (CFG_TUSB_RHPORT1_MODE) - #define TUD_OPT_RHPORT 1 + #define TUD_RHPORT_MODE (CFG_TUSB_RHPORT1_MODE) + #define TUD_OPT_RHPORT 1 #else - #define TUD_RHPORT_MODE OPT_MODE_NONE - #define TUD_OPT_RHPORT -1 + #define TUD_RHPORT_MODE OPT_MODE_NONE + #define TUD_OPT_RHPORT -1 #endif -#define CFG_TUD_ENABLED ( TUD_RHPORT_MODE & OPT_MODE_DEVICE ) -#define TUD_OPT_HIGH_SPEED ( (TUD_RHPORT_MODE & OPT_MODE_SPEED_MASK) ? (TUD_RHPORT_MODE & OPT_MODE_HIGH_SPEED) : (TUP_RHPORT_HIGHSPEED & (1 << TUD_OPT_RHPORT)) ) +#define CFG_TUD_ENABLED (TUD_RHPORT_MODE & OPT_MODE_DEVICE) + +#if CFG_TUD_ENABLED + #define TUD_OPT_HIGH_SPEED ((TUD_RHPORT_MODE & OPT_MODE_SPEED_MASK) ? (TUD_RHPORT_MODE & OPT_MODE_HIGH_SPEED) : (TUP_RHPORT_HIGHSPEED & (1 << TUD_OPT_RHPORT))) +#else + #define TUD_OPT_HIGH_SPEED 0 +#endif //------------- Roothub as Host -------------// From db9d97c9473f29ad59a87d641e6d41a27a00f332 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 9 Mar 2022 11:03:29 +0700 Subject: [PATCH 212/504] add tuh_descriptor_hid_report_get() --- examples/host/bare_api/src/main.c | 48 ++++++++++++++++++++++++++----- src/class/hid/hid_host.c | 17 +---------- src/host/usbh.c | 22 ++++++++++++++ src/host/usbh.h | 3 ++ 4 files changed, 67 insertions(+), 23 deletions(-) diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index b6b1527c0..2fe5999bc 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -64,23 +64,57 @@ int main(void) // TinyUSB Callbacks //--------------------------------------------------------------------+ -void print_device_descriptor(uint8_t dev_addr) +uint8_t usb_buf[256] TU_ATTR_ALIGNED(4); + +tusb_desc_device_t desc_device; + +bool print_device_descriptor(uint8_t daddr, tusb_control_request_t const * request, xfer_result_t result) { - (void) dev_addr; + (void) request; + + if ( XFER_RESULT_SUCCESS != result ) + { + printf("Failed to get device descriptor\r\n"); + return false; + } + + printf("Rhport %u Device %u: ID %04x:%04x\r\n", 0, daddr, desc_device.idVendor, desc_device.idProduct); printf("Device Descriptor:\r\n"); + printf(" bLength %u\r\n", desc_device.bLength); + printf(" bDescriptorType %u\r\n", desc_device.bDescriptorType); + printf(" bcdUSB %04x\r\n", desc_device.bcdUSB); + + printf(" bDeviceClass %u\r\n", desc_device.bDeviceClass); + printf(" bDeviceSubClass %u\r\n", desc_device.bDeviceSubClass); + printf(" bDeviceProtocol %u\r\n", desc_device.bDeviceProtocol); + printf(" bMaxPacketSize0 %u\r\n", desc_device.bMaxPacketSize0); + + printf(" idVendor 0x%04x\r\n", desc_device.idVendor); + printf(" idProduct 0x%04x\r\n", desc_device.idProduct); + printf(" bcdDevice %04x\r\n", desc_device.bcdDevice); + + printf(" iManufacturer %u\r\n", desc_device.iManufacturer); + printf(" iProduct %u\r\n", desc_device.iProduct); + printf(" iSerialNumber %u\r\n", desc_device.iSerialNumber); + + printf(" bNumConfigurations %u\r\n", desc_device.bNumConfigurations); + + return true; } // Invoked when device is mounted (configured) -void tuh_mount_cb (uint8_t dev_addr) +void tuh_mount_cb (uint8_t daddr) { - printf("Device attached, address = %d\r\n", dev_addr); - print_device_descriptor(dev_addr); + printf("Device attached, address = %d\r\n", daddr); + + // get device descriptor + tuh_descriptor_device_get(daddr, &desc_device, 18, print_device_descriptor); } /// Invoked when device is unmounted (bus reset/unplugged) -void tuh_umount_cb(uint8_t dev_addr) +void tuh_umount_cb(uint8_t daddr) { - printf("Device removed, address = %d\r\n", dev_addr); + printf("Device removed, address = %d\r\n", daddr); } //--------------------------------------------------------------------+ diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 9190642c6..32bb775b0 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -409,22 +409,7 @@ static bool config_get_report_desc(uint8_t dev_addr, tusb_control_request_t cons config_driver_mount_complete(dev_addr, instance, NULL, 0); }else { - TU_LOG2("HID Get Report Descriptor\r\n"); - tusb_control_request_t const new_request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_IN - }, - .bRequest = TUSB_REQ_GET_DESCRIPTOR, - .wValue = tu_u16(hid_itf->report_desc_type, 0), - .wIndex = itf_num, - .wLength = hid_itf->report_desc_len - }; - - TU_ASSERT(tuh_control_xfer(dev_addr, &new_request, usbh_get_enum_buf(), config_get_report_desc_complete)); + TU_ASSERT(tuh_descriptor_hid_report_get(dev_addr, itf_num, hid_itf->report_desc_type, usbh_get_enum_buf(), hid_itf->report_desc_len, config_get_report_desc_complete)); } return true; diff --git a/src/host/usbh.c b/src/host/usbh.c index 192979ce6..b047179c5 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -299,6 +299,7 @@ bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, void* buffer bool tuh_descriptor_device_get(uint8_t daddr, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) { + len = tu_min16(len, sizeof(tusb_desc_device_t)); return tuh_descriptor_get(daddr, TUSB_DESC_DEVICE, 0, buffer, len, complete_cb); } @@ -361,6 +362,27 @@ bool tuh_descriptor_string_serial_get(uint8_t daddr, uint16_t language_id, void* return tuh_descriptor_string_get(daddr, language_id, dev->i_serial, buffer, len, complete_cb); } +// Get HID report descriptor +bool tuh_descriptor_hid_report_get(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +{ + TU_LOG2("HID Get Report Descriptor\r\n"); + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_IN + }, + .bRequest = TUSB_REQ_GET_DESCRIPTOR, + .wValue = tu_htole16(TU_U16(desc_type, 0)), + .wIndex = itf_num, + .wLength = len + }; + + return tuh_control_xfer(daddr, &request, buffer, complete_cb); +} + bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, tuh_control_complete_cb_t complete_cb) { TU_LOG2("Set Configuration = %d\r\n", config_num); diff --git a/src/host/usbh.h b/src/host/usbh.h index 9465d1d1b..6fea2fac5 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -112,6 +112,9 @@ bool tuh_descriptor_string_product_get(uint8_t daddr, uint16_t language_id, void // Get serial string descriptor bool tuh_descriptor_string_serial_get(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); +// Get HID report descriptor +bool tuh_descriptor_hid_report_get(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); + //--------------------------------------------------------------------+ // APPLICATION CALLBACK //--------------------------------------------------------------------+ From f920e1c17102cac04b20ad3908efff24d96d8e7c Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 9 Mar 2022 11:21:13 +0700 Subject: [PATCH 213/504] rename host descriptor function --- examples/host/bare_api/src/main.c | 2 +- src/class/hid/hid_host.c | 2 +- src/host/usbh.c | 28 ++++++++++++++-------------- src/host/usbh.h | 14 +++++++------- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index 2fe5999bc..5f8f886c8 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -108,7 +108,7 @@ void tuh_mount_cb (uint8_t daddr) printf("Device attached, address = %d\r\n", daddr); // get device descriptor - tuh_descriptor_device_get(daddr, &desc_device, 18, print_device_descriptor); + tuh_descriptor_get_device(daddr, &desc_device, 18, print_device_descriptor); } /// Invoked when device is unmounted (bus reset/unplugged) diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 32bb775b0..323debe69 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -409,7 +409,7 @@ static bool config_get_report_desc(uint8_t dev_addr, tusb_control_request_t cons config_driver_mount_complete(dev_addr, instance, NULL, 0); }else { - TU_ASSERT(tuh_descriptor_hid_report_get(dev_addr, itf_num, hid_itf->report_desc_type, usbh_get_enum_buf(), hid_itf->report_desc_len, config_get_report_desc_complete)); + TU_ASSERT(tuh_descriptor_get_hid_report(dev_addr, itf_num, hid_itf->report_desc_type, usbh_get_enum_buf(), hid_itf->report_desc_len, config_get_report_desc_complete)); } return true; diff --git a/src/host/usbh.c b/src/host/usbh.c index b047179c5..74c763552 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -297,18 +297,18 @@ bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, void* buffer return true; } -bool tuh_descriptor_device_get(uint8_t daddr, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +bool tuh_descriptor_get_device(uint8_t daddr, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) { len = tu_min16(len, sizeof(tusb_desc_device_t)); return tuh_descriptor_get(daddr, TUSB_DESC_DEVICE, 0, buffer, len, complete_cb); } -bool tuh_descriptor_configuration_get(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +bool tuh_descriptor_get_configuration(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) { return tuh_descriptor_get(daddr, TUSB_DESC_CONFIGURATION, index, buffer, len, complete_cb); } -bool tuh_descriptor_string_get(uint8_t daddr, uint16_t language_id, uint8_t index, +bool tuh_descriptor_get_string(uint8_t daddr, uint16_t language_id, uint8_t index, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) { tusb_control_request_t const request = @@ -330,40 +330,40 @@ bool tuh_descriptor_string_get(uint8_t daddr, uint16_t language_id, uint8_t inde } // Get manufacturer string descriptor -bool tuh_descriptor_string_manufacturer_get(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +bool tuh_descriptor_get_manufacturer_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) { TU_VERIFY(tuh_mounted(daddr)); usbh_device_t const* dev = get_device(daddr); if (dev->i_manufacturer == 0) { return false; } - return tuh_descriptor_string_get(daddr, language_id, dev->i_manufacturer, buffer, len, complete_cb); + return tuh_descriptor_get_string(daddr, language_id, dev->i_manufacturer, buffer, len, complete_cb); } // Get product string descriptor -bool tuh_descriptor_string_product_get(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +bool tuh_descriptor_get_product_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) { TU_VERIFY(tuh_mounted(daddr)); usbh_device_t const* dev = get_device(daddr); if (dev->i_product == 0) { return false; } - return tuh_descriptor_string_get(daddr, language_id, dev->i_product, buffer, len, complete_cb); + return tuh_descriptor_get_string(daddr, language_id, dev->i_product, buffer, len, complete_cb); } // Get serial string descriptor -bool tuh_descriptor_string_serial_get(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) { TU_VERIFY(tuh_mounted(daddr)); usbh_device_t const* dev = get_device(daddr); if (dev->i_serial == 0) { return false; } - return tuh_descriptor_string_get(daddr, language_id, dev->i_serial, buffer, len, complete_cb); + return tuh_descriptor_get_string(daddr, language_id, dev->i_serial, buffer, len, complete_cb); } // Get HID report descriptor -bool tuh_descriptor_hid_report_get(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) { TU_LOG2("HID Get Report Descriptor\r\n"); tusb_control_request_t const request = @@ -868,7 +868,7 @@ static bool enum_request_addr0_device_desc(void) // Get first 8 bytes of device descriptor for Control Endpoint size TU_LOG2("Get 8 byte of Device Descriptor\r\n"); - TU_ASSERT(tuh_descriptor_device_get(addr0, _usbh_ctrl_buf, 8, enum_get_addr0_device_desc_complete)); + TU_ASSERT(tuh_descriptor_get_device(addr0, _usbh_ctrl_buf, 8, enum_get_addr0_device_desc_complete)); return true; } @@ -977,7 +977,7 @@ static bool enum_set_address_complete(uint8_t dev_addr, tusb_control_request_t c // Get full device descriptor TU_LOG2("Get Device Descriptor\r\n"); - TU_ASSERT(tuh_descriptor_device_get(new_addr, _usbh_ctrl_buf, sizeof(tusb_desc_device_t), enum_get_device_desc_complete)); + TU_ASSERT(tuh_descriptor_get_device(new_addr, _usbh_ctrl_buf, sizeof(tusb_desc_device_t), enum_get_device_desc_complete)); return true; } @@ -1000,7 +1000,7 @@ static bool enum_get_device_desc_complete(uint8_t dev_addr, tusb_control_request // Get 9-byte for total length uint8_t const config_idx = CONFIG_NUM - 1; TU_LOG2("Get Configuration[0] Descriptor (9 bytes)\r\n"); - TU_ASSERT( tuh_descriptor_configuration_get(dev_addr, config_idx, _usbh_ctrl_buf, 9, enum_get_9byte_config_desc_complete) ); + TU_ASSERT( tuh_descriptor_get_configuration(dev_addr, config_idx, _usbh_ctrl_buf, 9, enum_get_9byte_config_desc_complete) ); return true; } @@ -1020,7 +1020,7 @@ static bool enum_get_9byte_config_desc_complete(uint8_t dev_addr, tusb_control_r // Get full configuration descriptor uint8_t const config_idx = CONFIG_NUM - 1; TU_LOG2("Get Configuration[0] Descriptor\r\n"); - TU_ASSERT( tuh_descriptor_configuration_get(dev_addr, config_idx, _usbh_ctrl_buf, total_len, enum_get_config_desc_complete) ); + TU_ASSERT( tuh_descriptor_get_configuration(dev_addr, config_idx, _usbh_ctrl_buf, total_len, enum_get_config_desc_complete) ); return true; } diff --git a/src/host/usbh.h b/src/host/usbh.h index 6fea2fac5..31d63d6a7 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -94,26 +94,26 @@ bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); // Get device descriptor -bool tuh_descriptor_device_get(uint8_t daddr, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); +bool tuh_descriptor_get_device(uint8_t daddr, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); // Get configuration descriptor -bool tuh_descriptor_configuration_get(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); +bool tuh_descriptor_get_configuration(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); // Get string descriptor -bool tuh_descriptor_string_get(uint8_t daddr, uint16_t language_id, uint8_t index, +bool tuh_descriptor_get_string(uint8_t daddr, uint16_t language_id, uint8_t index, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); // Get manufacturer string descriptor -bool tuh_descriptor_string_manufacturer_get(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); +bool tuh_descriptor_get_manufacturer_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); // Get product string descriptor -bool tuh_descriptor_string_product_get(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); +bool tuh_descriptor_get_product_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); // Get serial string descriptor -bool tuh_descriptor_string_serial_get(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); +bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); // Get HID report descriptor -bool tuh_descriptor_hid_report_get(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); +bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); //--------------------------------------------------------------------+ // APPLICATION CALLBACK From 2f593e767c28ac5b789a5def2221620c1a2e58b8 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 9 Mar 2022 12:26:56 +0700 Subject: [PATCH 214/504] update use of mutex for host --- src/device/usbd.c | 2 +- src/host/usbh.c | 96 +++++++++++++++++++++++++++-------------------- src/tusb_option.h | 3 ++ 3 files changed, 59 insertions(+), 42 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 7926689b7..b14b5e0fc 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -273,7 +273,7 @@ enum { RHPORT_INVALID = 0xFFu }; static uint8_t _usbd_rhport = RHPORT_INVALID; // Event queue -// OPT_MODE_DEVICE is used by OS NONE for mutex (disable usb isr) +// 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; diff --git a/src/host/usbh.c b/src/host/usbh.c index 74c763552..59fcb4da3 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -112,13 +112,6 @@ typedef struct { // TODO merge ep2drv here, 4-bit should be sufficient }ep_status[CFG_TUH_ENDPOINT_MAX][2]; - - // Mutex for claiming endpoint, only needed when using with preempted RTOS -#if CFG_TUSB_OS != OPT_OS_NONE - osal_mutex_def_t mutexdef; - osal_mutex_t mutex; -#endif - } usbh_device_t; @@ -204,6 +197,9 @@ enum { CONFIG_NUM = 1 }; // default to use configuration 1 // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ +// sum of end device + hub +#define TOTAL_DEVICES (CFG_TUH_DEVICE_MAX + CFG_TUH_HUB) + static bool _usbh_initialized = false; // Device with address = 0 for enumeration @@ -211,14 +207,43 @@ static usbh_dev0_t _dev0; // all devices excluding zero-address // hub address start from CFG_TUH_DEVICE_MAX+1 -CFG_TUSB_MEM_SECTION usbh_device_t _usbh_devices[CFG_TUH_DEVICE_MAX + CFG_TUH_HUB]; +// TODO: hub can has its own simpler struct to save memory +CFG_TUSB_MEM_SECTION usbh_device_t _usbh_devices[TOTAL_DEVICES]; + +// Mutex for claiming endpoint, only needed when using with preempted RTOS +#if TUSB_OPT_MUTEX + +static osal_mutex_def_t _usbh_mutexdef[TOTAL_DEVICES]; +static osal_mutex_t _usbh_mutex[TOTAL_DEVICES]; + +static inline void lock_device(uint8_t daddr) +{ + // addr0 is always available + if (daddr) return; + osal_mutex_lock(&_usbh_mutex[daddr-1], OSAL_TIMEOUT_WAIT_FOREVER); +} + +static inline void unlock_device(uint8_t daddr) +{ + // addr0 is always available + if (daddr) return; + osal_mutex_unlock(&_usbh_mutex[daddr-1]); +} + +#else + +#define lock_device(_addr) +#define unlock_device(_addr) + +#endif // Event queue -// role device/host is used by OS NONE for mutex (disable usb isr) +// usbh_int_set is used as mutex in OS NONE config OSAL_QUEUE_DEF(usbh_int_set, _usbh_qdef, CFG_TUH_TASK_QUEUE_SZ, hcd_event_t); static osal_queue_t _usbh_q; -CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t _usbh_ctrl_buf[CFG_TUH_ENUMERATION_BUFSIZE]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN +static uint8_t _usbh_ctrl_buf[CFG_TUH_ENUMERATION_BUFSIZE]; //------------- Helper Function -------------// @@ -408,6 +433,13 @@ bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, tuh_control_comple // CLASS-USBD API (don't require to verify parameters) //--------------------------------------------------------------------+ +static void clear_device(usbh_device_t* dev) +{ + tu_memclr(dev, sizeof(usbh_device_t)); + memset(dev->itf2drv, DRVID_INVALID, sizeof(dev->itf2drv)); // invalid mapping + memset(dev->ep2drv , DRVID_INVALID, sizeof(dev->ep2drv )); // invalid mapping +} + bool tuh_inited(void) { return _usbh_initialized; @@ -421,25 +453,22 @@ bool tuh_init(uint8_t rhport) TU_LOG2("USBH init\r\n"); TU_LOG2_INT(sizeof(usbh_device_t)); - tu_memclr(_usbh_devices, sizeof(_usbh_devices)); - tu_memclr(&_dev0, sizeof(_dev0)); - //------------- Enumeration & Reporter Task init -------------// _usbh_q = osal_queue_create( &_usbh_qdef ); TU_ASSERT(_usbh_q != NULL); //------------- Semaphore, Mutex for Control Pipe -------------// - for(uint8_t i=0; imutex = osal_mutex_create(&dev->mutexdef); - TU_ASSERT(dev->mutex); +#if TUSB_OPT_MUTEX + _usbh_mutex[i] = osal_mutex_create(&_usbh_mutexdef[i]); + TU_ASSERT(_usbh_mutex[i]); #endif - - memset(dev->itf2drv, DRVID_INVALID, sizeof(dev->itf2drv)); // invalid mapping - memset(dev->ep2drv , DRVID_INVALID, sizeof(dev->ep2drv )); // invalid mapping } // Class drivers init @@ -686,14 +715,7 @@ void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port } hcd_device_close(rhport, dev_addr); - - // release all endpoints associated with the device - memset(dev->itf2drv, DRVID_INVALID, sizeof(dev->itf2drv)); // invalid mapping - memset(dev->ep2drv , DRVID_INVALID, sizeof(dev->ep2drv )); // invalid mapping - tu_memclr(dev->ep_status, sizeof(dev->ep_status)); - - dev->state = TUSB_DEVICE_STATE_UNPLUG; - dev->configured = false; + clear_device(dev); } } } @@ -1161,11 +1183,9 @@ bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr) usbh_device_t* dev = get_device(dev_addr); -#if CFG_TUSB_OS != OPT_OS_NONE // pre-check to help reducing mutex lock TU_VERIFY((dev->ep_status[epnum][dir].busy == 0) && (dev->ep_status[epnum][dir].claimed == 0)); - osal_mutex_lock(dev->mutex, OSAL_TIMEOUT_WAIT_FOREVER); -#endif + lock_device(dev_addr); // can only claim the endpoint if it is not busy and not claimed yet. bool const ret = (dev->ep_status[epnum][dir].busy == 0) && (dev->ep_status[epnum][dir].claimed == 0); @@ -1174,9 +1194,7 @@ bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr) dev->ep_status[epnum][dir].claimed = 1; } -#if CFG_TUSB_OS != OPT_OS_NONE - osal_mutex_unlock(dev->mutex); -#endif + unlock_device(dev_addr); return ret; } @@ -1189,9 +1207,7 @@ bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr) usbh_device_t* dev = get_device(dev_addr); -#if CFG_TUSB_OS != OPT_OS_NONE - osal_mutex_lock(dev->mutex, OSAL_TIMEOUT_WAIT_FOREVER); -#endif + lock_device(dev_addr); // can only release the endpoint if it is claimed and not busy bool const ret = (dev->ep_status[epnum][dir].busy == 0) && (dev->ep_status[epnum][dir].claimed == 1); @@ -1200,9 +1216,7 @@ bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr) dev->ep_status[epnum][dir].claimed = 0; } -#if CFG_TUSB_OS != OPT_OS_NONE - osal_mutex_unlock(dev->mutex); -#endif + unlock_device(dev_addr); return ret; } diff --git a/src/tusb_option.h b/src/tusb_option.h index afd69c38b..e5351b1c4 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -285,6 +285,9 @@ #define CFG_TUSB_OS_INC_PATH #endif +// mutex is only needed for RTOS +#define TUSB_OPT_MUTEX (CFG_TUSB_OS != OPT_OS_NONE) + //-------------------------------------------------------------------- // DEVICE OPTIONS //-------------------------------------------------------------------- From 708f05668d681439e521379e281d087d1910a0f3 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 9 Mar 2022 16:42:51 +0700 Subject: [PATCH 215/504] add tusb_debug.h remove tusb_error.h move debug utils to new header --- src/class/cdc/cdc_host.c | 4 +- src/class/cdc/cdc_rndis_host.h | 2 +- src/class/vendor/vendor_host.h | 12 +-- src/common/tusb_common.h | 134 +------------------------ src/common/tusb_debug.h | 174 +++++++++++++++++++++++++++++++++ src/common/tusb_error.h | 77 --------------- src/common/tusb_verify.h | 28 ------ src/device/usbd.c | 21 +--- src/host/usbh.c | 13 ++- src/host/usbh_control.c | 7 +- src/tusb.c | 22 ++++- 11 files changed, 220 insertions(+), 274 deletions(-) create mode 100644 src/common/tusb_debug.h delete mode 100644 src/common/tusb_error.h diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index c18234db4..2787cd201 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -100,7 +100,7 @@ bool tuh_cdc_send(uint8_t dev_addr, void const * p_data, uint32_t length, bool i { (void) is_notify; TU_VERIFY( tuh_cdc_mounted(dev_addr) ); - TU_VERIFY( p_data != NULL && length, TUSB_ERROR_INVALID_PARA); + TU_VERIFY( p_data != NULL && length); uint8_t const ep_out = cdch_data[dev_addr-1].ep_out; if ( usbh_edpt_busy(dev_addr, ep_out) ) return false; @@ -112,7 +112,7 @@ bool tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is { (void) is_notify; TU_VERIFY( tuh_cdc_mounted(dev_addr) ); - TU_VERIFY( p_buffer != NULL && length, TUSB_ERROR_INVALID_PARA); + TU_VERIFY( p_buffer != NULL && length ); uint8_t const ep_in = cdch_data[dev_addr-1].ep_in; if ( usbh_edpt_busy(dev_addr, ep_in) ) return false; diff --git a/src/class/cdc/cdc_rndis_host.h b/src/class/cdc/cdc_rndis_host.h index 170cb3b0e..447cc4e97 100644 --- a/src/class/cdc/cdc_rndis_host.h +++ b/src/class/cdc/cdc_rndis_host.h @@ -50,7 +50,7 @@ typedef struct { }rndish_data_t; void rndish_init(void); -tusb_error_t rndish_open_subtask(uint8_t dev_addr, cdch_data_t *p_cdc); +bool rndish_open_subtask(uint8_t dev_addr, cdch_data_t *p_cdc); void rndish_xfer_isr(cdch_data_t *p_cdc, pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_bytes); void rndish_close(uint8_t dev_addr); diff --git a/src/class/vendor/vendor_host.h b/src/class/vendor/vendor_host.h index 07fa56c61..65223fbca 100644 --- a/src/class/vendor/vendor_host.h +++ b/src/class/vendor/vendor_host.h @@ -49,16 +49,16 @@ static inline bool tusbh_custom_is_mounted(uint8_t dev_addr, uint16_t vendor_id, return false; } -tusb_error_t tusbh_custom_read(uint8_t dev_addr, uint16_t vendor_id, uint16_t product_id, void * p_buffer, uint16_t length); -tusb_error_t tusbh_custom_write(uint8_t dev_addr, uint16_t vendor_id, uint16_t product_id, void const * p_data, uint16_t length); +bool tusbh_custom_read(uint8_t dev_addr, uint16_t vendor_id, uint16_t product_id, void * p_buffer, uint16_t length); +bool tusbh_custom_write(uint8_t dev_addr, uint16_t vendor_id, uint16_t product_id, void const * p_data, uint16_t length); //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ -void cush_init(void); -tusb_error_t cush_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length); -void cush_isr(pipe_handle_t pipe_hdl, xfer_result_t event); -void cush_close(uint8_t dev_addr); +void cush_init(void); +bool cush_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length); +void cush_isr(pipe_handle_t pipe_hdl, xfer_result_t event); +void cush_close(uint8_t dev_addr); #ifdef __cplusplus } diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 26865805e..34f3bb8f7 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -71,8 +71,8 @@ #include "tusb_compiler.h" #include "tusb_verify.h" #include "tusb_types.h" +#include "tusb_debug.h" -#include "tusb_error.h" // TODO remove #include "tusb_timeout.h" // TODO remove //--------------------------------------------------------------------+ @@ -268,138 +268,6 @@ TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write16 (void* mem, ui + TU_BIN8(dlsb)) #endif -//--------------------------------------------------------------------+ -// Debug Function -//--------------------------------------------------------------------+ - -// CFG_TUSB_DEBUG for debugging -// 0 : no debug -// 1 : print error -// 2 : print warning -// 3 : print info -#if CFG_TUSB_DEBUG - -void tu_print_mem(void const *buf, uint32_t count, uint8_t indent); - -#ifdef CFG_TUSB_DEBUG_PRINTF - extern int CFG_TUSB_DEBUG_PRINTF(const char *format, ...); - #define tu_printf CFG_TUSB_DEBUG_PRINTF -#else - #define tu_printf printf -#endif - -static inline -void tu_print_var(uint8_t const* buf, uint32_t bufsize) -{ - for(uint32_t i=0; i= 2 - #define TU_LOG2 TU_LOG1 - #define TU_LOG2_MEM TU_LOG1_MEM - #define TU_LOG2_VAR TU_LOG1_VAR - #define TU_LOG2_INT TU_LOG1_INT - #define TU_LOG2_HEX TU_LOG1_HEX -#endif - -// Log Level 3: Info -#if CFG_TUSB_DEBUG >= 3 - #define TU_LOG3 TU_LOG1 - #define TU_LOG3_MEM TU_LOG1_MEM - #define TU_LOG3_VAR TU_LOG1_VAR - #define TU_LOG3_INT TU_LOG1_INT - #define TU_LOG3_HEX TU_LOG1_HEX -#endif - -typedef struct -{ - uint32_t key; - const char* data; -} tu_lookup_entry_t; - -typedef struct -{ - uint16_t count; - tu_lookup_entry_t const* items; -} tu_lookup_table_t; - -static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint32_t key) -{ - static char not_found[11]; - - for(uint16_t i=0; icount; i++) - { - if (p_table->items[i].key == key) return p_table->items[i].data; - } - - // not found return the key value in hex - snprintf(not_found, sizeof(not_found), "0x%08lX", (unsigned long) key); - - return not_found; -} - -#endif // CFG_TUSB_DEBUG - -#ifndef TU_LOG -#define TU_LOG(n, ...) -#define TU_LOG_MEM(n, ...) -#define TU_LOG_VAR(n, ...) -#define TU_LOG_INT(n, ...) -#define TU_LOG_HEX(n, ...) -#define TU_LOG_LOCATION() -#define TU_LOG_FAILED() -#endif - -// TODO replace all TU_LOGn with TU_LOG(n) - -#define TU_LOG0(...) -#define TU_LOG0_MEM(...) -#define TU_LOG0_VAR(...) -#define TU_LOG0_INT(...) -#define TU_LOG0_HEX(...) - - -#ifndef TU_LOG1 - #define TU_LOG1(...) - #define TU_LOG1_MEM(...) - #define TU_LOG1_VAR(...) - #define TU_LOG1_INT(...) - #define TU_LOG1_HEX(...) -#endif - -#ifndef TU_LOG2 - #define TU_LOG2(...) - #define TU_LOG2_MEM(...) - #define TU_LOG2_VAR(...) - #define TU_LOG2_INT(...) - #define TU_LOG2_HEX(...) -#endif - -#ifndef TU_LOG3 - #define TU_LOG3(...) - #define TU_LOG3_MEM(...) - #define TU_LOG3_VAR(...) - #define TU_LOG3_INT(...) - #define TU_LOG3_HEX(...) -#endif - #ifdef __cplusplus } #endif diff --git a/src/common/tusb_debug.h b/src/common/tusb_debug.h new file mode 100644 index 000000000..647e8a8db --- /dev/null +++ b/src/common/tusb_debug.h @@ -0,0 +1,174 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2022, 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_DEBUG_H_ +#define _TUSB_DEBUG_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Debug +//--------------------------------------------------------------------+ + +// CFG_TUSB_DEBUG for debugging +// 0 : no debug +// 1 : print error +// 2 : print warning +// 3 : print info +#if CFG_TUSB_DEBUG + +// Enum to String for debugging purposes +#if CFG_TUSB_DEBUG >= 2 +extern char const* const tu_str_speed[]; +extern char const* const tu_str_std_request[]; +#endif + +void tu_print_mem(void const *buf, uint32_t count, uint8_t indent); + +#ifdef CFG_TUSB_DEBUG_PRINTF + extern int CFG_TUSB_DEBUG_PRINTF(const char *format, ...); + #define tu_printf CFG_TUSB_DEBUG_PRINTF +#else + #define tu_printf printf +#endif + +static inline void tu_print_var(uint8_t const* buf, uint32_t bufsize) +{ + for(uint32_t i=0; i= 2 + #define TU_LOG2 TU_LOG1 + #define TU_LOG2_MEM TU_LOG1_MEM + #define TU_LOG2_VAR TU_LOG1_VAR + #define TU_LOG2_INT TU_LOG1_INT + #define TU_LOG2_HEX TU_LOG1_HEX +#endif + +// Log Level 3: Info +#if CFG_TUSB_DEBUG >= 3 + #define TU_LOG3 TU_LOG1 + #define TU_LOG3_MEM TU_LOG1_MEM + #define TU_LOG3_VAR TU_LOG1_VAR + #define TU_LOG3_INT TU_LOG1_INT + #define TU_LOG3_HEX TU_LOG1_HEX +#endif + +typedef struct +{ + uint32_t key; + const char* data; +} tu_lookup_entry_t; + +typedef struct +{ + uint16_t count; + tu_lookup_entry_t const* items; +} tu_lookup_table_t; + +static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint32_t key) +{ + static char not_found[11]; + + for(uint16_t i=0; icount; i++) + { + if (p_table->items[i].key == key) return p_table->items[i].data; + } + + // not found return the key value in hex + snprintf(not_found, sizeof(not_found), "0x%08lX", (unsigned long) key); + + return not_found; +} + +#endif // CFG_TUSB_DEBUG + +#ifndef TU_LOG + #define TU_LOG(n, ...) + #define TU_LOG_MEM(n, ...) + #define TU_LOG_VAR(n, ...) + #define TU_LOG_INT(n, ...) + #define TU_LOG_HEX(n, ...) + #define TU_LOG_LOCATION() + #define TU_LOG_FAILED() +#endif + +// TODO replace all TU_LOGn with TU_LOG(n) + +#define TU_LOG0(...) +#define TU_LOG0_MEM(...) +#define TU_LOG0_VAR(...) +#define TU_LOG0_INT(...) +#define TU_LOG0_HEX(...) + +#ifndef TU_LOG1 + #define TU_LOG1(...) + #define TU_LOG1_MEM(...) + #define TU_LOG1_VAR(...) + #define TU_LOG1_INT(...) + #define TU_LOG1_HEX(...) +#endif + +#ifndef TU_LOG2 + #define TU_LOG2(...) + #define TU_LOG2_MEM(...) + #define TU_LOG2_VAR(...) + #define TU_LOG2_INT(...) + #define TU_LOG2_HEX(...) +#endif + +#ifndef TU_LOG3 + #define TU_LOG3(...) + #define TU_LOG3_MEM(...) + #define TU_LOG3_VAR(...) + #define TU_LOG3_INT(...) + #define TU_LOG3_HEX(...) +#endif + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_DEBUG_H_ */ diff --git a/src/common/tusb_error.h b/src/common/tusb_error.h deleted file mode 100644 index 42541acd6..000000000 --- a/src/common/tusb_error.h +++ /dev/null @@ -1,77 +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. - * - * This file is part of the TinyUSB stack. - */ - -/** \ingroup Group_Common - * \defgroup Group_Error Error Codes - * @{ */ - -#ifndef _TUSB_ERRORS_H_ -#define _TUSB_ERRORS_H_ - -#include "tusb_option.h" - -#ifdef __cplusplus - extern "C" { -#endif - -#define ERROR_ENUM(x) x, -#define ERROR_STRING(x) #x, - -#define ERROR_TABLE(ENTRY) \ - ENTRY(TUSB_ERROR_NONE )\ - ENTRY(TUSB_ERROR_INVALID_PARA )\ - ENTRY(TUSB_ERROR_DEVICE_NOT_READY )\ - ENTRY(TUSB_ERROR_INTERFACE_IS_BUSY )\ - ENTRY(TUSB_ERROR_HCD_OPEN_PIPE_FAILED )\ - ENTRY(TUSB_ERROR_OSAL_TIMEOUT )\ - ENTRY(TUSB_ERROR_CDCH_DEVICE_NOT_MOUNTED )\ - ENTRY(TUSB_ERROR_MSCH_DEVICE_NOT_MOUNTED )\ - ENTRY(TUSB_ERROR_NOT_SUPPORTED )\ - ENTRY(TUSB_ERROR_NOT_ENOUGH_MEMORY )\ - ENTRY(TUSB_ERROR_FAILED )\ - -/// \brief Error Code returned -/// TODO obsolete and to be remove -typedef enum -{ - ERROR_TABLE(ERROR_ENUM) - TUSB_ERROR_COUNT -}tusb_error_t; - -#if CFG_TUSB_DEBUG -/// Enum to String for debugging purposes. Only available if \ref CFG_TUSB_DEBUG > 0 -extern char const* const tusb_strerr[TUSB_ERROR_COUNT]; -extern char const* const tusb_speed_str[]; - -#endif - -#ifdef __cplusplus - } -#endif - -#endif /* _TUSB_ERRORS_H_ */ - -/** @} */ diff --git a/src/common/tusb_verify.h b/src/common/tusb_verify.h index 8fef11dc7..f4a08ce2f 100644 --- a/src/common/tusb_verify.h +++ b/src/common/tusb_verify.h @@ -74,10 +74,8 @@ #if CFG_TUSB_DEBUG #include - #define _MESS_ERR(_err) tu_printf("%s %d: failed, error = %s\r\n", __func__, __LINE__, tusb_strerr[_err]) #define _MESS_FAILED() tu_printf("%s %d: ASSERT FAILED\r\n", __func__, __LINE__) #else - #define _MESS_ERR(_err) do {} while (0) #define _MESS_FAILED() do {} while (0) #endif @@ -144,32 +142,6 @@ #define TU_ASSERT(...) GET_3RD_ARG(__VA_ARGS__, ASSERT_2ARGS, ASSERT_1ARGS,UNUSED)(__VA_ARGS__) #endif -// TODO remove TU_ASSERT_ERR() later - -/*------------- Generator for TU_VERIFY_ERR and TU_VERIFY_ERR_HDLR -------------*/ -#define TU_VERIFY_ERR_DEF2(_error, _handler) do \ -{ \ - uint32_t _err = (uint32_t)(_error); \ - if ( 0 != _err ) { _MESS_ERR(_err); _handler; return _err; } \ -} while(0) - -#define TU_VERIFY_ERR_DEF3(_error, _handler, _ret) do \ -{ \ - uint32_t _err = (uint32_t)(_error); \ - if ( 0 != _err ) { _MESS_ERR(_err); _handler; return _ret; } \ -} while(0) - -/*------------------------------------------------------------------*/ -/* ASSERT Error - * basically TU_VERIFY Error with TU_BREAKPOINT() as handler - *------------------------------------------------------------------*/ -#define ASSERT_ERR_1ARGS(_error) TU_VERIFY_ERR_DEF2(_error, TU_BREAKPOINT()) -#define ASSERT_ERR_2ARGS(_error, _ret) TU_VERIFY_ERR_DEF3(_error, TU_BREAKPOINT(), _ret) - -#ifndef TU_ASSERT_ERR -#define TU_ASSERT_ERR(...) GET_3RD_ARG(__VA_ARGS__, ASSERT_ERR_2ARGS, ASSERT_ERR_1ARGS,UNUSED)(__VA_ARGS__) -#endif - /*------------------------------------------------------------------*/ /* ASSERT HDLR *------------------------------------------------------------------*/ diff --git a/src/device/usbd.c b/src/device/usbd.c index b14b5e0fc..fc66f83c6 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -315,23 +315,6 @@ static char const* const _usbd_event_str[DCD_EVENT_COUNT] = "Func Call" }; -static char const* const _tusb_std_request_str[] = -{ - "Get Status" , - "Clear Feature" , - "Reserved" , - "Set Feature" , - "Reserved" , - "Set Address" , - "Get Descriptor" , - "Set Descriptor" , - "Get Configuration" , - "Set Configuration" , - "Get Interface" , - "Set Interface" , - "Synch Frame" -}; - // for usbd_control to print the name of control complete driver void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback) { @@ -508,7 +491,7 @@ void tud_task (void) switch ( event.event_id ) { case DCD_EVENT_BUS_RESET: - TU_LOG2(": %s Speed\r\n", tusb_speed_str[event.bus_reset.speed]); + TU_LOG2(": %s Speed\r\n", tu_str_speed[event.bus_reset.speed]); usbd_reset(event.rhport); _usbd_dev.speed = event.bus_reset.speed; break; @@ -650,7 +633,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const #if CFG_TUSB_DEBUG >= 2 if (TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type && p_request->bRequest <= TUSB_REQ_SYNCH_FRAME) { - TU_LOG2(" %s", _tusb_std_request_str[p_request->bRequest]); + TU_LOG2(" %s", tu_str_std_request[p_request->bRequest]); if (TUSB_REQ_GET_DESCRIPTOR != p_request->bRequest) TU_LOG2("\r\n"); } #endif diff --git a/src/host/usbh.c b/src/host/usbh.c index 59fcb4da3..5d167408a 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -259,6 +259,7 @@ static void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t h static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size); // from usbh_control.c +extern bool usbh_control_xfer (uint8_t dev_addr, tusb_control_request_t const* request, void* buffer, tuh_control_complete_cb_t complete_cb); extern bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); //--------------------------------------------------------------------+ @@ -297,6 +298,16 @@ void osal_task_delay(uint32_t msec) } #endif + +bool tuh_control_xfer (uint8_t dev_addr, tusb_control_request_t const* request, void* buffer, tuh_control_complete_cb_t complete_cb) +{ + TU_LOG2("[%u:%u] %s: ", usbh_get_rhport(dev_addr), dev_addr, request->bRequest <= TUSB_REQ_SYNCH_FRAME ? tu_str_std_request[request->bRequest] : "Unknown Request"); + TU_LOG2_VAR(request); + TU_LOG2("\r\n"); + + return usbh_control_xfer(dev_addr, request, buffer, complete_cb); +} + //--------------------------------------------------------------------+ // Descriptors //--------------------------------------------------------------------+ @@ -864,7 +875,7 @@ static bool enum_new_device(hcd_event_t* event) if ( !hcd_port_connect_status(_dev0.rhport) ) return true; _dev0.speed = hcd_port_speed_get(_dev0.rhport ); - TU_LOG2("%s Speed\r\n", tusb_speed_str[_dev0.speed]); + TU_LOG2("%s Speed\r\n", tu_str_speed[_dev0.speed]); enum_request_addr0_device_desc(); } diff --git a/src/host/usbh_control.c b/src/host/usbh_control.c index d034eec7f..5f4fcf52f 100644 --- a/src/host/usbh_control.c +++ b/src/host/usbh_control.c @@ -33,6 +33,7 @@ enum { + STAGE_IDLE, STAGE_SETUP, STAGE_DATA, STAGE_ACK @@ -56,7 +57,7 @@ static usbh_control_xfer_t _ctrl_xfer; // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ -bool tuh_control_xfer (uint8_t dev_addr, tusb_control_request_t const* request, void* buffer, tuh_control_complete_cb_t complete_cb) +bool usbh_control_xfer (uint8_t dev_addr, tusb_control_request_t const* request, void* buffer, tuh_control_complete_cb_t complete_cb) { // TODO need to claim the endpoint first const uint8_t rhport = usbh_get_rhport(dev_addr); @@ -66,10 +67,6 @@ bool tuh_control_xfer (uint8_t dev_addr, tusb_control_request_t const* request, _ctrl_xfer.stage = STAGE_SETUP; _ctrl_xfer.complete_cb = complete_cb; - TU_LOG2("Control Setup (addr = %u): ", dev_addr); - TU_LOG2_VAR(request); - TU_LOG2("\r\n"); - // Send setup packet TU_ASSERT( hcd_setup_send(rhport, dev_addr, (uint8_t const*) &_ctrl_xfer.request) ); diff --git a/src/tusb.c b/src/tusb.c index a30221059..c6c04262c 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -161,9 +161,27 @@ uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf, #if CFG_TUSB_DEBUG #include -char const* const tusb_strerr[TUSB_ERROR_COUNT] = { ERROR_TABLE(ERROR_STRING) }; +#if CFG_TUSB_DEBUG >= 2 -char const* const tusb_speed_str[] = { "Full", "Low", "High" }; +char const* const tu_str_speed[] = { "Full", "Low", "High" }; +char const* const tu_str_std_request[] = +{ + "Get Status" , + "Clear Feature" , + "Reserved" , + "Set Feature" , + "Reserved" , + "Set Address" , + "Get Descriptor" , + "Set Descriptor" , + "Get Configuration" , + "Set Configuration" , + "Get Interface" , + "Set Interface" , + "Synch Frame" +}; + +#endif static void dump_str_line(uint8_t const* buf, uint16_t count) { From a5fb20533cc1c9e0ed155083c1bbcb3e7be75e67 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 9 Mar 2022 17:17:27 +0700 Subject: [PATCH 216/504] adding tusb_private.h to implement common edpt claim --- src/common/tusb_common.h | 13 --------- src/common/tusb_private.h | 61 +++++++++++++++++++++++++++++++++++++++ src/device/usbd.c | 4 +++ src/host/usbh.c | 41 +++++++++----------------- src/tusb.c | 25 ++++++++++++++++ src/tusb.h | 4 --- 6 files changed, 104 insertions(+), 44 deletions(-) create mode 100644 src/common/tusb_private.h diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 34f3bb8f7..58591f0be 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -75,19 +75,6 @@ #include "tusb_timeout.h" // TODO remove -//--------------------------------------------------------------------+ -// Internal Helper used by Host and Device Stack -//--------------------------------------------------------------------+ - -// Check if endpoint descriptor is valid per USB specs -bool tu_edpt_validate(tusb_desc_endpoint_t const * desc_ep, tusb_speed_t speed); - -// Bind all endpoint of a interface descriptor to class driver -void tu_edpt_bind_driver(uint8_t ep2drv[][2], tusb_desc_interface_t const* p_desc, uint16_t desc_len, uint8_t driver_id); - -// Calculate total length of n interfaces (depending on IAD) -uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_t itf_count, uint16_t max_len); - //--------------------------------------------------------------------+ // Internal Inline Functions //--------------------------------------------------------------------+ diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h new file mode 100644 index 000000000..5315c352f --- /dev/null +++ b/src/common/tusb_private.h @@ -0,0 +1,61 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2022, 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_PRIVATE_H_ +#define _TUSB_PRIVATE_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct TU_ATTR_PACKED +{ + volatile uint8_t busy : 1; + volatile uint8_t stalled : 1; + volatile uint8_t claimed : 1; +}tu_edpt_state_t; + +//--------------------------------------------------------------------+ +// Internal Helper used by Host and Device Stack +//--------------------------------------------------------------------+ + +// Check if endpoint descriptor is valid per USB specs +bool tu_edpt_validate(tusb_desc_endpoint_t const * desc_ep, tusb_speed_t speed); + +// Bind all endpoint of a interface descriptor to class driver +void tu_edpt_bind_driver(uint8_t ep2drv[][2], tusb_desc_interface_t const* p_desc, uint16_t desc_len, uint8_t driver_id); + +// Calculate total length of n interfaces (depending on IAD) +uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_t itf_count, uint16_t max_len); + +bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex); + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_PRIVATE_H_ */ diff --git a/src/device/usbd.c b/src/device/usbd.c index fc66f83c6..4b37e8bd9 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -29,6 +29,8 @@ #if CFG_TUD_ENABLED #include "tusb.h" +#include "common/tusb_private.h" + #include "device/usbd.h" #include "device/usbd_pvt.h" #include "device/dcd.h" @@ -70,6 +72,8 @@ typedef struct uint8_t itf2drv[16]; // map interface number to driver (0xff is invalid) uint8_t ep2drv[CFG_TUD_ENDPPOINT_MAX][2]; // map endpoint to driver ( 0xff is invalid ) + // TODO 4-bit should be sufficient for ep2drv if we want to save half its bytes + struct TU_ATTR_PACKED { volatile bool busy : 1; diff --git a/src/host/usbh.c b/src/host/usbh.c index 5d167408a..319031f5b 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -29,6 +29,8 @@ #if CFG_TUH_ENABLED #include "tusb.h" +#include "common/tusb_private.h" + #include "host/usbh.h" #include "host/usbh_classdriver.h" #include "hub.h" @@ -104,14 +106,7 @@ typedef struct { uint8_t itf2drv[CFG_TUH_INTERFACE_MAX]; // map interface number to driver (0xff is invalid) uint8_t ep2drv[CFG_TUH_ENDPOINT_MAX][2]; // map endpoint to driver ( 0xff is invalid ) - struct TU_ATTR_PACKED - { - volatile bool busy : 1; - volatile bool stalled : 1; - volatile bool claimed : 1; - - // TODO merge ep2drv here, 4-bit should be sufficient - }ep_status[CFG_TUH_ENDPOINT_MAX][2]; + tu_edpt_state_t ep_status[CFG_TUH_ENDPOINT_MAX][2]; } usbh_device_t; @@ -1189,25 +1184,19 @@ static bool parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configura // TODO has some duplication code with device, refactor later bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr) { - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + // addr0 is always available + if (dev_addr == 0) return true; - usbh_device_t* dev = get_device(dev_addr); + usbh_device_t* dev = get_device(dev_addr); + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + tu_edpt_state_t* ep_state = &dev->ep_status[epnum][dir]; - // pre-check to help reducing mutex lock - TU_VERIFY((dev->ep_status[epnum][dir].busy == 0) && (dev->ep_status[epnum][dir].claimed == 0)); - lock_device(dev_addr); - - // can only claim the endpoint if it is not busy and not claimed yet. - bool const ret = (dev->ep_status[epnum][dir].busy == 0) && (dev->ep_status[epnum][dir].claimed == 0); - if (ret) - { - dev->ep_status[epnum][dir].claimed = 1; - } - - unlock_device(dev_addr); - - return ret; +#if TUSB_OPT_MUTEX + return tu_edpt_claim(ep_state, &_usbh_mutex[dev_addr-1]); +#else + return tu_edpt_claim(ep_state, NULL); +#endif } // TODO has some duplication code with device, refactor later @@ -1299,6 +1288,4 @@ bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) return dev->ep_status[epnum][dir].busy; } - - #endif diff --git a/src/tusb.c b/src/tusb.c index c6c04262c..6ed2a3c05 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -29,6 +29,7 @@ #if CFG_TUH_ENABLED || CFG_TUD_ENABLED #include "tusb.h" +#include "common/tusb_private.h" // TODO clean up #if CFG_TUD_ENABLED @@ -67,6 +68,30 @@ bool tusb_inited(void) // Internal Helper for both Host and Device stack //--------------------------------------------------------------------+ +bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex) +{ + (void) mutex; + +#if TUSB_OPT_MUTEX + // pre-check to help reducing mutex lock + TU_VERIFY((ep_state->busy == 0) && (ep_state->claimed == 0)); + osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER); +#endif + + // can only claim the endpoint if it is not busy and not claimed yet. + bool const available = (ep_state->busy == 0) && (ep_state->claimed == 0); + if (available) + { + ep_state->claimed = 1; + } + +#if TUSB_OPT_MUTEX + osal_mutex_unlock(mutex); +#endif + + return available; +} + bool tu_edpt_validate(tusb_desc_endpoint_t const * desc_ep, tusb_speed_t speed) { uint16_t const max_packet_size = tu_edpt_packet_size(desc_ep); diff --git a/src/tusb.h b/src/tusb.h index 549f00b43..222855fcb 100644 --- a/src/tusb.h +++ b/src/tusb.h @@ -117,8 +117,6 @@ //--------------------------------------------------------------------+ // APPLICATION API //--------------------------------------------------------------------+ -/** \ingroup group_application_api - * @{ */ // Initialize device/host stack // Note: when using with RTOS, this should be called after scheduler/kernel is started. @@ -131,8 +129,6 @@ bool tusb_inited(void); // TODO // bool tusb_teardown(void); -/** @} */ - #ifdef __cplusplus } #endif From 110879074f3785c07bf3f125e26a2bbaa51897e4 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 9 Mar 2022 17:26:55 +0700 Subject: [PATCH 217/504] implement tu_edpt_release() --- src/common/tusb_private.h | 4 ++++ src/host/usbh.c | 26 +++++++++++--------------- src/tusb.c | 22 ++++++++++++++++++++++ 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index 5315c352f..b34506f65 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -52,8 +52,12 @@ void tu_edpt_bind_driver(uint8_t ep2drv[][2], tusb_desc_interface_t const* p_des // Calculate total length of n interfaces (depending on IAD) uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_t itf_count, uint16_t max_len); +// Claim an endpoint with provided mutex bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex); +// Release an endpoint with provided mutex +bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex); + #ifdef __cplusplus } #endif diff --git a/src/host/usbh.c b/src/host/usbh.c index 319031f5b..8206c06a4 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -1202,23 +1202,19 @@ bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr) // TODO has some duplication code with device, refactor later bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr) { - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + // addr0 is always available + if (dev_addr == 0) return true; - usbh_device_t* dev = get_device(dev_addr); + usbh_device_t* dev = get_device(dev_addr); + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + tu_edpt_state_t* ep_state = &dev->ep_status[epnum][dir]; - lock_device(dev_addr); - - // can only release the endpoint if it is claimed and not busy - bool const ret = (dev->ep_status[epnum][dir].busy == 0) && (dev->ep_status[epnum][dir].claimed == 1); - if (ret) - { - dev->ep_status[epnum][dir].claimed = 0; - } - - unlock_device(dev_addr); - - return ret; +#if TUSB_OPT_MUTEX + return tu_edpt_release(ep_state, &_usbh_mutex[dev_addr-1]); +#else + return tu_edpt_release(ep_state, NULL); +#endif } // TODO has some duplication code with device, refactor later diff --git a/src/tusb.c b/src/tusb.c index 6ed2a3c05..c86bdd891 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -92,6 +92,28 @@ bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex) return available; } +bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex) +{ + (void) mutex; + +#if TUSB_OPT_MUTEX + osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER); +#endif + + // can only release the endpoint if it is claimed and not busy + bool const ret = (ep_state->claimed == 1) && (ep_state->busy == 0); + if (ret) + { + ep_state->claimed = 0; + } + +#if TUSB_OPT_MUTEX + osal_mutex_unlock(mutex); +#endif + + return ret; +} + bool tu_edpt_validate(tusb_desc_endpoint_t const * desc_ep, tusb_speed_t speed) { uint16_t const max_packet_size = tu_edpt_packet_size(desc_ep); From d56cde33ef66985b5d3cb087f87cf8bc1a2b111d Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 9 Mar 2022 17:34:12 +0700 Subject: [PATCH 218/504] refactor usbd to also use common endpoint claim/release --- src/device/usbd.c | 65 +++++++++++++---------------------------------- src/host/usbh.c | 7 ++--- 2 files changed, 21 insertions(+), 51 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 4b37e8bd9..7ab2660f4 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -69,19 +69,10 @@ typedef struct volatile uint8_t cfg_num; // current active configuration (0x00 is not configured) uint8_t speed; - uint8_t itf2drv[16]; // map interface number to driver (0xff is invalid) - uint8_t ep2drv[CFG_TUD_ENDPPOINT_MAX][2]; // map endpoint to driver ( 0xff is invalid ) + uint8_t itf2drv[16]; // map interface number to driver (0xff is invalid) + uint8_t ep2drv[CFG_TUD_ENDPPOINT_MAX][2]; // map endpoint to driver ( 0xff is invalid ), can use only 4-bit each - // TODO 4-bit should be sufficient for ep2drv if we want to save half its bytes - - struct TU_ATTR_PACKED - { - volatile bool busy : 1; - volatile bool stalled : 1; - volatile bool claimed : 1; - - // TODO merge ep2drv here, 4-bit should be sufficient - }ep_status[CFG_TUD_ENDPPOINT_MAX][2]; + tu_edpt_state_t ep_status[CFG_TUD_ENDPPOINT_MAX][2]; }usbd_device_t; @@ -1229,52 +1220,30 @@ bool usbd_edpt_claim(uint8_t rhport, uint8_t ep_addr) // TODO add this check later, also make sure we don't starve an out endpoint while suspending // TU_VERIFY(tud_ready()); - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + tu_edpt_state_t* ep_state = &_usbd_dev.ep_status[epnum][dir]; -#if CFG_TUSB_OS != OPT_OS_NONE - // pre-check to help reducing mutex lock - TU_VERIFY((_usbd_dev.ep_status[epnum][dir].busy == 0) && (_usbd_dev.ep_status[epnum][dir].claimed == 0)); - osal_mutex_lock(_usbd_mutex, OSAL_TIMEOUT_WAIT_FOREVER); +#if TUSB_OPT_MUTEX + return tu_edpt_claim(ep_state, _usbd_mutex); +#else + return tu_edpt_claim(ep_state, NULL); #endif - - // can only claim the endpoint if it is not busy and not claimed yet. - bool const ret = (_usbd_dev.ep_status[epnum][dir].busy == 0) && (_usbd_dev.ep_status[epnum][dir].claimed == 0); - if (ret) - { - _usbd_dev.ep_status[epnum][dir].claimed = 1; - } - -#if CFG_TUSB_OS != OPT_OS_NONE - osal_mutex_unlock(_usbd_mutex); -#endif - - return ret; } bool usbd_edpt_release(uint8_t rhport, uint8_t ep_addr) { (void) rhport; - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + tu_edpt_state_t* ep_state = &_usbd_dev.ep_status[epnum][dir]; -#if CFG_TUSB_OS != OPT_OS_NONE - osal_mutex_lock(_usbd_mutex, OSAL_TIMEOUT_WAIT_FOREVER); +#if TUSB_OPT_MUTEX + return tu_edpt_release(ep_state, _usbd_mutex); +#else + return tu_edpt_release(ep_state, NULL); #endif - - // can only release the endpoint if it is claimed and not busy - bool const ret = (_usbd_dev.ep_status[epnum][dir].busy == 0) && (_usbd_dev.ep_status[epnum][dir].claimed == 1); - if (ret) - { - _usbd_dev.ep_status[epnum][dir].claimed = 0; - } - -#if CFG_TUSB_OS != OPT_OS_NONE - osal_mutex_unlock(_usbd_mutex); -#endif - - return ret; } bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) diff --git a/src/host/usbh.c b/src/host/usbh.c index 8206c06a4..69ec081fd 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -104,9 +104,10 @@ typedef struct { volatile uint8_t state; // device state, value from enum tusbh_device_state_t uint8_t itf2drv[CFG_TUH_INTERFACE_MAX]; // map interface number to driver (0xff is invalid) - uint8_t ep2drv[CFG_TUH_ENDPOINT_MAX][2]; // map endpoint to driver ( 0xff is invalid ) + uint8_t ep2drv[CFG_TUH_ENDPOINT_MAX][2]; // map endpoint to driver ( 0xff is invalid ), can use only 4-bit each tu_edpt_state_t ep_status[CFG_TUH_ENDPOINT_MAX][2]; + } usbh_device_t; @@ -1193,7 +1194,7 @@ bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr) tu_edpt_state_t* ep_state = &dev->ep_status[epnum][dir]; #if TUSB_OPT_MUTEX - return tu_edpt_claim(ep_state, &_usbh_mutex[dev_addr-1]); + return tu_edpt_claim(ep_state, _usbh_mutex[dev_addr-1]); #else return tu_edpt_claim(ep_state, NULL); #endif @@ -1211,7 +1212,7 @@ bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr) tu_edpt_state_t* ep_state = &dev->ep_status[epnum][dir]; #if TUSB_OPT_MUTEX - return tu_edpt_release(ep_state, &_usbh_mutex[dev_addr-1]); + return tu_edpt_release(ep_state, _usbh_mutex[dev_addr-1]); #else return tu_edpt_release(ep_state, NULL); #endif From 0e5e644d27a722f7a95fcd5f049770094fb02cd6 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 9 Mar 2022 17:51:35 +0700 Subject: [PATCH 219/504] minor clean up --- src/host/usbh.c | 2 +- src/host/usbh_control.c | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index 69ec081fd..808ef1299 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -561,7 +561,7 @@ void tuh_task(void) else { usbh_device_t* dev = get_device(event.dev_addr); - dev->ep_status[epnum][ep_dir].busy = false; + dev->ep_status[epnum][ep_dir].busy = 0; dev->ep_status[epnum][ep_dir].claimed = 0; if ( 0 == epnum ) diff --git a/src/host/usbh_control.c b/src/host/usbh_control.c index 5f4fcf52f..f311cc257 100644 --- a/src/host/usbh_control.c +++ b/src/host/usbh_control.c @@ -50,9 +50,6 @@ typedef struct static usbh_control_xfer_t _ctrl_xfer; -//CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN -//static uint8_t _tuh_ctrl_buf[CFG_TUH_ENUMERATION_BUFSIZE]; - //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ @@ -76,6 +73,7 @@ bool usbh_control_xfer (uint8_t dev_addr, tusb_control_request_t const* request, static void _xfer_complete(uint8_t dev_addr, xfer_result_t result) { TU_LOG2("\r\n"); + _ctrl_xfer.stage = STAGE_IDLE; if (_ctrl_xfer.complete_cb) _ctrl_xfer.complete_cb(dev_addr, &_ctrl_xfer.request, result); } @@ -90,7 +88,7 @@ bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t resu if (XFER_RESULT_SUCCESS != result) { - TU_LOG2("Control failed: result = %d\r\n", result); + TU_LOG2("[%u:%u] Control %s\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED"); // terminate transfer if any stage failed _xfer_complete(dev_addr, result); @@ -113,7 +111,7 @@ bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t resu if (request->wLength) { - TU_LOG2("Control data (addr = %u):\r\n", dev_addr); + TU_LOG2("[%u:%u] Control data:\r\n", rhport, dev_addr); TU_LOG2_MEM(_ctrl_xfer.buffer, request->wLength, 2); } From 97636eff8e855c1f901477ca7914c0eca5024432 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 10 Mar 2022 00:36:49 +0700 Subject: [PATCH 220/504] more clean up --- src/host/usbh.c | 251 ++++++++++++++++++++++-------------------------- 1 file changed, 115 insertions(+), 136 deletions(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index 808ef1299..aec97cf2a 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -65,10 +65,10 @@ typedef struct struct TU_ATTR_PACKED { - volatile uint8_t connected : 1; - volatile uint8_t addressed : 1; - volatile uint8_t configured : 1; - volatile uint8_t suspended : 1; + volatile uint8_t connected : 1; + volatile uint8_t addressed : 1; + volatile uint8_t configured : 1; + volatile uint8_t suspended : 1; }; } usbh_dev0_t; @@ -81,10 +81,10 @@ typedef struct { struct TU_ATTR_PACKED { - volatile uint8_t connected : 1; - volatile uint8_t addressed : 1; - volatile uint8_t configured : 1; - volatile uint8_t suspended : 1; + volatile uint8_t connected : 1; + volatile uint8_t addressed : 1; + volatile uint8_t configured : 1; + volatile uint8_t suspended : 1; }; //------------- device descriptor -------------// @@ -208,29 +208,8 @@ CFG_TUSB_MEM_SECTION usbh_device_t _usbh_devices[TOTAL_DEVICES]; // Mutex for claiming endpoint, only needed when using with preempted RTOS #if TUSB_OPT_MUTEX - static osal_mutex_def_t _usbh_mutexdef[TOTAL_DEVICES]; static osal_mutex_t _usbh_mutex[TOTAL_DEVICES]; - -static inline void lock_device(uint8_t daddr) -{ - // addr0 is always available - if (daddr) return; - osal_mutex_lock(&_usbh_mutex[daddr-1], OSAL_TIMEOUT_WAIT_FOREVER); -} - -static inline void unlock_device(uint8_t daddr) -{ - // addr0 is always available - if (daddr) return; - osal_mutex_unlock(&_usbh_mutex[daddr-1]); -} - -#else - -#define lock_device(_addr) -#define unlock_device(_addr) - #endif // Event queue @@ -769,6 +748,113 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) } } +//--------------------------------------------------------------------+ +// Endpoint API +//--------------------------------------------------------------------+ + +// TODO has some duplication code with device, refactor later +bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr) +{ + // addr0 is always available + if (dev_addr == 0) return true; + + usbh_device_t* dev = get_device(dev_addr); + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + tu_edpt_state_t* ep_state = &dev->ep_status[epnum][dir]; + +#if TUSB_OPT_MUTEX + return tu_edpt_claim(ep_state, _usbh_mutex[dev_addr-1]); +#else + return tu_edpt_claim(ep_state, NULL); +#endif +} + +// TODO has some duplication code with device, refactor later +bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr) +{ + // addr0 is always available + if (dev_addr == 0) return true; + + usbh_device_t* dev = get_device(dev_addr); + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + tu_edpt_state_t* ep_state = &dev->ep_status[epnum][dir]; + +#if TUSB_OPT_MUTEX + return tu_edpt_release(ep_state, _usbh_mutex[dev_addr-1]); +#else + return tu_edpt_release(ep_state, NULL); +#endif +} + +// TODO has some duplication code with device, refactor later +bool usbh_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + usbh_device_t* dev = get_device(dev_addr); + + TU_LOG2(" Queue EP %02X with %u bytes ... ", ep_addr, total_bytes); + + // Attempt to transfer on a busy endpoint, sound like an race condition ! + TU_ASSERT(dev->ep_status[epnum][dir].busy == 0); + + // Set busy first since the actual transfer can be complete before hcd_edpt_xfer() + // could return and USBH task can preempt and clear the busy + dev->ep_status[epnum][dir].busy = true; + + if ( hcd_edpt_xfer(dev->rhport, dev_addr, ep_addr, buffer, total_bytes) ) + { + TU_LOG2("OK\r\n"); + return true; + }else + { + // HCD error, mark endpoint as ready to allow next transfer + dev->ep_status[epnum][dir].busy = false; + dev->ep_status[epnum][dir].claimed = 0; + TU_LOG2("failed\r\n"); + TU_BREAKPOINT(); + return false; + } +} + +static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size) +{ + TU_LOG2("Open EP0 with Size = %u (addr = %u)\r\n", max_packet_size, dev_addr); + + tusb_desc_endpoint_t ep0_desc = + { + .bLength = sizeof(tusb_desc_endpoint_t), + .bDescriptorType = TUSB_DESC_ENDPOINT, + .bEndpointAddress = 0, + .bmAttributes = { .xfer = TUSB_XFER_CONTROL }, + .wMaxPacketSize = max_packet_size, + .bInterval = 0 + }; + + return hcd_edpt_open(usbh_get_rhport(dev_addr), dev_addr, &ep0_desc); +} + +bool usbh_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep) +{ + usbh_device_t* dev = get_device(dev_addr); + TU_ASSERT(tu_edpt_validate(desc_ep, (tusb_speed_t) dev->speed)); + + return hcd_edpt_open(rhport, dev_addr, desc_ep); +} + +bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + usbh_device_t* dev = get_device(dev_addr); + + return dev->ep_status[epnum][dir].busy; +} + //--------------------------------------------------------------------+ // Enumeration Process // is a lengthy process with a series of control transfer to configure @@ -1178,111 +1264,4 @@ static bool parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configura return true; } -//--------------------------------------------------------------------+ -// Endpoint API -//--------------------------------------------------------------------+ - -// TODO has some duplication code with device, refactor later -bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr) -{ - // addr0 is always available - if (dev_addr == 0) return true; - - usbh_device_t* dev = get_device(dev_addr); - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - tu_edpt_state_t* ep_state = &dev->ep_status[epnum][dir]; - -#if TUSB_OPT_MUTEX - return tu_edpt_claim(ep_state, _usbh_mutex[dev_addr-1]); -#else - return tu_edpt_claim(ep_state, NULL); -#endif -} - -// TODO has some duplication code with device, refactor later -bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr) -{ - // addr0 is always available - if (dev_addr == 0) return true; - - usbh_device_t* dev = get_device(dev_addr); - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - tu_edpt_state_t* ep_state = &dev->ep_status[epnum][dir]; - -#if TUSB_OPT_MUTEX - return tu_edpt_release(ep_state, _usbh_mutex[dev_addr-1]); -#else - return tu_edpt_release(ep_state, NULL); -#endif -} - -// TODO has some duplication code with device, refactor later -bool usbh_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) -{ - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - usbh_device_t* dev = get_device(dev_addr); - - TU_LOG2(" Queue EP %02X with %u bytes ... ", ep_addr, total_bytes); - - // Attempt to transfer on a busy endpoint, sound like an race condition ! - TU_ASSERT(dev->ep_status[epnum][dir].busy == 0); - - // Set busy first since the actual transfer can be complete before hcd_edpt_xfer() - // could return and USBH task can preempt and clear the busy - dev->ep_status[epnum][dir].busy = true; - - if ( hcd_edpt_xfer(dev->rhport, dev_addr, ep_addr, buffer, total_bytes) ) - { - TU_LOG2("OK\r\n"); - return true; - }else - { - // HCD error, mark endpoint as ready to allow next transfer - dev->ep_status[epnum][dir].busy = false; - dev->ep_status[epnum][dir].claimed = 0; - TU_LOG2("failed\r\n"); - TU_BREAKPOINT(); - return false; - } -} - -static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size) -{ - TU_LOG2("Open EP0 with Size = %u (addr = %u)\r\n", max_packet_size, dev_addr); - - tusb_desc_endpoint_t ep0_desc = - { - .bLength = sizeof(tusb_desc_endpoint_t), - .bDescriptorType = TUSB_DESC_ENDPOINT, - .bEndpointAddress = 0, - .bmAttributes = { .xfer = TUSB_XFER_CONTROL }, - .wMaxPacketSize = max_packet_size, - .bInterval = 0 - }; - - return hcd_edpt_open(usbh_get_rhport(dev_addr), dev_addr, &ep0_desc); -} - -bool usbh_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep) -{ - usbh_device_t* dev = get_device(dev_addr); - TU_ASSERT(tu_edpt_validate(desc_ep, (tusb_speed_t) dev->speed)); - - return hcd_edpt_open(rhport, dev_addr, desc_ep); -} - -bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) -{ - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - usbh_device_t* dev = get_device(dev_addr); - - return dev->ep_status[epnum][dir].busy; -} - #endif From 22f682c37879a38aa662c2205d411b2246d0639c Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 9 Mar 2022 15:22:31 -0800 Subject: [PATCH 221/504] Add host example that prints out info of connected devices --- examples/host/device_info/CMakeLists.txt | 27 +++ examples/host/device_info/Makefile | 28 ++++ examples/host/device_info/only.txt | 9 + examples/host/device_info/src/main.c | 175 ++++++++++++++++++++ examples/host/device_info/src/tusb_config.h | 96 +++++++++++ 5 files changed, 335 insertions(+) create mode 100644 examples/host/device_info/CMakeLists.txt create mode 100644 examples/host/device_info/Makefile create mode 100644 examples/host/device_info/only.txt create mode 100644 examples/host/device_info/src/main.c create mode 100644 examples/host/device_info/src/tusb_config.h diff --git a/examples/host/device_info/CMakeLists.txt b/examples/host/device_info/CMakeLists.txt new file mode 100644 index 000000000..bff281a8c --- /dev/null +++ b/examples/host/device_info/CMakeLists.txt @@ -0,0 +1,27 @@ +cmake_minimum_required(VERSION 3.5) + +include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) + +# gets PROJECT name for the example +family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR}) + +project(${PROJECT}) + +# Checks this example is valid for the family and initializes the project +family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}) + +add_executable(${PROJECT}) + +# Example source +target_sources(${PROJECT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c + ) + +# Example include +target_include_directories(${PROJECT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src + ) + +# Configure compilation flags and libraries for the example... see the corresponding function +# in hw/bsp/FAMILY/family.cmake for details. +family_configure_host_example(${PROJECT}) \ No newline at end of file diff --git a/examples/host/device_info/Makefile b/examples/host/device_info/Makefile new file mode 100644 index 000000000..c59369ffa --- /dev/null +++ b/examples/host/device_info/Makefile @@ -0,0 +1,28 @@ +include ../../../tools/top.mk +include ../../make.mk + +INC += \ + src \ + $(TOP)/hw \ + +# Example source +EXAMPLE_SOURCE += \ + src/main.c + +SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) + +# TODO: suppress warning caused by host stack +CFLAGS += -Wno-error=cast-align -Wno-error=null-dereference + +# TinyUSB Host Stack source +SRC_C += \ + src/class/cdc/cdc_host.c \ + src/class/hid/hid_host.c \ + src/class/msc/msc_host.c \ + src/host/hub.c \ + src/host/usbh.c \ + src/host/usbh_control.c \ + src/portable/ohci/ohci.c \ + src/portable/nxp/lpc17_40/hcd_lpc17_40.c + +include ../../rules.mk diff --git a/examples/host/device_info/only.txt b/examples/host/device_info/only.txt new file mode 100644 index 000000000..7fe4e3f5c --- /dev/null +++ b/examples/host/device_info/only.txt @@ -0,0 +1,9 @@ +mcu:LPC175X_6X +mcu:LPC177X_8X +mcu:LPC18XX +mcu:LPC40XX +mcu:LPC43XX +mcu:MIMXRT10XX +mcu:RP2040 +mcu:MSP432E4 +mcu:RX65X diff --git a/examples/host/device_info/src/main.c b/examples/host/device_info/src/main.c new file mode 100644 index 000000000..45b616af0 --- /dev/null +++ b/examples/host/device_info/src/main.c @@ -0,0 +1,175 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2022 Scott Shawcroft for Adafruit Industries + * + * 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 prints out info about the enumerated devices. */ + + +#include +#include +#include + +#include "bsp/board.h" +#include "tusb.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF PROTYPES +//--------------------------------------------------------------------+ +void led_blinking_task(void); + +static xfer_result_t _get_string_result; + +static bool _transfer_done_cb(uint8_t daddr, tusb_control_request_t const *request, xfer_result_t result) { + (void)daddr; + (void)request; + _get_string_result = result; + return true; +} + +static void _convert_utf16le_to_utf8(const uint16_t *utf16, size_t utf16_len, uint8_t *utf8, size_t utf8_len) { + // TODO: Check for runover. + (void)utf8_len; + // Get the UTF-16 length out of the data itself. + + for (size_t i = 0; i < utf16_len; i++) { + uint16_t chr = utf16[i]; + if (chr < 0x80) { + *utf8++ = chr & 0xff; + } else if (chr < 0x800) { + *utf8++ = (uint8_t)(0xC0 | (chr >> 6 & 0x1F)); + *utf8++ = (uint8_t)(0x80 | (chr >> 0 & 0x3F)); + } else { + // TODO: Verify surrogate. + *utf8++ = (uint8_t)(0xE0 | (chr >> 12 & 0x0F)); + *utf8++ = (uint8_t)(0x80 | (chr >> 6 & 0x3F)); + *utf8++ = (uint8_t)(0x80 | (chr >> 0 & 0x3F)); + } + // TODO: Handle UTF-16 code points that take two entries. + } +} + +// Count how many bytes a utf-16-le encoded string will take in utf-8. +static int _count_utf8_bytes(const uint16_t *buf, size_t len) { + size_t total_bytes = 0; + for (size_t i = 0; i < len; i++) { + uint16_t chr = buf[i]; + if (chr < 0x80) { + total_bytes += 1; + } else if (chr < 0x800) { + total_bytes += 2; + } else { + total_bytes += 3; + } + // TODO: Handle UTF-16 code points that take two entries. + } + return total_bytes; +} + +static void _wait_and_convert(uint16_t *temp_buf, size_t buf_len) { + while (_get_string_result == 0xff) { + tuh_task(); + } + size_t utf16_len = ((temp_buf[0] & 0xff) - 2) / sizeof(uint16_t); + size_t utf8_len = _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'; +} + +/*------------- MAIN -------------*/ +int main(void) +{ + board_init(); + + printf("TinyUSB Host Device Info Example\r\n"); + + tusb_init(); + + uint32_t interval_ms = 5000; + uint32_t start_time = 0; + + while (1) + { + // tinyusb host task + tuh_task(); + led_blinking_task(); + + if (board_millis() - start_time < interval_ms) { + continue; + } + start_time = board_millis(); + // Brute force check every device address to see if it is active. + for (int i = 1; i < CFG_TUH_DEVICE_MAX + CFG_TUH_HUB + 1; i++) { + if (!tuh_ready(i)) { + continue; + } + uint16_t vid; + uint16_t pid; + tuh_vid_pid_get(i, &vid, &pid); + printf("%d vid %04x pid %04x\r\n", i, vid, pid); + + _get_string_result = 0xff; + uint16_t temp_buf[127]; + if (tuh_descriptor_string_serial_get(i, 0, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb)) { + _wait_and_convert(temp_buf, TU_ARRAY_SIZE(temp_buf)); + printf("Serial: %s\r\n", (const char*) temp_buf); + } + + _get_string_result = 0xff; + temp_buf[0] = 0; + if (tuh_descriptor_string_product_get(i, 0, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb)) { + _wait_and_convert(temp_buf, TU_ARRAY_SIZE(temp_buf)); + printf("Product: %s\r\n", (const char*) temp_buf); + } + + _get_string_result = 0xff; + temp_buf[0] = 0; + if (tuh_descriptor_string_manufacturer_get(i, 0, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb)) { + _wait_and_convert(temp_buf, TU_ARRAY_SIZE(temp_buf)); + printf("Manufacturer: %s\r\n", (const char*) temp_buf); + } + } + printf("\n"); + } + + return 0; +} + + +//--------------------------------------------------------------------+ +// Blinking Task +//--------------------------------------------------------------------+ +void led_blinking_task(void) +{ + const uint32_t interval_ms = 1000; + static uint32_t start_ms = 0; + + static bool led_state = false; + + // Blink every interval ms + if ( board_millis() - start_ms < interval_ms) return; // not enough time + start_ms += interval_ms; + + board_led_write(led_state); + led_state = 1 - led_state; // toggle +} diff --git a/examples/host/device_info/src/tusb_config.h b/examples/host/device_info/src/tusb_config.h new file mode 100644 index 000000000..6b413e46f --- /dev/null +++ b/examples/host/device_info/src/tusb_config.h @@ -0,0 +1,96 @@ +/* + * 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 _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +//-------------------------------------------------------------------- +// COMMON CONFIGURATION +//-------------------------------------------------------------------- + +// defined by compiler flags for flexibility +#ifndef CFG_TUSB_MCU + #error CFG_TUSB_MCU must be defined +#endif + +#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | OPT_MODE_HIGH_SPEED) +#else + #define CFG_TUSB_RHPORT0_MODE OPT_MODE_HOST +#endif + +#ifndef CFG_TUSB_OS +#define CFG_TUSB_OS OPT_OS_NONE +#endif + +// CFG_TUSB_DEBUG is defined by compiler in DEBUG build +// #define CFG_TUSB_DEBUG 0 + +/* 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 + +//-------------------------------------------------------------------- +// CONFIGURATION +//-------------------------------------------------------------------- + +// Size of buffer to hold descriptors and other data used for enumeration +#define CFG_TUH_ENUMERATION_BUFSIZE 256 + +// only hub class is enabled +#define CFG_TUH_HUB 1 + +// max device support (excluding hub device) +// 1 hub typically has 4 ports +#define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB ? 4 : 1) + +#define CFG_TUH_ENDPOINT_MAX 8 + +#define CFG_TUH_TASK_QUEUE_SZ 64 + +//------------- HID -------------// + +#define CFG_TUH_HID_EP_BUFSIZE 64 + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_CONFIG_H_ */ From b05401a5ab788a9b1a56bdb79b74e49b6909339f Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 10 Mar 2022 11:59:51 +0700 Subject: [PATCH 222/504] merge control stage host and device value --- src/common/tusb_types.h | 1 + src/host/usbh_control.c | 22 +++++++--------------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index 5b26f5aec..f998eabfb 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -265,6 +265,7 @@ typedef enum enum { + CONTROL_STAGE_IDLE, CONTROL_STAGE_SETUP, CONTROL_STAGE_DATA, CONTROL_STAGE_ACK diff --git a/src/host/usbh_control.c b/src/host/usbh_control.c index f311cc257..741b0723a 100644 --- a/src/host/usbh_control.c +++ b/src/host/usbh_control.c @@ -31,14 +31,6 @@ #include "tusb.h" #include "usbh_classdriver.h" -enum -{ - STAGE_IDLE, - STAGE_SETUP, - STAGE_DATA, - STAGE_ACK -}; - typedef struct { tusb_control_request_t request TU_ATTR_ALIGNED(4); @@ -61,7 +53,7 @@ bool usbh_control_xfer (uint8_t dev_addr, tusb_control_request_t const* request, _ctrl_xfer.request = (*request); _ctrl_xfer.buffer = buffer; - _ctrl_xfer.stage = STAGE_SETUP; + _ctrl_xfer.stage = CONTROL_STAGE_SETUP; _ctrl_xfer.complete_cb = complete_cb; // Send setup packet @@ -73,7 +65,7 @@ bool usbh_control_xfer (uint8_t dev_addr, tusb_control_request_t const* request, static void _xfer_complete(uint8_t dev_addr, xfer_result_t result) { TU_LOG2("\r\n"); - _ctrl_xfer.stage = STAGE_IDLE; + _ctrl_xfer.stage = CONTROL_STAGE_IDLE; if (_ctrl_xfer.complete_cb) _ctrl_xfer.complete_cb(dev_addr, &_ctrl_xfer.request, result); } @@ -96,8 +88,8 @@ bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t resu { switch(_ctrl_xfer.stage) { - case STAGE_SETUP: - _ctrl_xfer.stage = STAGE_DATA; + case CONTROL_STAGE_SETUP: + _ctrl_xfer.stage = CONTROL_STAGE_DATA; if (request->wLength) { // DATA stage: initial data toggle is always 1 @@ -106,8 +98,8 @@ bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t resu } __attribute__((fallthrough)); - case STAGE_DATA: - _ctrl_xfer.stage = STAGE_ACK; + case CONTROL_STAGE_DATA: + _ctrl_xfer.stage = CONTROL_STAGE_ACK; if (request->wLength) { @@ -119,7 +111,7 @@ bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t resu hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, 1-request->bmRequestType_bit.direction), NULL, 0); break; - case STAGE_ACK: + case CONTROL_STAGE_ACK: _xfer_complete(dev_addr, result); break; From 5e9f522b9ad1c9c9b905101c364d0728d4895d5b Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 10 Mar 2022 12:56:15 +0700 Subject: [PATCH 223/504] refactor host control xfer --- src/host/usbh.c | 30 +++++++++++++++++++++--------- src/host/usbh_control.c | 16 ++++++---------- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index aec97cf2a..9a2bc86a8 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -55,6 +55,7 @@ //--------------------------------------------------------------------+ // device0 struct must be strictly a subset of normal device struct +// TODO refactor later typedef struct { // port @@ -70,6 +71,8 @@ typedef struct volatile uint8_t configured : 1; volatile uint8_t suspended : 1; }; + + uint8_t control_stage; // state of control transfer } usbh_dev0_t; typedef struct { @@ -87,12 +90,13 @@ typedef struct { volatile uint8_t suspended : 1; }; - //------------- device descriptor -------------// - uint8_t ep0_size; + uint8_t control_stage; // state of control transfer + //------------- device descriptor -------------// uint16_t vid; uint16_t pid; + uint8_t ep0_size; uint8_t i_manufacturer; uint8_t i_product; uint8_t i_serial; @@ -234,8 +238,8 @@ static void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t h static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size); // from usbh_control.c -extern bool usbh_control_xfer (uint8_t dev_addr, tusb_control_request_t const* request, void* buffer, tuh_control_complete_cb_t complete_cb); -extern bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); +extern bool usbh_control_xfer (uint8_t daddr, tusb_control_request_t const* request, void* buffer, tuh_control_complete_cb_t complete_cb); +extern uint8_t usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, uint8_t* stage, xfer_result_t result, uint32_t xferred_bytes); //--------------------------------------------------------------------+ // PUBLIC API (Parameter Verification is required) @@ -274,13 +278,21 @@ void osal_task_delay(uint32_t msec) #endif -bool tuh_control_xfer (uint8_t dev_addr, tusb_control_request_t const* request, void* buffer, tuh_control_complete_cb_t complete_cb) +bool tuh_control_xfer (uint8_t daddr, tusb_control_request_t const* request, void* buffer, tuh_control_complete_cb_t complete_cb) { - TU_LOG2("[%u:%u] %s: ", usbh_get_rhport(dev_addr), dev_addr, request->bRequest <= TUSB_REQ_SYNCH_FRAME ? tu_str_std_request[request->bRequest] : "Unknown Request"); + TU_LOG2("[%u:%u] %s: ", usbh_get_rhport(daddr), daddr, request->bRequest <= TUSB_REQ_SYNCH_FRAME ? tu_str_std_request[request->bRequest] : "Unknown Request"); TU_LOG2_VAR(request); TU_LOG2("\r\n"); - return usbh_control_xfer(dev_addr, request, buffer, complete_cb); + if (daddr) + { + get_device(daddr)->control_stage = CONTROL_STAGE_SETUP; + }else + { + _dev0.control_stage = CONTROL_STAGE_SETUP; + } + + return usbh_control_xfer(daddr, request, buffer, complete_cb); } //--------------------------------------------------------------------+ @@ -535,7 +547,7 @@ void tuh_task(void) { // device 0 only has control endpoint TU_ASSERT(epnum == 0, ); - usbh_control_xfer_cb(event.dev_addr, ep_addr, event.xfer_complete.result, event.xfer_complete.len); + usbh_control_xfer_cb(event.dev_addr, ep_addr, &_dev0.control_stage, event.xfer_complete.result, event.xfer_complete.len); } else { @@ -545,7 +557,7 @@ void tuh_task(void) if ( 0 == epnum ) { - usbh_control_xfer_cb(event.dev_addr, ep_addr, event.xfer_complete.result, event.xfer_complete.len); + usbh_control_xfer_cb(event.dev_addr, ep_addr, &dev->control_stage, event.xfer_complete.result, event.xfer_complete.len); }else { uint8_t drv_id = dev->ep2drv[epnum][ep_dir]; diff --git a/src/host/usbh_control.c b/src/host/usbh_control.c index 741b0723a..88287a47b 100644 --- a/src/host/usbh_control.c +++ b/src/host/usbh_control.c @@ -34,8 +34,6 @@ typedef struct { tusb_control_request_t request TU_ATTR_ALIGNED(4); - - uint8_t stage; uint8_t* buffer; tuh_control_complete_cb_t complete_cb; } usbh_control_xfer_t; @@ -53,7 +51,6 @@ bool usbh_control_xfer (uint8_t dev_addr, tusb_control_request_t const* request, _ctrl_xfer.request = (*request); _ctrl_xfer.buffer = buffer; - _ctrl_xfer.stage = CONTROL_STAGE_SETUP; _ctrl_xfer.complete_cb = complete_cb; // Send setup packet @@ -65,17 +62,15 @@ bool usbh_control_xfer (uint8_t dev_addr, tusb_control_request_t const* request, static void _xfer_complete(uint8_t dev_addr, xfer_result_t result) { TU_LOG2("\r\n"); - _ctrl_xfer.stage = CONTROL_STAGE_IDLE; if (_ctrl_xfer.complete_cb) _ctrl_xfer.complete_cb(dev_addr, &_ctrl_xfer.request, result); } -bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) +bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, uint8_t* stage, xfer_result_t result, uint32_t xferred_bytes) { (void) ep_addr; (void) xferred_bytes; const uint8_t rhport = usbh_get_rhport(dev_addr); - tusb_control_request_t const * request = &_ctrl_xfer.request; if (XFER_RESULT_SUCCESS != result) @@ -83,13 +78,14 @@ bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t resu TU_LOG2("[%u:%u] Control %s\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED"); // terminate transfer if any stage failed + *stage = CONTROL_STAGE_IDLE; _xfer_complete(dev_addr, result); }else { - switch(_ctrl_xfer.stage) + switch(*stage) { case CONTROL_STAGE_SETUP: - _ctrl_xfer.stage = CONTROL_STAGE_DATA; + *stage = CONTROL_STAGE_DATA; if (request->wLength) { // DATA stage: initial data toggle is always 1 @@ -99,8 +95,7 @@ bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t resu __attribute__((fallthrough)); case CONTROL_STAGE_DATA: - _ctrl_xfer.stage = CONTROL_STAGE_ACK; - + *stage = CONTROL_STAGE_ACK; if (request->wLength) { TU_LOG2("[%u:%u] Control data:\r\n", rhport, dev_addr); @@ -112,6 +107,7 @@ bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t resu break; case CONTROL_STAGE_ACK: + *stage = CONTROL_STAGE_IDLE; _xfer_complete(dev_addr, result); break; From b9ca301527040458bd369cf967732a76d5139222 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 10 Mar 2022 13:19:15 +0700 Subject: [PATCH 224/504] remove obsolete device state --- src/common/tusb_types.h | 8 -------- src/host/hcd.h | 3 ++- src/host/usbh.c | 36 ++++++++++++++++-------------------- 3 files changed, 18 insertions(+), 29 deletions(-) diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index f998eabfb..da164145b 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -223,14 +223,6 @@ enum { #define TUSB_DESC_CONFIG_POWER_MA(x) ((x)/2) -/// Device State TODO remove -typedef enum -{ - TUSB_DEVICE_STATE_UNPLUG = 0 , - TUSB_DEVICE_STATE_CONFIGURED , - TUSB_DEVICE_STATE_SUSPENDED , -}tusb_device_state_t; - typedef enum { XFER_RESULT_SUCCESS, diff --git a/src/host/hcd.h b/src/host/hcd.h index 9819f5f2a..c40bea64c 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -94,7 +94,8 @@ typedef struct } hcd_event_t; -typedef struct { +typedef struct +{ uint8_t rhport; uint8_t hub_addr; uint8_t hub_port; diff --git a/src/host/usbh.c b/src/host/usbh.c index 9a2bc86a8..07baeee96 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -82,6 +82,7 @@ typedef struct { uint8_t hub_port; uint8_t speed; + // Device State struct TU_ATTR_PACKED { volatile uint8_t connected : 1; @@ -92,7 +93,7 @@ typedef struct { uint8_t control_stage; // state of control transfer - //------------- device descriptor -------------// + // Device Descriptor uint16_t vid; uint16_t pid; @@ -101,12 +102,10 @@ typedef struct { uint8_t i_product; uint8_t i_serial; - //------------- configuration descriptor -------------// + // Configuration Descriptor // uint8_t interface_count; // bNumInterfaces alias - //------------- device -------------// - volatile uint8_t state; // device state, value from enum tusbh_device_state_t - + // Endpoint & Interface uint8_t itf2drv[CFG_TUH_INTERFACE_MAX]; // map interface number to driver (0xff is invalid) uint8_t ep2drv[CFG_TUH_ENDPOINT_MAX][2]; // map endpoint to driver ( 0xff is invalid ), can use only 4-bit each @@ -685,9 +684,8 @@ void hcd_event_device_remove(uint8_t hostid, bool in_isr) } -// a device unplugged on hostid, hub_addr, hub_port -// return true if found and unmounted device, false if cannot find -void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port) +// a device unplugged from rhport:hub_addr:hub_port +static void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port) { //------------- find the all devices (star-network) under port that is unplugged -------------// // TODO mark as disconnected in ISR, also handle dev0 @@ -700,7 +698,7 @@ void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port if (dev->rhport == rhport && (hub_addr == 0 || dev->hub_addr == hub_addr) && // hub_addr == 0 & hub_port == 0 means roothub (hub_port == 0 || dev->hub_port == hub_port) && - dev->state != TUSB_DEVICE_STATE_UNPLUG) + dev->connected) { // Invoke callback before close driver if (tuh_umount_cb) tuh_umount_cb(dev_addr); @@ -729,7 +727,7 @@ static uint8_t get_new_address(bool is_hub) for (uint8_t i=0; i < count; i++) { uint8_t const addr = start + i; - if (get_device(addr)->state == TUSB_DEVICE_STATE_UNPLUG) return addr; + if (!get_device(addr)->connected) return addr; } return ADDR_INVALID; } @@ -951,17 +949,17 @@ static bool enum_hub_get_status0_complete(uint8_t dev_addr, tusb_control_request return true; } -#endif +#endif // hub static bool enum_new_device(hcd_event_t* event) { - _dev0.rhport = event->rhport; // TODO refractor integrate to device_pool + _dev0.rhport = event->rhport; _dev0.hub_addr = event->connection.hub_addr; _dev0.hub_port = event->connection.hub_port; - //------------- connected/disconnected directly with roothub -------------// if (_dev0.hub_addr == 0) { + // connected/disconnected directly with roothub // wait until device is stable TODO non blocking osal_task_delay(RESET_DELAY); @@ -974,14 +972,14 @@ static bool enum_new_device(hcd_event_t* event) enum_request_addr0_device_desc(); } #if CFG_TUH_HUB - //------------- connected/disconnected via hub -------------// else { + // connected/disconnected via external hub // wait until device is stable osal_task_delay(RESET_DELAY); TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, enum_hub_get_status0_complete) ); } -#endif // CFG_TUH_HUB +#endif // hub return true; } @@ -994,7 +992,6 @@ static bool enum_request_addr0_device_desc(void) // Get first 8 bytes of device descriptor for Control Endpoint size TU_LOG2("Get 8 byte of Device Descriptor\r\n"); - TU_ASSERT(tuh_descriptor_get_device(addr0, _usbh_ctrl_buf, 8, enum_get_addr0_device_desc_complete)); return true; } @@ -1024,7 +1021,7 @@ static bool enum_get_addr0_device_desc_complete(uint8_t dev_addr, tusb_control_r if (_dev0.hub_addr == 0) { // connected directly to roothub - hcd_port_reset( _dev0.rhport ); // reset port after 8 byte descriptor + hcd_port_reset( _dev0.rhport ); osal_task_delay(RESET_DELAY); enum_request_set_addr(); @@ -1040,14 +1037,13 @@ static bool enum_get_addr0_device_desc_complete(uint8_t dev_addr, tusb_control_r TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, enum_hub_get_status1_complete) ); } -#endif +#endif // hub return true; } static bool enum_request_set_addr(void) { - uint8_t const addr0 = 0; tusb_desc_device_t const * desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; // Get new address @@ -1079,6 +1075,7 @@ static bool enum_request_set_addr(void) .wLength = 0 }; + uint8_t const addr0 = 0; TU_ASSERT( tuh_control_xfer(addr0, &new_request, NULL, enum_set_address_complete) ); return true; @@ -1172,7 +1169,6 @@ static bool enum_set_config_complete(uint8_t dev_addr, tusb_control_request_t co TU_LOG2("Device configured\r\n"); usbh_device_t* dev = get_device(dev_addr); dev->configured = 1; - dev->state = TUSB_DEVICE_STATE_CONFIGURED; // Start the Set Configuration process for interfaces (itf = DRVID_INVALID) // Since driver can perform control transfer within its set_config, this is done asynchronously. From 171d021ab56960f8d7e222faa263168ead0f9d6a Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 10 Mar 2022 22:22:05 +0700 Subject: [PATCH 225/504] refactor and integrate usbh control xfer back to usbh.c fix enumeration with hub when reset port before set address --- src/device/usbd_pvt.h | 2 +- src/host/usbh.c | 447 +++++++++++++++++++++++------------- src/host/usbh_classdriver.h | 1 + src/host/usbh_control.c | 82 ++----- src/osal/osal_none.h | 2 +- 5 files changed, 317 insertions(+), 217 deletions(-) diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index dae95cebb..29753451e 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -80,7 +80,7 @@ bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16 // If caller does not make any transfer, it must release endpoint for others. bool usbd_edpt_claim(uint8_t rhport, uint8_t ep_addr); -// Release an endpoint without submitting a transfer +// Release claimed endpoint without submitting a transfer bool usbd_edpt_release(uint8_t rhport, uint8_t ep_addr); // Check if endpoint is busy transferring diff --git a/src/host/usbh.c b/src/host/usbh.c index 07baeee96..3d9db70fa 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -72,7 +72,6 @@ typedef struct volatile uint8_t suspended : 1; }; - uint8_t control_stage; // state of control transfer } usbh_dev0_t; typedef struct { @@ -91,13 +90,12 @@ typedef struct { volatile uint8_t suspended : 1; }; - uint8_t control_stage; // state of control transfer - // Device Descriptor + uint8_t ep0_size; + uint16_t vid; uint16_t pid; - uint8_t ep0_size; uint8_t i_manufacturer; uint8_t i_product; uint8_t i_serial; @@ -113,6 +111,14 @@ typedef struct { } usbh_device_t; +typedef struct +{ + tusb_control_request_t request TU_ATTR_ALIGNED(4); + uint8_t* buffer; + tuh_control_complete_cb_t complete_cb; + + uint8_t daddr; +} usbh_control_xfer_t; //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF @@ -211,8 +217,24 @@ CFG_TUSB_MEM_SECTION usbh_device_t _usbh_devices[TOTAL_DEVICES]; // Mutex for claiming endpoint, only needed when using with preempted RTOS #if TUSB_OPT_MUTEX -static osal_mutex_def_t _usbh_mutexdef[TOTAL_DEVICES]; -static osal_mutex_t _usbh_mutex[TOTAL_DEVICES]; +static osal_mutex_def_t _usbh_mutexdef; +static osal_mutex_t _usbh_mutex; + +TU_ATTR_ALWAYS_INLINE static inline void usbh_lock(void) +{ + osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER); +} + +TU_ATTR_ALWAYS_INLINE static inline void usbh_unlock(void) +{ + osal_mutex_unlock(_usbh_mutex); +} + +#else + +#define usbh_lock() +#define usbh_unlock() + #endif // Event queue @@ -223,6 +245,15 @@ static osal_queue_t _usbh_q; CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t _usbh_ctrl_buf[CFG_TUH_ENUMERATION_BUFSIZE]; +// Control transfer: since most controller does not support multiple control transfer +// on multiple devices concurrently. And control transfer is not used much except enumeration +// We will only execute control transfer one at a time. +struct +{ + usbh_control_xfer_t xfer; + uint8_t stage; +}_ctrl_xfer; + //------------- Helper Function -------------// TU_ATTR_ALWAYS_INLINE @@ -235,10 +266,7 @@ static inline usbh_device_t* get_device(uint8_t dev_addr) static bool enum_new_device(hcd_event_t* event); static void process_device_unplugged(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); - -// from usbh_control.c -extern bool usbh_control_xfer (uint8_t daddr, tusb_control_request_t const* request, void* buffer, tuh_control_complete_cb_t complete_cb); -extern uint8_t usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, uint8_t* stage, xfer_result_t result, uint32_t xferred_bytes); +static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); //--------------------------------------------------------------------+ // PUBLIC API (Parameter Verification is required) @@ -276,24 +304,6 @@ void osal_task_delay(uint32_t msec) } #endif - -bool tuh_control_xfer (uint8_t daddr, tusb_control_request_t const* request, void* buffer, tuh_control_complete_cb_t complete_cb) -{ - TU_LOG2("[%u:%u] %s: ", usbh_get_rhport(daddr), daddr, request->bRequest <= TUSB_REQ_SYNCH_FRAME ? tu_str_std_request[request->bRequest] : "Unknown Request"); - TU_LOG2_VAR(request); - TU_LOG2("\r\n"); - - if (daddr) - { - get_device(daddr)->control_stage = CONTROL_STAGE_SETUP; - }else - { - _dev0.control_stage = CONTROL_STAGE_SETUP; - } - - return usbh_control_xfer(daddr, request, buffer, complete_cb); -} - //--------------------------------------------------------------------+ // Descriptors //--------------------------------------------------------------------+ @@ -449,26 +459,30 @@ bool tuh_init(uint8_t rhport) TU_LOG2("USBH init\r\n"); TU_LOG2_INT(sizeof(usbh_device_t)); + TU_LOG2_INT(sizeof(hcd_event_t)); + TU_LOG2_INT(sizeof(usbh_control_xfer_t)); - //------------- Enumeration & Reporter Task init -------------// + // Event queue _usbh_q = osal_queue_create( &_usbh_qdef ); TU_ASSERT(_usbh_q != NULL); - //------------- Semaphore, Mutex for Control Pipe -------------// +#if TUSB_OPT_MUTEX + // Mutex + _usbh_mutex = osal_mutex_create(&_usbh_mutexdef); + TU_ASSERT(_usbh_mutex); +#endif + + // Device tu_memclr(&_dev0, sizeof(_dev0)); tu_memclr(_usbh_devices, sizeof(_usbh_devices)); + tu_memclr(&_ctrl_xfer, sizeof(_ctrl_xfer)); for(uint8_t i=0; icontrol_stage, event.xfer_complete.result, event.xfer_complete.len); + usbh_control_xfer_cb(event.dev_addr, ep_addr, event.xfer_complete.result, event.xfer_complete.len); }else { uint8_t drv_id = dev->ep2drv[epnum][ep_dir]; @@ -683,81 +697,6 @@ void hcd_event_device_remove(uint8_t hostid, bool in_isr) hcd_event_handler(&event, in_isr); } - -// a device unplugged from rhport:hub_addr:hub_port -static void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port) -{ - //------------- find the all devices (star-network) under port that is unplugged -------------// - // TODO mark as disconnected in ISR, also handle dev0 - for ( uint8_t dev_id = 0; dev_id < TU_ARRAY_SIZE(_usbh_devices); dev_id++ ) - { - usbh_device_t* dev = &_usbh_devices[dev_id]; - uint8_t const dev_addr = dev_id+1; - - // TODO Hub multiple level - if (dev->rhport == rhport && - (hub_addr == 0 || dev->hub_addr == hub_addr) && // hub_addr == 0 & hub_port == 0 means roothub - (hub_port == 0 || dev->hub_port == hub_port) && - dev->connected) - { - // Invoke callback before close driver - if (tuh_umount_cb) tuh_umount_cb(dev_addr); - - // Close class driver - for (uint8_t drv_id = 0; drv_id < USBH_CLASS_DRIVER_COUNT; drv_id++) - { - TU_LOG2("%s close\r\n", usbh_class_drivers[drv_id].name); - usbh_class_drivers[drv_id].close(dev_addr); - } - - hcd_device_close(rhport, dev_addr); - clear_device(dev); - } - } -} - -//--------------------------------------------------------------------+ -// INTERNAL HELPER -//--------------------------------------------------------------------+ -static uint8_t get_new_address(bool is_hub) -{ - uint8_t const start = (is_hub ? CFG_TUH_DEVICE_MAX : 0) + 1; - uint8_t const count = (is_hub ? CFG_TUH_HUB : CFG_TUH_DEVICE_MAX); - - for (uint8_t i=0; i < count; i++) - { - uint8_t const addr = start + i; - if (!get_device(addr)->connected) return addr; - } - return ADDR_INVALID; -} - -void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) -{ - usbh_device_t* dev = get_device(dev_addr); - - for(itf_num++; itf_num < CFG_TUH_INTERFACE_MAX; itf_num++) - { - // continue with next valid interface - // TODO skip IAD binding interface such as CDCs - uint8_t const drv_id = dev->itf2drv[itf_num]; - if (drv_id != DRVID_INVALID) - { - usbh_class_driver_t const * driver = &usbh_class_drivers[drv_id]; - TU_LOG2("%s set config: itf = %u\r\n", driver->name, itf_num); - driver->set_config(dev_addr, itf_num); - break; - } - } - - // all interface are configured - if (itf_num == CFG_TUH_INTERFACE_MAX) - { - // Invoke callback if available - if (tuh_mount_cb) tuh_mount_cb(dev_addr); - } -} - //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ @@ -774,7 +713,7 @@ bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr) tu_edpt_state_t* ep_state = &dev->ep_status[epnum][dir]; #if TUSB_OPT_MUTEX - return tu_edpt_claim(ep_state, _usbh_mutex[dev_addr-1]); + return tu_edpt_claim(ep_state, _usbh_mutex); #else return tu_edpt_claim(ep_state, NULL); #endif @@ -792,7 +731,7 @@ bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr) tu_edpt_state_t* ep_state = &dev->ep_status[epnum][dir]; #if TUSB_OPT_MUTEX - return tu_edpt_release(ep_state, _usbh_mutex[dev_addr-1]); + return tu_edpt_release(ep_state, _usbh_mutex); #else return tu_edpt_release(ep_state, NULL); #endif @@ -865,6 +804,183 @@ bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) return dev->ep_status[epnum][dir].busy; } +//--------------------------------------------------------------------+ +// Control transfer +//--------------------------------------------------------------------+ + +bool tuh_control_xfer (uint8_t daddr, tusb_control_request_t const* request, void* buffer, tuh_control_complete_cb_t complete_cb) +{ + // pre-check to help reducing mutex lock + TU_VERIFY(_ctrl_xfer.stage == CONTROL_STAGE_IDLE); + + usbh_lock(); + + bool const is_idle = (_ctrl_xfer.stage == CONTROL_STAGE_IDLE); + if (is_idle) _ctrl_xfer.stage = CONTROL_STAGE_SETUP; + + usbh_unlock(); + + TU_VERIFY(is_idle); + + const uint8_t rhport = usbh_get_rhport(daddr); + + TU_LOG2("[%u:%u] %s: ", rhport, daddr, request->bRequest <= TUSB_REQ_SYNCH_FRAME ? tu_str_std_request[request->bRequest] : "Unknown Request"); + TU_LOG2_VAR(request); + TU_LOG2("\r\n"); + + _ctrl_xfer.xfer.request = (*request); + _ctrl_xfer.xfer.buffer = buffer; + _ctrl_xfer.xfer.complete_cb = complete_cb; + _ctrl_xfer.xfer.daddr = daddr; + + return hcd_setup_send(rhport, daddr, (uint8_t const*) &_ctrl_xfer.xfer.request); +} + +TU_ATTR_ALWAYS_INLINE static inline void set_control_xfer_stage(uint8_t stage) +{ + usbh_lock(); + _ctrl_xfer.stage = stage; + usbh_unlock(); +} + +static void _xfer_complete(uint8_t dev_addr, xfer_result_t result) +{ + TU_LOG2("\r\n"); + + usbh_lock(); + _ctrl_xfer.stage = CONTROL_STAGE_IDLE; + usbh_unlock(); + + if (_ctrl_xfer.xfer.complete_cb) _ctrl_xfer.xfer.complete_cb(dev_addr, &_ctrl_xfer.xfer.request, result); +} + +static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) +{ + (void) ep_addr; + (void) xferred_bytes; + + const uint8_t rhport = usbh_get_rhport(dev_addr); + tusb_control_request_t const * request = &_ctrl_xfer.xfer.request; + + if (XFER_RESULT_SUCCESS != result) + { + TU_LOG2("[%u:%u] Control %s\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED"); + + // terminate transfer if any stage failed + _xfer_complete(dev_addr, result); + }else + { + switch(_ctrl_xfer.stage) + { + case CONTROL_STAGE_SETUP: + if (request->wLength) + { + // DATA stage: initial data toggle is always 1 + set_control_xfer_stage(CONTROL_STAGE_DATA); + return hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.xfer.buffer, request->wLength); + } + __attribute__((fallthrough)); + + case CONTROL_STAGE_DATA: + if (request->wLength) + { + TU_LOG2("[%u:%u] Control data:\r\n", rhport, dev_addr); + TU_LOG2_MEM(_ctrl_xfer.xfer.buffer, request->wLength, 2); + } + + // ACK stage: toggle is always 1 + set_control_xfer_stage(CONTROL_STAGE_ACK); + hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, 1-request->bmRequestType_bit.direction), NULL, 0); + break; + + case CONTROL_STAGE_ACK: + _xfer_complete(dev_addr, result); + break; + + default: return false; + } + } + + return true; +} + +// a device unplugged from rhport:hub_addr:hub_port +static void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port) +{ + //------------- find the all devices (star-network) under port that is unplugged -------------// + // TODO mark as disconnected in ISR, also handle dev0 + for ( uint8_t dev_id = 0; dev_id < TU_ARRAY_SIZE(_usbh_devices); dev_id++ ) + { + usbh_device_t* dev = &_usbh_devices[dev_id]; + uint8_t const dev_addr = dev_id+1; + + // TODO Hub multiple level + if (dev->rhport == rhport && + (hub_addr == 0 || dev->hub_addr == hub_addr) && // hub_addr == 0 & hub_port == 0 means roothub + (hub_port == 0 || dev->hub_port == hub_port) && + dev->connected) + { + // Invoke callback before close driver + if (tuh_umount_cb) tuh_umount_cb(dev_addr); + + // Close class driver + for (uint8_t drv_id = 0; drv_id < USBH_CLASS_DRIVER_COUNT; drv_id++) + { + TU_LOG2("%s close\r\n", usbh_class_drivers[drv_id].name); + usbh_class_drivers[drv_id].close(dev_addr); + } + + hcd_device_close(rhport, dev_addr); + clear_device(dev); + // abort on-going control xfer if any + if (_ctrl_xfer.xfer.daddr == dev_addr) set_control_xfer_stage(CONTROL_STAGE_IDLE); + } + } +} + +//--------------------------------------------------------------------+ +// INTERNAL HELPER +//--------------------------------------------------------------------+ + +static uint8_t get_new_address(bool is_hub) +{ + uint8_t const start = (is_hub ? CFG_TUH_DEVICE_MAX : 0) + 1; + uint8_t const count = (is_hub ? CFG_TUH_HUB : CFG_TUH_DEVICE_MAX); + + for (uint8_t i=0; i < count; i++) + { + uint8_t const addr = start + i; + if (!get_device(addr)->connected) return addr; + } + return ADDR_INVALID; +} + +void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) +{ + usbh_device_t* dev = get_device(dev_addr); + + for(itf_num++; itf_num < CFG_TUH_INTERFACE_MAX; itf_num++) + { + // continue with next valid interface + // TODO skip IAD binding interface such as CDCs + uint8_t const drv_id = dev->itf2drv[itf_num]; + if (drv_id != DRVID_INVALID) + { + usbh_class_driver_t const * driver = &usbh_class_drivers[drv_id]; + TU_LOG2("%s set config: itf = %u\r\n", driver->name, itf_num); + driver->set_config(dev_addr, itf_num); + break; + } + } + + // all interface are configured + if (itf_num == CFG_TUH_INTERFACE_MAX) + { + // Invoke callback if available + if (tuh_mount_cb) tuh_mount_cb(dev_addr); + } +} + //--------------------------------------------------------------------+ // Enumeration Process // is a lengthy process with a series of control transfer to configure @@ -886,43 +1002,16 @@ static bool enum_set_config_complete (uint8_t dev_addr, tusb_control_ static bool parse_configuration_descriptor (uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg); #if CFG_TUH_HUB -static bool enum_hub_clear_reset0_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) -{ - (void) dev_addr; (void) request; - TU_ASSERT(XFER_RESULT_SUCCESS == result); - enum_request_addr0_device_desc(); - return true; -} -static bool enum_hub_clear_reset1_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) -{ - (void) dev_addr; (void) request; - TU_ASSERT(XFER_RESULT_SUCCESS == result); +// Enum sequence: +// New device (reset on the way) -> Get Status 0 -> Clear Reset 0 -> Get 8byte Device Descriptor +// -> Port Reset 1 -> reset delay -> Get Status 1 -> Clear Reset 1 -> queue hub interrupt endpoint - enum_request_set_addr(); - - // done with hub, waiting for next data on status pipe - (void) hub_status_pipe_queue( _dev0.hub_addr ); - - return true; -} - -static bool enum_hub_get_status1_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) -{ - (void) dev_addr; (void) request; - TU_ASSERT(XFER_RESULT_SUCCESS == result); - - hub_port_status_response_t port_status; - memcpy(&port_status, _usbh_ctrl_buf, sizeof(hub_port_status_response_t)); - - // Acknowledge Port Reset Change if Reset Successful - if (port_status.change.reset) - { - TU_ASSERT( hub_port_clear_feature(_dev0.hub_addr, _dev0.hub_port, HUB_FEATURE_PORT_RESET_CHANGE, enum_hub_clear_reset1_complete) ); - } - - return true; -} +static bool enum_hub_get_status0_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +static bool enum_hub_clear_reset0_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +static bool enum_hub_set_reset1_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +static bool enum_hub_get_status1_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +static bool enum_hub_clear_reset1_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); static bool enum_hub_get_status0_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) { @@ -949,6 +1038,57 @@ static bool enum_hub_get_status0_complete(uint8_t dev_addr, tusb_control_request return true; } + +static bool enum_hub_clear_reset0_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +{ + (void) dev_addr; (void) request; + TU_ASSERT(XFER_RESULT_SUCCESS == result); + enum_request_addr0_device_desc(); + return true; +} + +static bool enum_hub_set_reset1_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +{ + (void) dev_addr; (void) request; + TU_ASSERT(XFER_RESULT_SUCCESS == result); + + osal_task_delay(RESET_DELAY); + + TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, enum_hub_get_status1_complete) ); + + return true; +} + +static bool enum_hub_get_status1_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +{ + (void) dev_addr; (void) request; + TU_ASSERT(XFER_RESULT_SUCCESS == result); + + hub_port_status_response_t port_status; + memcpy(&port_status, _usbh_ctrl_buf, sizeof(hub_port_status_response_t)); + + // Acknowledge Port Reset Change if Reset Successful + if (port_status.change.reset) + { + TU_ASSERT( hub_port_clear_feature(_dev0.hub_addr, _dev0.hub_port, HUB_FEATURE_PORT_RESET_CHANGE, enum_hub_clear_reset1_complete) ); + } + + return true; +} + +static bool enum_hub_clear_reset1_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +{ + (void) dev_addr; (void) request; + TU_ASSERT(XFER_RESULT_SUCCESS == result); + + enum_request_set_addr(); + + // done with hub, waiting for next data on status pipe + (void) hub_status_pipe_queue( _dev0.hub_addr ); + + return true; +} + #endif // hub static bool enum_new_device(hcd_event_t* event) @@ -1030,12 +1170,7 @@ static bool enum_get_addr0_device_desc_complete(uint8_t dev_addr, tusb_control_r else { // after RESET_DELAY the hub_port_reset() already complete - TU_ASSERT( hub_port_reset(_dev0.hub_addr, _dev0.hub_port, NULL) ); - osal_task_delay(RESET_DELAY); - - tuh_task(); // FIXME temporarily to clean up port_reset control transfer - - TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, enum_hub_get_status1_complete) ); + TU_ASSERT( hub_port_reset(_dev0.hub_addr, _dev0.hub_port, enum_hub_set_reset1_complete) ); } #endif // hub diff --git a/src/host/usbh_classdriver.h b/src/host/usbh_classdriver.h index 2f9957cc6..0435eae70 100644 --- a/src/host/usbh_classdriver.h +++ b/src/host/usbh_classdriver.h @@ -73,6 +73,7 @@ bool usbh_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_ // If caller does not make any transfer, it must release endpoint for others. bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr); +// Release claimed endpoint without submitting a transfer bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr); // Check if endpoint transferring is complete diff --git a/src/host/usbh_control.c b/src/host/usbh_control.c index 88287a47b..38f03a8d2 100644 --- a/src/host/usbh_control.c +++ b/src/host/usbh_control.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if CFG_TUH_ENABLED +#if CFG_TUH_ENABLED && 0 #include "tusb.h" #include "usbh_classdriver.h" @@ -36,86 +36,50 @@ typedef struct tusb_control_request_t request TU_ATTR_ALIGNED(4); uint8_t* buffer; tuh_control_complete_cb_t complete_cb; + + uint8_t daddr; } usbh_control_xfer_t; -static usbh_control_xfer_t _ctrl_xfer; +static usbh_control_xfer_t _xfer; +static uint8_t _stage = CONTROL_STAGE_IDLE; //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ +uint8_t usbh_control_xfer_stage(void) +{ + return _stage; +} + bool usbh_control_xfer (uint8_t dev_addr, tusb_control_request_t const* request, void* buffer, tuh_control_complete_cb_t complete_cb) { // TODO need to claim the endpoint first const uint8_t rhport = usbh_get_rhport(dev_addr); - _ctrl_xfer.request = (*request); - _ctrl_xfer.buffer = buffer; - _ctrl_xfer.complete_cb = complete_cb; + _ctrl_xfer.xfer.daddr = dev_addr; + _ctrl_xfer.xfer.request = (*request); + _ctrl_xfer.xfer.buffer = buffer; + _ctrl_xfer.xfer.complete_cb = complete_cb; + + _stage = CONTROL_STAGE_SETUP; // Send setup packet - TU_ASSERT( hcd_setup_send(rhport, dev_addr, (uint8_t const*) &_ctrl_xfer.request) ); + TU_ASSERT( hcd_setup_send(rhport, dev_addr, (uint8_t const*) &_ctrl_xfer.xfer.request) ); return true; } +void usbh_control_xfer_abort(uint8_t dev_addr) +{ + if (_ctrl_xfer.xfer.daddr == dev_addr) _stage = CONTROL_STAGE_IDLE; +} + static void _xfer_complete(uint8_t dev_addr, xfer_result_t result) { TU_LOG2("\r\n"); - if (_ctrl_xfer.complete_cb) _ctrl_xfer.complete_cb(dev_addr, &_ctrl_xfer.request, result); + if (_ctrl_xfer.xfer.complete_cb) _ctrl_xfer.xfer.complete_cb(dev_addr, &_ctrl_xfer.xfer.request, result); } -bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, uint8_t* stage, xfer_result_t result, uint32_t xferred_bytes) -{ - (void) ep_addr; - (void) xferred_bytes; - - const uint8_t rhport = usbh_get_rhport(dev_addr); - tusb_control_request_t const * request = &_ctrl_xfer.request; - - if (XFER_RESULT_SUCCESS != result) - { - TU_LOG2("[%u:%u] Control %s\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED"); - - // terminate transfer if any stage failed - *stage = CONTROL_STAGE_IDLE; - _xfer_complete(dev_addr, result); - }else - { - switch(*stage) - { - case CONTROL_STAGE_SETUP: - *stage = CONTROL_STAGE_DATA; - if (request->wLength) - { - // DATA stage: initial data toggle is always 1 - hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.buffer, request->wLength); - return true; - } - __attribute__((fallthrough)); - - case CONTROL_STAGE_DATA: - *stage = CONTROL_STAGE_ACK; - if (request->wLength) - { - TU_LOG2("[%u:%u] Control data:\r\n", rhport, dev_addr); - TU_LOG2_MEM(_ctrl_xfer.buffer, request->wLength, 2); - } - - // ACK stage: toggle is always 1 - hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, 1-request->bmRequestType_bit.direction), NULL, 0); - break; - - case CONTROL_STAGE_ACK: - *stage = CONTROL_STAGE_IDLE; - _xfer_complete(dev_addr, result); - break; - - default: return false; - } - } - - return true; -} #endif diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index e1dd95c34..4217f0422 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -111,7 +111,7 @@ typedef struct typedef osal_queue_def_t* osal_queue_t; -// role device/host is used by OS NONE for mutex (disable usb isr) only +// _int_set is used as mutex in OS NONE (disable/enable USB ISR) #define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ uint8_t _name##_buf[_depth*sizeof(_type)]; \ osal_queue_def_t _name = { \ From 66c933fb61ee01ba640f39a9328b4892d16bb225 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 10 Mar 2022 23:16:59 +0700 Subject: [PATCH 226/504] fix enumeration issue when plugging hub with multiple devices attached --- src/host/hub.c | 4 +- src/host/hub.h | 2 +- src/host/usbh.c | 121 ++++++++++++++++++++++++++---------------------- src/host/usbh.h | 3 +- 4 files changed, 70 insertions(+), 60 deletions(-) diff --git a/src/host/hub.c b/src/host/hub.c index 1fec8b892..4c375c290 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -189,7 +189,7 @@ void hub_close(uint8_t dev_addr) if (p_hub->ep_in) tu_memclr(p_hub, sizeof( hub_interface_t)); } -bool hub_status_pipe_queue(uint8_t dev_addr) +bool hub_edpt_status_xfer(uint8_t dev_addr) { hub_interface_t* hub_itf = get_itf(dev_addr); return usbh_edpt_xfer(dev_addr, hub_itf->ep_in, &hub_itf->status_change, 1); @@ -324,7 +324,7 @@ static bool connection_get_status_complete (uint8_t dev_addr, tusb_control_reque // prepare for next hub status // TODO continue with status_change, or maybe we can do it again with status - hub_status_pipe_queue(dev_addr); + hub_edpt_status_xfer(dev_addr); } return true; diff --git a/src/host/hub.h b/src/host/hub.h index c4d544193..6d81f6773 100644 --- a/src/host/hub.h +++ b/src/host/hub.h @@ -176,7 +176,7 @@ bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, t bool hub_port_reset(uint8_t hub_addr, uint8_t hub_port, tuh_control_complete_cb_t complete_cb); bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, tuh_control_complete_cb_t complete_cb); -bool hub_status_pipe_queue(uint8_t dev_addr); +bool hub_edpt_status_xfer(uint8_t dev_addr); //--------------------------------------------------------------------+ // Internal Class Driver API diff --git a/src/host/usbh.c b/src/host/usbh.c index 3d9db70fa..01675cddd 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -543,7 +543,7 @@ void tuh_task(void) if ( event.connection.hub_addr != 0) { // done with hub, waiting for next data on status pipe - (void) hub_status_pipe_queue( event.connection.hub_addr ); + (void) hub_edpt_status_xfer( event.connection.hub_addr ); } #endif break; @@ -904,6 +904,10 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result return true; } +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ + // a device unplugged from rhport:hub_addr:hub_port static void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port) { @@ -938,49 +942,6 @@ static void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t h } } -//--------------------------------------------------------------------+ -// INTERNAL HELPER -//--------------------------------------------------------------------+ - -static uint8_t get_new_address(bool is_hub) -{ - uint8_t const start = (is_hub ? CFG_TUH_DEVICE_MAX : 0) + 1; - uint8_t const count = (is_hub ? CFG_TUH_HUB : CFG_TUH_DEVICE_MAX); - - for (uint8_t i=0; i < count; i++) - { - uint8_t const addr = start + i; - if (!get_device(addr)->connected) return addr; - } - return ADDR_INVALID; -} - -void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) -{ - usbh_device_t* dev = get_device(dev_addr); - - for(itf_num++; itf_num < CFG_TUH_INTERFACE_MAX; itf_num++) - { - // continue with next valid interface - // TODO skip IAD binding interface such as CDCs - uint8_t const drv_id = dev->itf2drv[itf_num]; - if (drv_id != DRVID_INVALID) - { - usbh_class_driver_t const * driver = &usbh_class_drivers[drv_id]; - TU_LOG2("%s set config: itf = %u\r\n", driver->name, itf_num); - driver->set_config(dev_addr, itf_num); - break; - } - } - - // all interface are configured - if (itf_num == CFG_TUH_INTERFACE_MAX) - { - // Invoke callback if available - if (tuh_mount_cb) tuh_mount_cb(dev_addr); - } -} - //--------------------------------------------------------------------+ // Enumeration Process // is a lengthy process with a series of control transfer to configure @@ -991,9 +952,9 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) //--------------------------------------------------------------------+ static bool enum_request_addr0_device_desc(void); -static bool enum_request_set_addr(void); - static bool enum_get_addr0_device_desc_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); + +static bool enum_request_set_addr(void); static bool enum_set_address_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); static bool enum_get_device_desc_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); static bool enum_get_9byte_config_desc_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); @@ -1001,6 +962,9 @@ static bool enum_get_config_desc_complete (uint8_t dev_addr, tusb_control_ static bool enum_set_config_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); static bool parse_configuration_descriptor (uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg); +static uint8_t get_new_address(bool is_hub); +static void enum_full_complete(void); + #if CFG_TUH_HUB // Enum sequence: @@ -1015,7 +979,7 @@ static bool enum_hub_clear_reset1_complete(uint8_t dev_addr, tusb_control_reques static bool enum_hub_get_status0_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) { - (void) dev_addr; (void) request; + (void) request; TU_ASSERT(XFER_RESULT_SUCCESS == result); hub_port_status_response_t port_status; @@ -1024,7 +988,8 @@ static bool enum_hub_get_status0_complete(uint8_t dev_addr, tusb_control_request if ( !port_status.status.connection ) { // device unplugged while delaying, nothing else to do, queue hub status - return hub_status_pipe_queue(dev_addr); + enum_full_complete(); + return false; } _dev0.speed = (port_status.status.high_speed) ? TUSB_SPEED_HIGH : @@ -1083,9 +1048,6 @@ static bool enum_hub_clear_reset1_complete(uint8_t dev_addr, tusb_control_reques enum_request_set_addr(); - // done with hub, waiting for next data on status pipe - (void) hub_status_pipe_queue( _dev0.hub_addr ); - return true; } @@ -1144,11 +1106,8 @@ static bool enum_get_addr0_device_desc_complete(uint8_t dev_addr, tusb_control_r if (XFER_RESULT_SUCCESS != result) { -#if CFG_TUH_HUB - // TODO remove, waiting for next data on status pipe - if (_dev0.hub_addr != 0) hub_status_pipe_queue(_dev0.hub_addr); -#endif - + // stop enumeration, maybe we could retry this + enum_full_complete(); return false; } @@ -1407,4 +1366,54 @@ static bool parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configura return true; } +void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) +{ + usbh_device_t* dev = get_device(dev_addr); + + for(itf_num++; itf_num < CFG_TUH_INTERFACE_MAX; itf_num++) + { + // continue with next valid interface + // TODO skip IAD binding interface such as CDCs + uint8_t const drv_id = dev->itf2drv[itf_num]; + if (drv_id != DRVID_INVALID) + { + usbh_class_driver_t const * driver = &usbh_class_drivers[drv_id]; + TU_LOG2("%s set config: itf = %u\r\n", driver->name, itf_num); + driver->set_config(dev_addr, itf_num); + break; + } + } + + // all interface are configured + if (itf_num == CFG_TUH_INTERFACE_MAX) + { + enum_full_complete(); + + // Invoke callback if available + if (tuh_mount_cb) tuh_mount_cb(dev_addr); + } +} + +static void enum_full_complete(void) +{ +#if CFG_TUH_HUB + // get next hub status + if (_dev0.hub_addr) hub_edpt_status_xfer(_dev0.hub_addr); +#endif + +} + +static uint8_t get_new_address(bool is_hub) +{ + uint8_t const start = (is_hub ? CFG_TUH_DEVICE_MAX : 0) + 1; + uint8_t const count = (is_hub ? CFG_TUH_HUB : CFG_TUH_DEVICE_MAX); + + for (uint8_t i=0; i < count; i++) + { + uint8_t const addr = start + i; + if (!get_device(addr)->connected) return addr; + } + return ADDR_INVALID; +} + #endif diff --git a/src/host/usbh.h b/src/host/usbh.h index 31d63d6a7..eec2ed702 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -80,7 +80,8 @@ static inline bool tuh_ready(uint8_t daddr) return tuh_mounted(daddr) && !tuh_suspended(daddr); } -// Carry out control transfer +// Carry out a control transfer +// true on success, false if there is on-going control trasnfer bool tuh_control_xfer (uint8_t daddr, tusb_control_request_t const* request, void* buffer, tuh_control_complete_cb_t complete_cb); // Set Configuration From 951ece17e1e26c297f3c05807271ab1ba56a2ada Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 10 Mar 2022 23:20:12 +0700 Subject: [PATCH 227/504] fix build warning --- src/host/usbh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index 01675cddd..11bf2f997 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -979,7 +979,7 @@ static bool enum_hub_clear_reset1_complete(uint8_t dev_addr, tusb_control_reques static bool enum_hub_get_status0_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) { - (void) request; + (void) dev_addr; (void) request; TU_ASSERT(XFER_RESULT_SUCCESS == result); hub_port_status_response_t port_status; From 37960990a5fb0a42a5faa19230f0051efaa4e6c0 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 10 Mar 2022 11:01:44 -0800 Subject: [PATCH 228/504] Print speed. Don't crash if string get fails --- examples/host/device_info/src/main.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/examples/host/device_info/src/main.c b/examples/host/device_info/src/main.c index 45b616af0..e6149db89 100644 --- a/examples/host/device_info/src/main.c +++ b/examples/host/device_info/src/main.c @@ -90,6 +90,10 @@ static void _wait_and_convert(uint16_t *temp_buf, size_t buf_len) { while (_get_string_result == 0xff) { tuh_task(); } + if (_get_string_result != XFER_RESULT_SUCCESS) { + temp_buf[0] = 0; + return; + } size_t utf16_len = ((temp_buf[0] & 0xff) - 2) / sizeof(uint16_t); size_t utf8_len = _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); @@ -128,6 +132,21 @@ int main(void) tuh_vid_pid_get(i, &vid, &pid); printf("%d vid %04x pid %04x\r\n", i, vid, pid); + tusb_speed_t speed = tuh_speed_get(i); + switch (speed) { + case TUSB_SPEED_FULL: + printf("Full speed\r\n"); + break; + case TUSB_SPEED_LOW: + printf("Low speed\r\n"); + break; + case TUSB_SPEED_HIGH: + printf("High speed\r\n"); + break; + default: + break; + } + _get_string_result = 0xff; uint16_t temp_buf[127]; if (tuh_descriptor_string_serial_get(i, 0, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb)) { From a715077b1079993f4cd01bbf54b8166a6612b29b Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 11 Mar 2022 09:57:35 +0700 Subject: [PATCH 229/504] remove usbh_control.c --- examples/host/bare_api/Makefile | 1 - examples/host/cdc_msc_hid/Makefile | 1 - examples/host/hid_controller/Makefile | 1 - examples/host/hid_to_cdc/Makefile | 3 +- hw/bsp/rp2040/family.cmake | 1 - src/host/usbh_control.c | 85 --------------------------- 6 files changed, 1 insertion(+), 91 deletions(-) delete mode 100644 src/host/usbh_control.c diff --git a/examples/host/bare_api/Makefile b/examples/host/bare_api/Makefile index c59369ffa..13e14df53 100644 --- a/examples/host/bare_api/Makefile +++ b/examples/host/bare_api/Makefile @@ -21,7 +21,6 @@ SRC_C += \ src/class/msc/msc_host.c \ src/host/hub.c \ src/host/usbh.c \ - src/host/usbh_control.c \ src/portable/ohci/ohci.c \ src/portable/nxp/lpc17_40/hcd_lpc17_40.c diff --git a/examples/host/cdc_msc_hid/Makefile b/examples/host/cdc_msc_hid/Makefile index ce0dd1a40..272acbac8 100644 --- a/examples/host/cdc_msc_hid/Makefile +++ b/examples/host/cdc_msc_hid/Makefile @@ -19,7 +19,6 @@ SRC_C += \ src/class/msc/msc_host.c \ src/host/hub.c \ src/host/usbh.c \ - src/host/usbh_control.c \ src/portable/ohci/ohci.c \ src/portable/nxp/lpc17_40/hcd_lpc17_40.c diff --git a/examples/host/hid_controller/Makefile b/examples/host/hid_controller/Makefile index c58df562b..06dc56914 100644 --- a/examples/host/hid_controller/Makefile +++ b/examples/host/hid_controller/Makefile @@ -22,7 +22,6 @@ SRC_C += \ src/class/msc/msc_host.c \ src/host/hub.c \ src/host/usbh.c \ - src/host/usbh_control.c \ src/portable/ohci/ohci.c \ src/portable/nxp/lpc17_40/hcd_lpc17_40.c diff --git a/examples/host/hid_to_cdc/Makefile b/examples/host/hid_to_cdc/Makefile index b62a383eb..3fe9b0888 100644 --- a/examples/host/hid_to_cdc/Makefile +++ b/examples/host/hid_to_cdc/Makefile @@ -14,7 +14,6 @@ CFLAGS += -Wno-error=cast-align -Wno-error=null-dereference SRC_C += \ src/class/hid/hid_host.c \ src/host/hub.c \ - src/host/usbh.c \ - src/host/usbh_control.c + src/host/usbh.c include ../../rules.mk diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index 1aa180ef8..e832c0756 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -83,7 +83,6 @@ if (NOT TARGET _rp2040_family_inclusion_marker) ${TOP}/src/portable/raspberrypi/rp2040/hcd_rp2040.c ${TOP}/src/portable/raspberrypi/rp2040/rp2040_usb.c ${TOP}/src/host/usbh.c - ${TOP}/src/host/usbh_control.c ${TOP}/src/host/hub.c ${TOP}/src/class/cdc/cdc_host.c ${TOP}/src/class/hid/hid_host.c diff --git a/src/host/usbh_control.c b/src/host/usbh_control.c deleted file mode 100644 index 38f03a8d2..000000000 --- a/src/host/usbh_control.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020, 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_TUH_ENABLED && 0 - -#include "tusb.h" -#include "usbh_classdriver.h" - -typedef struct -{ - tusb_control_request_t request TU_ATTR_ALIGNED(4); - uint8_t* buffer; - tuh_control_complete_cb_t complete_cb; - - uint8_t daddr; -} usbh_control_xfer_t; - -static usbh_control_xfer_t _xfer; -static uint8_t _stage = CONTROL_STAGE_IDLE; - -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM DECLARATION -//--------------------------------------------------------------------+ - -uint8_t usbh_control_xfer_stage(void) -{ - return _stage; -} - -bool usbh_control_xfer (uint8_t dev_addr, tusb_control_request_t const* request, void* buffer, tuh_control_complete_cb_t complete_cb) -{ - // TODO need to claim the endpoint first - const uint8_t rhport = usbh_get_rhport(dev_addr); - - _ctrl_xfer.xfer.daddr = dev_addr; - _ctrl_xfer.xfer.request = (*request); - _ctrl_xfer.xfer.buffer = buffer; - _ctrl_xfer.xfer.complete_cb = complete_cb; - - _stage = CONTROL_STAGE_SETUP; - - // Send setup packet - TU_ASSERT( hcd_setup_send(rhport, dev_addr, (uint8_t const*) &_ctrl_xfer.xfer.request) ); - - return true; -} - -void usbh_control_xfer_abort(uint8_t dev_addr) -{ - if (_ctrl_xfer.xfer.daddr == dev_addr) _stage = CONTROL_STAGE_IDLE; -} - -static void _xfer_complete(uint8_t dev_addr, xfer_result_t result) -{ - TU_LOG2("\r\n"); - if (_ctrl_xfer.xfer.complete_cb) _ctrl_xfer.xfer.complete_cb(dev_addr, &_ctrl_xfer.xfer.request, result); -} - - -#endif From 6b5490ced687ba44ede9a0dd1dd62b4b67eedf59 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 11 Mar 2022 13:12:36 +0700 Subject: [PATCH 230/504] merge device_info into bare_api example --- examples/host/bare_api/src/main.c | 123 +++++++++++-- examples/host/device_info/CMakeLists.txt | 27 --- examples/host/device_info/Makefile | 28 --- examples/host/device_info/only.txt | 9 - examples/host/device_info/src/main.c | 194 -------------------- examples/host/device_info/src/tusb_config.h | 96 ---------- src/host/usbh.c | 4 +- 7 files changed, 107 insertions(+), 374 deletions(-) delete mode 100644 examples/host/device_info/CMakeLists.txt delete mode 100644 examples/host/device_info/Makefile delete mode 100644 examples/host/device_info/only.txt delete mode 100644 examples/host/device_info/src/main.c delete mode 100644 examples/host/device_info/src/tusb_config.h diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index 5f8f886c8..73e97c390 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -46,8 +46,6 @@ int main(void) board_init(); printf("TinyUSB Host HID Controller Example\r\n"); - printf("Note: Events only displayed for explictly supported controllers\r\n"); - tusb_init(); while (1) @@ -64,10 +62,74 @@ int main(void) // TinyUSB Callbacks //--------------------------------------------------------------------+ -uint8_t usb_buf[256] TU_ATTR_ALIGNED(4); +// English +#define LANGUAGE_ID 0x0409 +//uint8_t usb_buf[256] TU_ATTR_ALIGNED(4); tusb_desc_device_t desc_device; +static volatile xfer_result_t _get_string_result; + +static bool _transfer_done_cb(uint8_t daddr, tusb_control_request_t const *request, xfer_result_t result) { + (void)daddr; + (void)request; + _get_string_result = result; + return true; +} + +static void _convert_utf16le_to_utf8(const uint16_t *utf16, size_t utf16_len, uint8_t *utf8, size_t utf8_len) { + // TODO: Check for runover. + (void)utf8_len; + // Get the UTF-16 length out of the data itself. + + for (size_t i = 0; i < utf16_len; i++) { + uint16_t chr = utf16[i]; + if (chr < 0x80) { + *utf8++ = chr & 0xff; + } else if (chr < 0x800) { + *utf8++ = (uint8_t)(0xC0 | (chr >> 6 & 0x1F)); + *utf8++ = (uint8_t)(0x80 | (chr >> 0 & 0x3F)); + } else { + // TODO: Verify surrogate. + *utf8++ = (uint8_t)(0xE0 | (chr >> 12 & 0x0F)); + *utf8++ = (uint8_t)(0x80 | (chr >> 6 & 0x3F)); + *utf8++ = (uint8_t)(0x80 | (chr >> 0 & 0x3F)); + } + // TODO: Handle UTF-16 code points that take two entries. + } +} + +// Count how many bytes a utf-16-le encoded string will take in utf-8. +static int _count_utf8_bytes(const uint16_t *buf, size_t len) { + size_t total_bytes = 0; + for (size_t i = 0; i < len; i++) { + uint16_t chr = buf[i]; + if (chr < 0x80) { + total_bytes += 1; + } else if (chr < 0x800) { + total_bytes += 2; + } else { + total_bytes += 3; + } + // TODO: Handle UTF-16 code points that take two entries. + } + return total_bytes; +} + +static void _wait_and_convert(uint16_t *temp_buf, size_t buf_len) { + while (_get_string_result == 0xff) { + tuh_task(); + } + if (_get_string_result != XFER_RESULT_SUCCESS) { + temp_buf[0] = 0; + return; + } + size_t utf16_len = ((temp_buf[0] & 0xff) - 2) / sizeof(uint16_t); + size_t utf8_len = _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'; +} + bool print_device_descriptor(uint8_t daddr, tusb_control_request_t const * request, xfer_result_t result) { (void) request; @@ -78,26 +140,49 @@ bool print_device_descriptor(uint8_t daddr, tusb_control_request_t const * reque return false; } - printf("Rhport %u Device %u: ID %04x:%04x\r\n", 0, daddr, desc_device.idVendor, desc_device.idProduct); + printf("Device %u: ID %04x:%04x\r\n", daddr, desc_device.idVendor, desc_device.idProduct); printf("Device Descriptor:\r\n"); - printf(" bLength %u\r\n", desc_device.bLength); - printf(" bDescriptorType %u\r\n", desc_device.bDescriptorType); - printf(" bcdUSB %04x\r\n", desc_device.bcdUSB); + printf(" bLength %u\r\n" , desc_device.bLength); + printf(" bDescriptorType %u\r\n" , desc_device.bDescriptorType); + printf(" bcdUSB %04x\r\n" , desc_device.bcdUSB); + printf(" bDeviceClass %u\r\n" , desc_device.bDeviceClass); + printf(" bDeviceSubClass %u\r\n" , desc_device.bDeviceSubClass); + printf(" bDeviceProtocol %u\r\n" , desc_device.bDeviceProtocol); + printf(" bMaxPacketSize0 %u\r\n" , desc_device.bMaxPacketSize0); + printf(" idVendor 0x%04x\r\n" , desc_device.idVendor); + printf(" idProduct 0x%04x\r\n" , desc_device.idProduct); + printf(" bcdDevice %04x\r\n" , desc_device.bcdDevice); - printf(" bDeviceClass %u\r\n", desc_device.bDeviceClass); - printf(" bDeviceSubClass %u\r\n", desc_device.bDeviceSubClass); - printf(" bDeviceProtocol %u\r\n", desc_device.bDeviceProtocol); - printf(" bMaxPacketSize0 %u\r\n", desc_device.bMaxPacketSize0); + _get_string_result = 0xff; + uint16_t temp_buf[128]; - printf(" idVendor 0x%04x\r\n", desc_device.idVendor); - printf(" idProduct 0x%04x\r\n", desc_device.idProduct); - printf(" bcdDevice %04x\r\n", desc_device.bcdDevice); + printf(" iManufacturer %u " , desc_device.iManufacturer); + temp_buf[0] = 0; + if (tuh_descriptor_get_manufacturer_string(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb)) { + _wait_and_convert(temp_buf, TU_ARRAY_SIZE(temp_buf)); + printf((const char*) temp_buf); + } + printf("\r\n"); - printf(" iManufacturer %u\r\n", desc_device.iManufacturer); - printf(" iProduct %u\r\n", desc_device.iProduct); - printf(" iSerialNumber %u\r\n", desc_device.iSerialNumber); + printf(" iProduct %u " , desc_device.iProduct); + _get_string_result = 0xff; + temp_buf[0] = 0; + if (tuh_descriptor_get_product_string(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb)) { + _wait_and_convert(temp_buf, TU_ARRAY_SIZE(temp_buf)); + printf((const char*) temp_buf); + } + printf("\r\n"); - printf(" bNumConfigurations %u\r\n", desc_device.bNumConfigurations); + printf(" iSerialNumber %u " , desc_device.iSerialNumber); + _get_string_result = 0xff; + temp_buf[0] = 0; + if (tuh_descriptor_get_serial_string(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb)) { + _wait_and_convert(temp_buf, TU_ARRAY_SIZE(temp_buf)); + printf((const char*) temp_buf); + } + printf("\r\n"); + + printf(" bNumConfigurations %u\r\n" , desc_device.bNumConfigurations); return true; } @@ -107,7 +192,7 @@ void tuh_mount_cb (uint8_t daddr) { printf("Device attached, address = %d\r\n", daddr); - // get device descriptor + // Get Device Descriptor tuh_descriptor_get_device(daddr, &desc_device, 18, print_device_descriptor); } diff --git a/examples/host/device_info/CMakeLists.txt b/examples/host/device_info/CMakeLists.txt deleted file mode 100644 index bff281a8c..000000000 --- a/examples/host/device_info/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -cmake_minimum_required(VERSION 3.5) - -include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) - -# gets PROJECT name for the example -family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR}) - -project(${PROJECT}) - -# Checks this example is valid for the family and initializes the project -family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}) - -add_executable(${PROJECT}) - -# Example source -target_sources(${PROJECT} PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c - ) - -# Example include -target_include_directories(${PROJECT} PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/src - ) - -# Configure compilation flags and libraries for the example... see the corresponding function -# in hw/bsp/FAMILY/family.cmake for details. -family_configure_host_example(${PROJECT}) \ No newline at end of file diff --git a/examples/host/device_info/Makefile b/examples/host/device_info/Makefile deleted file mode 100644 index c59369ffa..000000000 --- a/examples/host/device_info/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -include ../../../tools/top.mk -include ../../make.mk - -INC += \ - src \ - $(TOP)/hw \ - -# Example source -EXAMPLE_SOURCE += \ - src/main.c - -SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) - -# TODO: suppress warning caused by host stack -CFLAGS += -Wno-error=cast-align -Wno-error=null-dereference - -# TinyUSB Host Stack source -SRC_C += \ - src/class/cdc/cdc_host.c \ - src/class/hid/hid_host.c \ - src/class/msc/msc_host.c \ - src/host/hub.c \ - src/host/usbh.c \ - src/host/usbh_control.c \ - src/portable/ohci/ohci.c \ - src/portable/nxp/lpc17_40/hcd_lpc17_40.c - -include ../../rules.mk diff --git a/examples/host/device_info/only.txt b/examples/host/device_info/only.txt deleted file mode 100644 index 7fe4e3f5c..000000000 --- a/examples/host/device_info/only.txt +++ /dev/null @@ -1,9 +0,0 @@ -mcu:LPC175X_6X -mcu:LPC177X_8X -mcu:LPC18XX -mcu:LPC40XX -mcu:LPC43XX -mcu:MIMXRT10XX -mcu:RP2040 -mcu:MSP432E4 -mcu:RX65X diff --git a/examples/host/device_info/src/main.c b/examples/host/device_info/src/main.c deleted file mode 100644 index e6149db89..000000000 --- a/examples/host/device_info/src/main.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2022 Scott Shawcroft for Adafruit Industries - * - * 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 prints out info about the enumerated devices. */ - - -#include -#include -#include - -#include "bsp/board.h" -#include "tusb.h" - -//--------------------------------------------------------------------+ -// MACRO CONSTANT TYPEDEF PROTYPES -//--------------------------------------------------------------------+ -void led_blinking_task(void); - -static xfer_result_t _get_string_result; - -static bool _transfer_done_cb(uint8_t daddr, tusb_control_request_t const *request, xfer_result_t result) { - (void)daddr; - (void)request; - _get_string_result = result; - return true; -} - -static void _convert_utf16le_to_utf8(const uint16_t *utf16, size_t utf16_len, uint8_t *utf8, size_t utf8_len) { - // TODO: Check for runover. - (void)utf8_len; - // Get the UTF-16 length out of the data itself. - - for (size_t i = 0; i < utf16_len; i++) { - uint16_t chr = utf16[i]; - if (chr < 0x80) { - *utf8++ = chr & 0xff; - } else if (chr < 0x800) { - *utf8++ = (uint8_t)(0xC0 | (chr >> 6 & 0x1F)); - *utf8++ = (uint8_t)(0x80 | (chr >> 0 & 0x3F)); - } else { - // TODO: Verify surrogate. - *utf8++ = (uint8_t)(0xE0 | (chr >> 12 & 0x0F)); - *utf8++ = (uint8_t)(0x80 | (chr >> 6 & 0x3F)); - *utf8++ = (uint8_t)(0x80 | (chr >> 0 & 0x3F)); - } - // TODO: Handle UTF-16 code points that take two entries. - } -} - -// Count how many bytes a utf-16-le encoded string will take in utf-8. -static int _count_utf8_bytes(const uint16_t *buf, size_t len) { - size_t total_bytes = 0; - for (size_t i = 0; i < len; i++) { - uint16_t chr = buf[i]; - if (chr < 0x80) { - total_bytes += 1; - } else if (chr < 0x800) { - total_bytes += 2; - } else { - total_bytes += 3; - } - // TODO: Handle UTF-16 code points that take two entries. - } - return total_bytes; -} - -static void _wait_and_convert(uint16_t *temp_buf, size_t buf_len) { - while (_get_string_result == 0xff) { - tuh_task(); - } - if (_get_string_result != XFER_RESULT_SUCCESS) { - temp_buf[0] = 0; - return; - } - size_t utf16_len = ((temp_buf[0] & 0xff) - 2) / sizeof(uint16_t); - size_t utf8_len = _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'; -} - -/*------------- MAIN -------------*/ -int main(void) -{ - board_init(); - - printf("TinyUSB Host Device Info Example\r\n"); - - tusb_init(); - - uint32_t interval_ms = 5000; - uint32_t start_time = 0; - - while (1) - { - // tinyusb host task - tuh_task(); - led_blinking_task(); - - if (board_millis() - start_time < interval_ms) { - continue; - } - start_time = board_millis(); - // Brute force check every device address to see if it is active. - for (int i = 1; i < CFG_TUH_DEVICE_MAX + CFG_TUH_HUB + 1; i++) { - if (!tuh_ready(i)) { - continue; - } - uint16_t vid; - uint16_t pid; - tuh_vid_pid_get(i, &vid, &pid); - printf("%d vid %04x pid %04x\r\n", i, vid, pid); - - tusb_speed_t speed = tuh_speed_get(i); - switch (speed) { - case TUSB_SPEED_FULL: - printf("Full speed\r\n"); - break; - case TUSB_SPEED_LOW: - printf("Low speed\r\n"); - break; - case TUSB_SPEED_HIGH: - printf("High speed\r\n"); - break; - default: - break; - } - - _get_string_result = 0xff; - uint16_t temp_buf[127]; - if (tuh_descriptor_string_serial_get(i, 0, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb)) { - _wait_and_convert(temp_buf, TU_ARRAY_SIZE(temp_buf)); - printf("Serial: %s\r\n", (const char*) temp_buf); - } - - _get_string_result = 0xff; - temp_buf[0] = 0; - if (tuh_descriptor_string_product_get(i, 0, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb)) { - _wait_and_convert(temp_buf, TU_ARRAY_SIZE(temp_buf)); - printf("Product: %s\r\n", (const char*) temp_buf); - } - - _get_string_result = 0xff; - temp_buf[0] = 0; - if (tuh_descriptor_string_manufacturer_get(i, 0, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb)) { - _wait_and_convert(temp_buf, TU_ARRAY_SIZE(temp_buf)); - printf("Manufacturer: %s\r\n", (const char*) temp_buf); - } - } - printf("\n"); - } - - return 0; -} - - -//--------------------------------------------------------------------+ -// Blinking Task -//--------------------------------------------------------------------+ -void led_blinking_task(void) -{ - const uint32_t interval_ms = 1000; - static uint32_t start_ms = 0; - - static bool led_state = false; - - // Blink every interval ms - if ( board_millis() - start_ms < interval_ms) return; // not enough time - start_ms += interval_ms; - - board_led_write(led_state); - led_state = 1 - led_state; // toggle -} diff --git a/examples/host/device_info/src/tusb_config.h b/examples/host/device_info/src/tusb_config.h deleted file mode 100644 index 6b413e46f..000000000 --- a/examples/host/device_info/src/tusb_config.h +++ /dev/null @@ -1,96 +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 _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -//-------------------------------------------------------------------- -// COMMON CONFIGURATION -//-------------------------------------------------------------------- - -// defined by compiler flags for flexibility -#ifndef CFG_TUSB_MCU - #error CFG_TUSB_MCU must be defined -#endif - -#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | OPT_MODE_HIGH_SPEED) -#else - #define CFG_TUSB_RHPORT0_MODE OPT_MODE_HOST -#endif - -#ifndef CFG_TUSB_OS -#define CFG_TUSB_OS OPT_OS_NONE -#endif - -// CFG_TUSB_DEBUG is defined by compiler in DEBUG build -// #define CFG_TUSB_DEBUG 0 - -/* 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 - -//-------------------------------------------------------------------- -// CONFIGURATION -//-------------------------------------------------------------------- - -// Size of buffer to hold descriptors and other data used for enumeration -#define CFG_TUH_ENUMERATION_BUFSIZE 256 - -// only hub class is enabled -#define CFG_TUH_HUB 1 - -// max device support (excluding hub device) -// 1 hub typically has 4 ports -#define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB ? 4 : 1) - -#define CFG_TUH_ENDPOINT_MAX 8 - -#define CFG_TUH_TASK_QUEUE_SZ 64 - -//------------- HID -------------// - -#define CFG_TUH_HID_EP_BUFSIZE 64 - -#ifdef __cplusplus - } -#endif - -#endif /* _TUSB_CONFIG_H_ */ diff --git a/src/host/usbh.c b/src/host/usbh.c index 11bf2f997..617aff79a 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -535,7 +535,7 @@ void tuh_task(void) break; case HCD_EVENT_DEVICE_REMOVE: - TU_LOG2("USBH DEVICE REMOVED\r\n"); + TU_LOG2("[%u:%u:%u] USBH DEVICE REMOVED\r\n", event.rhport, event.connection.hub_addr, event.connection.hub_port); process_device_unplugged(event.rhport, event.connection.hub_addr, event.connection.hub_port); #if CFG_TUH_HUB @@ -924,6 +924,8 @@ static void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t h (hub_port == 0 || dev->hub_port == hub_port) && dev->connected) { + TU_LOG2(" Address = %u\r\n", dev_addr); + // Invoke callback before close driver if (tuh_umount_cb) tuh_umount_cb(dev_addr); From bcdeb386cc4d3afb3d7213c961e4611e511c4e97 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 11 Mar 2022 21:57:55 +0700 Subject: [PATCH 231/504] rework usbh control xfer - change API of tuh_control_xfer and its callback - rename tuh_control_complete_cb_t to tuh_control_xfer_cb_t - add user argument to control callback - migrate usbh and hub --- examples/host/bare_api/src/main.c | 16 +- src/class/cdc/cdc_host.c | 2 +- src/class/cdc/cdc_host.h | 6 +- src/host/hub.c | 148 +++++++++------ src/host/hub.h | 8 +- src/host/usbh.c | 292 +++++++++++++++++------------- src/host/usbh.h | 70 ++++--- 7 files changed, 315 insertions(+), 227 deletions(-) diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index 73e97c390..6888d13a2 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -70,9 +70,9 @@ tusb_desc_device_t desc_device; static volatile xfer_result_t _get_string_result; -static bool _transfer_done_cb(uint8_t daddr, tusb_control_request_t const *request, xfer_result_t result) { +static bool _transfer_done_cb(uint8_t daddr, tuh_control_xfer_t const *xfer, xfer_result_t result) { (void)daddr; - (void)request; + (void)xfer; _get_string_result = result; return true; } @@ -130,9 +130,9 @@ static void _wait_and_convert(uint16_t *temp_buf, size_t buf_len) { ((uint8_t*) temp_buf)[utf8_len] = '\0'; } -bool print_device_descriptor(uint8_t daddr, tusb_control_request_t const * request, xfer_result_t result) +bool print_device_descriptor(uint8_t daddr, tuh_control_xfer_t const * xfer, xfer_result_t result) { - (void) request; + (void) xfer; if ( XFER_RESULT_SUCCESS != result ) { @@ -158,7 +158,7 @@ bool print_device_descriptor(uint8_t daddr, tusb_control_request_t const * reque printf(" iManufacturer %u " , desc_device.iManufacturer); temp_buf[0] = 0; - if (tuh_descriptor_get_manufacturer_string(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb)) { + if (tuh_descriptor_get_manufacturer_string(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb, 0)) { _wait_and_convert(temp_buf, TU_ARRAY_SIZE(temp_buf)); printf((const char*) temp_buf); } @@ -167,7 +167,7 @@ bool print_device_descriptor(uint8_t daddr, tusb_control_request_t const * reque printf(" iProduct %u " , desc_device.iProduct); _get_string_result = 0xff; temp_buf[0] = 0; - if (tuh_descriptor_get_product_string(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb)) { + if (tuh_descriptor_get_product_string(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb, 0)) { _wait_and_convert(temp_buf, TU_ARRAY_SIZE(temp_buf)); printf((const char*) temp_buf); } @@ -176,7 +176,7 @@ bool print_device_descriptor(uint8_t daddr, tusb_control_request_t const * reque printf(" iSerialNumber %u " , desc_device.iSerialNumber); _get_string_result = 0xff; temp_buf[0] = 0; - if (tuh_descriptor_get_serial_string(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb)) { + if (tuh_descriptor_get_serial_string(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb, 0)) { _wait_and_convert(temp_buf, TU_ARRAY_SIZE(temp_buf)); printf((const char*) temp_buf); } @@ -193,7 +193,7 @@ void tuh_mount_cb (uint8_t daddr) printf("Device attached, address = %d\r\n", daddr); // Get Device Descriptor - tuh_descriptor_get_device(daddr, &desc_device, 18, print_device_descriptor); + tuh_descriptor_get_device(daddr, &desc_device, 18, print_device_descriptor, 0); } /// Invoked when device is unmounted (bus reset/unplugged) diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 2787cd201..6a29f3f43 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -120,7 +120,7 @@ bool tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is return usbh_edpt_xfer(dev_addr, ep_in, p_buffer, length); } -bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_control_complete_cb_t complete_cb) +bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_control_xfer_cb_t complete_cb) { cdch_data_t const * p_cdc = get_itf(dev_addr); tusb_control_request_t const request = diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index 0d435138b..67162a0ca 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -42,14 +42,14 @@ * \defgroup CDC_Serial_Host Host * @{ */ -bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_control_complete_cb_t complete_cb); +bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_control_xfer_cb_t complete_cb); -static inline bool tuh_cdc_connect(uint8_t dev_addr, tuh_control_complete_cb_t complete_cb) +static inline bool tuh_cdc_connect(uint8_t dev_addr, tuh_control_xfer_cb_t complete_cb) { return tuh_cdc_set_control_line_state(dev_addr, true, true, complete_cb); } -static inline bool tuh_cdc_disconnect(uint8_t dev_addr, tuh_control_complete_cb_t complete_cb) +static inline bool tuh_cdc_disconnect(uint8_t dev_addr, tuh_control_xfer_cb_t complete_cb) { return tuh_cdc_set_control_line_state(dev_addr, false, false, complete_cb); } diff --git a/src/host/hub.c b/src/host/hub.c index 4c375c290..a0cf7b7e5 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -77,71 +77,92 @@ static char const* const _hub_feature_str[] = //--------------------------------------------------------------------+ // HUB //--------------------------------------------------------------------+ -bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_control_complete_cb_t complete_cb) +bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_control_xfer_cb_t complete_cb) { - tusb_control_request_t const request = + tuh_control_xfer_t const xfer = { - .bmRequestType_bit = + .request = { - .recipient = TUSB_REQ_RCPT_OTHER, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_OUT + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_OTHER, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HUB_REQUEST_CLEAR_FEATURE, + .wValue = feature, + .wIndex = hub_port, + .wLength = 0 }, - .bRequest = HUB_REQUEST_CLEAR_FEATURE, - .wValue = feature, - .wIndex = hub_port, - .wLength = 0 + + .buffer = NULL, + .complete_cb = complete_cb, + .user_arg = 0 }; TU_LOG2("HUB Clear Feature: %s, addr = %u port = %u\r\n", _hub_feature_str[feature], hub_addr, hub_port); - TU_ASSERT( tuh_control_xfer(hub_addr, &request, NULL, complete_cb) ); + TU_ASSERT( tuh_control_xfer(hub_addr, &xfer) ); return true; } -bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_control_complete_cb_t complete_cb) +bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_control_xfer_cb_t complete_cb) { - tusb_control_request_t const request = + tuh_control_xfer_t const xfer = { - .bmRequestType_bit = + .request = { - .recipient = TUSB_REQ_RCPT_OTHER, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_OUT + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_OTHER, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HUB_REQUEST_SET_FEATURE, + .wValue = feature, + .wIndex = hub_port, + .wLength = 0 }, - .bRequest = HUB_REQUEST_SET_FEATURE, - .wValue = feature, - .wIndex = hub_port, - .wLength = 0 + + .buffer = NULL, + .complete_cb = complete_cb, + .user_arg = 0 }; TU_LOG2("HUB Set Feature: %s, addr = %u port = %u\r\n", _hub_feature_str[feature], hub_addr, hub_port); - TU_ASSERT( tuh_control_xfer(hub_addr, &request, NULL, complete_cb) ); + TU_ASSERT( tuh_control_xfer(hub_addr, &xfer) ); return true; } -bool hub_port_reset(uint8_t hub_addr, uint8_t hub_port, tuh_control_complete_cb_t complete_cb) +bool hub_port_reset(uint8_t hub_addr, uint8_t hub_port, tuh_control_xfer_cb_t complete_cb) { return hub_port_set_feature(hub_addr, hub_port, HUB_FEATURE_PORT_RESET, complete_cb); } -bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, tuh_control_complete_cb_t complete_cb) +bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, tuh_control_xfer_cb_t complete_cb) { - tusb_control_request_t const request = + tuh_control_xfer_t const xfer = { - .bmRequestType_bit = + .request = { - .recipient = TUSB_REQ_RCPT_OTHER, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_IN + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_OTHER, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN + }, + .bRequest = HUB_REQUEST_GET_STATUS, + .wValue = 0, + .wIndex = hub_port, + .wLength = 4 }, - .bRequest = HUB_REQUEST_GET_STATUS, - .wValue = 0, - .wIndex = hub_port, - .wLength = 4 + + .buffer = resp, + .complete_cb = complete_cb, + .user_arg = 0 }; TU_LOG2("HUB Get Port Status: addr = %u port = %u\r\n", hub_addr, hub_port); - TU_ASSERT( tuh_control_xfer( hub_addr, &request, resp, complete_cb) ); + TU_ASSERT( tuh_control_xfer( hub_addr, &xfer) ); return true; } @@ -200,8 +221,8 @@ bool hub_edpt_status_xfer(uint8_t dev_addr) // Set Configure //--------------------------------------------------------------------+ -static bool config_set_port_power (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); -static bool config_port_power_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +static bool config_set_port_power (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); +static bool config_port_power_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); bool hub_set_config(uint8_t dev_addr, uint8_t itf_num) { @@ -209,28 +230,35 @@ bool hub_set_config(uint8_t dev_addr, uint8_t itf_num) TU_ASSERT(itf_num == p_hub->itf_num); // Get Hub Descriptor - tusb_control_request_t const request = + tuh_control_xfer_t const xfer = { - .bmRequestType_bit = + .request = { - .recipient = TUSB_REQ_RCPT_DEVICE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_IN + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN + }, + .bRequest = HUB_REQUEST_GET_DESCRIPTOR, + .wValue = 0, + .wIndex = 0, + .wLength = sizeof(descriptor_hub_desc_t) }, - .bRequest = HUB_REQUEST_GET_DESCRIPTOR, - .wValue = 0, - .wIndex = 0, - .wLength = sizeof(descriptor_hub_desc_t) + + .buffer = _hub_buffer, + .complete_cb = config_set_port_power, + .user_arg = 0 }; - TU_ASSERT( tuh_control_xfer(dev_addr, &request, _hub_buffer, config_set_port_power) ); + TU_ASSERT( tuh_control_xfer(dev_addr, &xfer) ); return true; } -static bool config_set_port_power (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +static bool config_set_port_power (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { - (void) request; + (void) xfer; TU_ASSERT(XFER_RESULT_SUCCESS == result); hub_interface_t* p_hub = get_itf(dev_addr); @@ -246,12 +274,12 @@ static bool config_set_port_power (uint8_t dev_addr, tusb_control_request_t cons return hub_port_set_feature(dev_addr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete); } -static bool config_port_power_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +static bool config_port_power_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { TU_ASSERT(XFER_RESULT_SUCCESS == result); hub_interface_t* p_hub = get_itf(dev_addr); - if (request->wIndex == p_hub->port_count) + if (xfer->request.wIndex == p_hub->port_count) { // All ports are power -> queue notification status endpoint and // complete the SET CONFIGURATION @@ -261,7 +289,7 @@ static bool config_port_power_complete (uint8_t dev_addr, tusb_control_request_t }else { // power next port - uint8_t const hub_port = (uint8_t) (request->wIndex + 1); + uint8_t const hub_port = (uint8_t) (xfer->request.wIndex + 1); return hub_port_set_feature(dev_addr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete); } @@ -272,9 +300,9 @@ static bool config_port_power_complete (uint8_t dev_addr, tusb_control_request_t // Connection Changes //--------------------------------------------------------------------+ -static bool connection_get_status_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); -static bool connection_clear_conn_change_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); -static bool connection_port_reset_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +static bool connection_get_status_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); +static bool connection_clear_conn_change_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); +static bool connection_port_reset_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); // callback as response of interrupt endpoint polling bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) @@ -302,12 +330,12 @@ bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32 return true; } -static bool connection_get_status_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +static bool connection_get_status_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { TU_ASSERT(result == XFER_RESULT_SUCCESS); hub_interface_t* p_hub = get_itf(dev_addr); - uint8_t const port_num = (uint8_t) request->wIndex; + uint8_t const port_num = (uint8_t) xfer->request.wIndex; // Connection change if (p_hub->port_status.change.connection) @@ -330,12 +358,12 @@ static bool connection_get_status_complete (uint8_t dev_addr, tusb_control_reque return true; } -static bool connection_clear_conn_change_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +static bool connection_clear_conn_change_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { TU_ASSERT(result == XFER_RESULT_SUCCESS); hub_interface_t* p_hub = get_itf(dev_addr); - uint8_t const port_num = (uint8_t) request->wIndex; + uint8_t const port_num = (uint8_t) xfer->request.wIndex; if ( p_hub->port_status.status.connection ) { @@ -361,12 +389,12 @@ static bool connection_clear_conn_change_complete (uint8_t dev_addr, tusb_contro return true; } -static bool connection_port_reset_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +static bool connection_port_reset_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { TU_ASSERT(result == XFER_RESULT_SUCCESS); // hub_interface_t* p_hub = get_itf(dev_addr); - uint8_t const port_num = (uint8_t) request->wIndex; + uint8_t const port_num = (uint8_t) xfer->request.wIndex; // submit attach event hcd_event_t event = diff --git a/src/host/hub.h b/src/host/hub.h index 6d81f6773..a5d8704d3 100644 --- a/src/host/hub.h +++ b/src/host/hub.h @@ -171,11 +171,11 @@ typedef struct { TU_VERIFY_STATIC( sizeof(hub_port_status_response_t) == 4, "size is not correct"); -bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_control_complete_cb_t complete_cb); -bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_control_complete_cb_t complete_cb); +bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_control_xfer_cb_t complete_cb); +bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_control_xfer_cb_t complete_cb); -bool hub_port_reset(uint8_t hub_addr, uint8_t hub_port, tuh_control_complete_cb_t complete_cb); -bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, tuh_control_complete_cb_t complete_cb); +bool hub_port_reset(uint8_t hub_addr, uint8_t hub_port, tuh_control_xfer_cb_t complete_cb); +bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, tuh_control_xfer_cb_t complete_cb); bool hub_edpt_status_xfer(uint8_t dev_addr); //--------------------------------------------------------------------+ diff --git a/src/host/usbh.c b/src/host/usbh.c index 617aff79a..a8692c8e5 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -111,15 +111,6 @@ typedef struct { } usbh_device_t; -typedef struct -{ - tusb_control_request_t request TU_ATTR_ALIGNED(4); - uint8_t* buffer; - tuh_control_complete_cb_t complete_cb; - - uint8_t daddr; -} usbh_control_xfer_t; - //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ @@ -250,7 +241,8 @@ static uint8_t _usbh_ctrl_buf[CFG_TUH_ENUMERATION_BUFSIZE]; // We will only execute control transfer one at a time. struct { - usbh_control_xfer_t xfer; + tuh_control_xfer_t xfer; + uint8_t daddr; // device address that is transferring uint8_t stage; }_ctrl_xfer; @@ -308,132 +300,165 @@ void osal_task_delay(uint32_t msec) // Descriptors //--------------------------------------------------------------------+ -bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len, + tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { - tusb_control_request_t const request = + tuh_control_xfer_t const xfer = { - .bmRequestType_bit = + .request = { - .recipient = TUSB_REQ_RCPT_DEVICE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_IN + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_IN + }, + .bRequest = TUSB_REQ_GET_DESCRIPTOR, + .wValue = tu_htole16( TU_U16(type, index) ), + .wIndex = 0, + .wLength = tu_htole16(len) }, - .bRequest = TUSB_REQ_GET_DESCRIPTOR, - .wValue = tu_htole16( TU_U16(type, index) ), - .wIndex = 0, - .wLength = tu_htole16(len) + + .buffer = buffer, + .complete_cb = complete_cb, + .user_arg = user_arg }; - TU_ASSERT( tuh_control_xfer(daddr, &request, buffer, complete_cb) ); - - return true; + return tuh_control_xfer(daddr, &xfer); } -bool tuh_descriptor_get_device(uint8_t daddr, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +bool tuh_descriptor_get_device(uint8_t daddr, void* buffer, uint16_t len, + tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { len = tu_min16(len, sizeof(tusb_desc_device_t)); - return tuh_descriptor_get(daddr, TUSB_DESC_DEVICE, 0, buffer, len, complete_cb); + return tuh_descriptor_get(daddr, TUSB_DESC_DEVICE, 0, buffer, len, complete_cb, user_arg); } -bool tuh_descriptor_get_configuration(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +bool tuh_descriptor_get_configuration(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, + tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { - return tuh_descriptor_get(daddr, TUSB_DESC_CONFIGURATION, index, buffer, len, complete_cb); + return tuh_descriptor_get(daddr, TUSB_DESC_CONFIGURATION, index, buffer, len, complete_cb, user_arg); } -bool tuh_descriptor_get_string(uint8_t daddr, uint16_t language_id, uint8_t index, - void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +bool tuh_descriptor_get_string(uint8_t daddr, uint16_t language_id, uint8_t index, void* buffer, uint16_t len, + tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { - tusb_control_request_t const request = + tuh_control_xfer_t const xfer = { - .bmRequestType_bit = + .request = { - .recipient = TUSB_REQ_RCPT_DEVICE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_IN + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_IN + }, + .bRequest = TUSB_REQ_GET_DESCRIPTOR, + .wValue = tu_htole16( TU_U16(TUSB_DESC_STRING, index) ), + .wIndex = tu_htole16(language_id), + .wLength = tu_htole16(len) }, - .bRequest = TUSB_REQ_GET_DESCRIPTOR, - .wValue = tu_htole16( TU_U16(TUSB_DESC_STRING, index) ), - .wIndex = tu_htole16(language_id), - .wLength = tu_htole16(len) + + .buffer = buffer, + .complete_cb = complete_cb, + .user_arg = user_arg }; - TU_ASSERT( tuh_control_xfer(daddr, &request, buffer, complete_cb) ); - return true; + return tuh_control_xfer(daddr, &xfer); } // Get manufacturer string descriptor -bool tuh_descriptor_get_manufacturer_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +bool tuh_descriptor_get_manufacturer_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, + tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { TU_VERIFY(tuh_mounted(daddr)); usbh_device_t const* dev = get_device(daddr); if (dev->i_manufacturer == 0) { return false; } - return tuh_descriptor_get_string(daddr, language_id, dev->i_manufacturer, buffer, len, complete_cb); + return tuh_descriptor_get_string(daddr, language_id, dev->i_manufacturer, buffer, len, complete_cb, user_arg); } // Get product string descriptor -bool tuh_descriptor_get_product_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +bool tuh_descriptor_get_product_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, + tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { TU_VERIFY(tuh_mounted(daddr)); usbh_device_t const* dev = get_device(daddr); if (dev->i_product == 0) { return false; } - return tuh_descriptor_get_string(daddr, language_id, dev->i_product, buffer, len, complete_cb); + return tuh_descriptor_get_string(daddr, language_id, dev->i_product, buffer, len, complete_cb, user_arg); } // Get serial string descriptor -bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, + tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { TU_VERIFY(tuh_mounted(daddr)); usbh_device_t const* dev = get_device(daddr); if (dev->i_serial == 0) { return false; } - return tuh_descriptor_get_string(daddr, language_id, dev->i_serial, buffer, len, complete_cb); + return tuh_descriptor_get_string(daddr, language_id, dev->i_serial, buffer, len, complete_cb, user_arg); } // Get HID report descriptor -bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, void* buffer, uint16_t len, + tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { TU_LOG2("HID Get Report Descriptor\r\n"); - tusb_control_request_t const request = + tuh_control_xfer_t const xfer = { - .bmRequestType_bit = + .request = { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_IN + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_IN + }, + .bRequest = TUSB_REQ_GET_DESCRIPTOR, + .wValue = tu_htole16(TU_U16(desc_type, 0)), + .wIndex = itf_num, + .wLength = len }, - .bRequest = TUSB_REQ_GET_DESCRIPTOR, - .wValue = tu_htole16(TU_U16(desc_type, 0)), - .wIndex = itf_num, - .wLength = len + + .buffer = buffer, + .complete_cb = complete_cb, + .user_arg = user_arg }; - return tuh_control_xfer(daddr, &request, buffer, complete_cb); + return tuh_control_xfer(daddr, &xfer); } -bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, tuh_control_complete_cb_t complete_cb) +bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, + tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { TU_LOG2("Set Configuration = %d\r\n", config_num); - tusb_control_request_t const request = + + tuh_control_xfer_t const xfer = { - .bmRequestType_bit = + .request = { - .recipient = TUSB_REQ_RCPT_DEVICE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_OUT + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_OUT + }, + .bRequest = TUSB_REQ_SET_CONFIGURATION, + .wValue = tu_htole16(config_num), + .wIndex = 0, + .wLength = 0 }, - .bRequest = TUSB_REQ_SET_CONFIGURATION, - .wValue = tu_htole16(config_num), - .wIndex = 0, - .wLength = 0 + + .buffer = NULL, + .complete_cb = complete_cb, + .user_arg = user_arg }; - TU_ASSERT( tuh_control_xfer(daddr, &request, NULL, complete_cb) ); - return true; + return tuh_control_xfer(daddr, &xfer); } //--------------------------------------------------------------------+ @@ -460,7 +485,7 @@ bool tuh_init(uint8_t rhport) TU_LOG2("USBH init\r\n"); TU_LOG2_INT(sizeof(usbh_device_t)); TU_LOG2_INT(sizeof(hcd_event_t)); - TU_LOG2_INT(sizeof(usbh_control_xfer_t)); + TU_LOG2_INT(sizeof(tuh_control_xfer_t)); // Event queue _usbh_q = osal_queue_create( &_usbh_qdef ); @@ -808,7 +833,7 @@ bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) // Control transfer //--------------------------------------------------------------------+ -bool tuh_control_xfer (uint8_t daddr, tusb_control_request_t const* request, void* buffer, tuh_control_complete_cb_t complete_cb) +bool tuh_control_xfer (uint8_t daddr, tuh_control_xfer_t const* xfer) { // pre-check to help reducing mutex lock TU_VERIFY(_ctrl_xfer.stage == CONTROL_STAGE_IDLE); @@ -824,16 +849,13 @@ bool tuh_control_xfer (uint8_t daddr, tusb_control_request_t const* request, voi const uint8_t rhport = usbh_get_rhport(daddr); - TU_LOG2("[%u:%u] %s: ", rhport, daddr, request->bRequest <= TUSB_REQ_SYNCH_FRAME ? tu_str_std_request[request->bRequest] : "Unknown Request"); - TU_LOG2_VAR(request); + TU_LOG2("[%u:%u] %s: ", rhport, daddr, xfer->request.bRequest <= TUSB_REQ_SYNCH_FRAME ? tu_str_std_request[xfer->request.bRequest] : "Unknown Request"); + TU_LOG2_VAR(&xfer->request); TU_LOG2("\r\n"); - _ctrl_xfer.xfer.request = (*request); - _ctrl_xfer.xfer.buffer = buffer; - _ctrl_xfer.xfer.complete_cb = complete_cb; - _ctrl_xfer.xfer.daddr = daddr; - - return hcd_setup_send(rhport, daddr, (uint8_t const*) &_ctrl_xfer.xfer.request); + _ctrl_xfer.daddr = daddr; + _ctrl_xfer.xfer = (*xfer); + return hcd_setup_send(rhport, daddr, (uint8_t*) &_ctrl_xfer.xfer.request); } TU_ATTR_ALWAYS_INLINE static inline void set_control_xfer_stage(uint8_t stage) @@ -851,7 +873,12 @@ static void _xfer_complete(uint8_t dev_addr, xfer_result_t result) _ctrl_xfer.stage = CONTROL_STAGE_IDLE; usbh_unlock(); - if (_ctrl_xfer.xfer.complete_cb) _ctrl_xfer.xfer.complete_cb(dev_addr, &_ctrl_xfer.xfer.request, result); + if (_ctrl_xfer.xfer.complete_cb) + { + // duplicate xfer since user can execute control transfer within callback + tuh_control_xfer_t const xfer_temp = _ctrl_xfer.xfer; + _ctrl_xfer.xfer.complete_cb(dev_addr, &xfer_temp, result); + } } static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) @@ -939,7 +966,7 @@ static void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t h hcd_device_close(rhport, dev_addr); clear_device(dev); // abort on-going control xfer if any - if (_ctrl_xfer.xfer.daddr == dev_addr) set_control_xfer_stage(CONTROL_STAGE_IDLE); + if (_ctrl_xfer.daddr == dev_addr) set_control_xfer_stage(CONTROL_STAGE_IDLE); } } } @@ -954,14 +981,14 @@ static void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t h //--------------------------------------------------------------------+ static bool enum_request_addr0_device_desc(void); -static bool enum_get_addr0_device_desc_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +static bool enum_get_addr0_device_desc_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); static bool enum_request_set_addr(void); -static bool enum_set_address_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); -static bool enum_get_device_desc_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); -static bool enum_get_9byte_config_desc_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); -static bool enum_get_config_desc_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); -static bool enum_set_config_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +static bool enum_set_address_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); +static bool enum_get_device_desc_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); +static bool enum_get_9byte_config_desc_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); +static bool enum_get_config_desc_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); +static bool enum_set_config_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); static bool parse_configuration_descriptor (uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg); static uint8_t get_new_address(bool is_hub); @@ -973,15 +1000,15 @@ static void enum_full_complete(void); // New device (reset on the way) -> Get Status 0 -> Clear Reset 0 -> Get 8byte Device Descriptor // -> Port Reset 1 -> reset delay -> Get Status 1 -> Clear Reset 1 -> queue hub interrupt endpoint -static bool enum_hub_get_status0_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); -static bool enum_hub_clear_reset0_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); -static bool enum_hub_set_reset1_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); -static bool enum_hub_get_status1_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); -static bool enum_hub_clear_reset1_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +static bool enum_hub_get_status0_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); +static bool enum_hub_clear_reset0_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); +static bool enum_hub_set_reset1_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); +static bool enum_hub_get_status1_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); +static bool enum_hub_clear_reset1_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); -static bool enum_hub_get_status0_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +static bool enum_hub_get_status0_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { - (void) dev_addr; (void) request; + (void) dev_addr; (void) xfer; TU_ASSERT(XFER_RESULT_SUCCESS == result); hub_port_status_response_t port_status; @@ -1006,17 +1033,17 @@ static bool enum_hub_get_status0_complete(uint8_t dev_addr, tusb_control_request return true; } -static bool enum_hub_clear_reset0_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +static bool enum_hub_clear_reset0_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { - (void) dev_addr; (void) request; + (void) dev_addr; (void) xfer; TU_ASSERT(XFER_RESULT_SUCCESS == result); enum_request_addr0_device_desc(); return true; } -static bool enum_hub_set_reset1_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +static bool enum_hub_set_reset1_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { - (void) dev_addr; (void) request; + (void) dev_addr; (void) xfer; TU_ASSERT(XFER_RESULT_SUCCESS == result); osal_task_delay(RESET_DELAY); @@ -1026,9 +1053,9 @@ static bool enum_hub_set_reset1_complete(uint8_t dev_addr, tusb_control_request_ return true; } -static bool enum_hub_get_status1_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +static bool enum_hub_get_status1_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { - (void) dev_addr; (void) request; + (void) dev_addr; (void) xfer; TU_ASSERT(XFER_RESULT_SUCCESS == result); hub_port_status_response_t port_status; @@ -1043,9 +1070,9 @@ static bool enum_hub_get_status1_complete(uint8_t dev_addr, tusb_control_request return true; } -static bool enum_hub_clear_reset1_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +static bool enum_hub_clear_reset1_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { - (void) dev_addr; (void) request; + (void) dev_addr; (void) xfer; TU_ASSERT(XFER_RESULT_SUCCESS == result); enum_request_set_addr(); @@ -1096,14 +1123,14 @@ static bool enum_request_addr0_device_desc(void) // Get first 8 bytes of device descriptor for Control Endpoint size TU_LOG2("Get 8 byte of Device Descriptor\r\n"); - TU_ASSERT(tuh_descriptor_get_device(addr0, _usbh_ctrl_buf, 8, enum_get_addr0_device_desc_complete)); + TU_ASSERT(tuh_descriptor_get_device(addr0, _usbh_ctrl_buf, 8, enum_get_addr0_device_desc_complete, 0)); return true; } // After Get Device Descriptor of Address 0 -static bool enum_get_addr0_device_desc_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +static bool enum_get_addr0_device_desc_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { - (void) request; + (void) xfer; TU_ASSERT(0 == dev_addr); if (XFER_RESULT_SUCCESS != result) @@ -1157,33 +1184,40 @@ static bool enum_request_set_addr(void) new_dev->connected = 1; new_dev->ep0_size = desc_device->bMaxPacketSize0; - tusb_control_request_t const new_request = + tuh_control_xfer_t const xfer = { - .bmRequestType_bit = + .request = { - .recipient = TUSB_REQ_RCPT_DEVICE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_OUT + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_OUT + }, + .bRequest = TUSB_REQ_SET_ADDRESS, + .wValue = tu_htole16(new_addr), + .wIndex = 0, + .wLength = 0 }, - .bRequest = TUSB_REQ_SET_ADDRESS, - .wValue = tu_htole16(new_addr), - .wIndex = 0, - .wLength = 0 + + .buffer = NULL, + .complete_cb = enum_set_address_complete, + .user_arg = 0 }; uint8_t const addr0 = 0; - TU_ASSERT( tuh_control_xfer(addr0, &new_request, NULL, enum_set_address_complete) ); + TU_ASSERT( tuh_control_xfer(addr0, &xfer) ); return true; } // After SET_ADDRESS is complete -static bool enum_set_address_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +static bool enum_set_address_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { TU_ASSERT(0 == dev_addr); TU_ASSERT(XFER_RESULT_SUCCESS == result); - uint8_t const new_addr = (uint8_t const) request->wValue; + uint8_t const new_addr = (uint8_t const) xfer->request.wValue; usbh_device_t* new_dev = get_device(new_addr); new_dev->addressed = 1; @@ -1197,13 +1231,13 @@ static bool enum_set_address_complete(uint8_t dev_addr, tusb_control_request_t c // Get full device descriptor TU_LOG2("Get Device Descriptor\r\n"); - TU_ASSERT(tuh_descriptor_get_device(new_addr, _usbh_ctrl_buf, sizeof(tusb_desc_device_t), enum_get_device_desc_complete)); + TU_ASSERT(tuh_descriptor_get_device(new_addr, _usbh_ctrl_buf, sizeof(tusb_desc_device_t), enum_get_device_desc_complete, 0)); return true; } -static bool enum_get_device_desc_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +static bool enum_get_device_desc_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { - (void) request; + (void) xfer; TU_ASSERT(XFER_RESULT_SUCCESS == result); tusb_desc_device_t const * desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; @@ -1220,13 +1254,13 @@ static bool enum_get_device_desc_complete(uint8_t dev_addr, tusb_control_request // Get 9-byte for total length uint8_t const config_idx = CONFIG_NUM - 1; TU_LOG2("Get Configuration[0] Descriptor (9 bytes)\r\n"); - TU_ASSERT( tuh_descriptor_get_configuration(dev_addr, config_idx, _usbh_ctrl_buf, 9, enum_get_9byte_config_desc_complete) ); + TU_ASSERT( tuh_descriptor_get_configuration(dev_addr, config_idx, _usbh_ctrl_buf, 9, enum_get_9byte_config_desc_complete, 0) ); return true; } -static bool enum_get_9byte_config_desc_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +static bool enum_get_9byte_config_desc_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { - (void) request; + (void) xfer; TU_ASSERT(XFER_RESULT_SUCCESS == result); // TODO not enough buffer to hold configuration descriptor @@ -1240,26 +1274,26 @@ static bool enum_get_9byte_config_desc_complete(uint8_t dev_addr, tusb_control_r // Get full configuration descriptor uint8_t const config_idx = CONFIG_NUM - 1; TU_LOG2("Get Configuration[0] Descriptor\r\n"); - TU_ASSERT( tuh_descriptor_get_configuration(dev_addr, config_idx, _usbh_ctrl_buf, total_len, enum_get_config_desc_complete) ); + TU_ASSERT( tuh_descriptor_get_configuration(dev_addr, config_idx, _usbh_ctrl_buf, total_len, enum_get_config_desc_complete, 0) ); return true; } -static bool enum_get_config_desc_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +static bool enum_get_config_desc_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { - (void) request; + (void) xfer; TU_ASSERT(XFER_RESULT_SUCCESS == result); // Parse configuration & set up drivers // Driver open aren't allowed to make any usb transfer yet TU_ASSERT( parse_configuration_descriptor(dev_addr, (tusb_desc_configuration_t*) _usbh_ctrl_buf) ); - TU_ASSERT( tuh_configuration_set(dev_addr, CONFIG_NUM, enum_set_config_complete) ); + TU_ASSERT( tuh_configuration_set(dev_addr, CONFIG_NUM, enum_set_config_complete, 0) ); return true; } -static bool enum_set_config_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +static bool enum_set_config_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { - (void) request; + (void) xfer; TU_ASSERT(XFER_RESULT_SUCCESS == result); TU_LOG2("Device configured\r\n"); diff --git a/src/host/usbh.h b/src/host/usbh.h index eec2ed702..d836d9593 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -38,7 +38,19 @@ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -typedef bool (*tuh_control_complete_cb_t)(uint8_t daddr, tusb_control_request_t const * request, xfer_result_t result); +// forward declaration +struct tuh_control_xfer_s; +typedef struct tuh_control_xfer_s tuh_control_xfer_t; + +typedef bool (*tuh_control_xfer_cb_t)(uint8_t daddr, tuh_control_xfer_t const * xfer, xfer_result_t result); + +struct tuh_control_xfer_s +{ + tusb_control_request_t request TU_ATTR_ALIGNED(4); + uint8_t* buffer; + tuh_control_xfer_cb_t complete_cb; + uintptr_t user_arg; +}; //--------------------------------------------------------------------+ // APPLICATION API @@ -81,40 +93,54 @@ static inline bool tuh_ready(uint8_t daddr) } // Carry out a control transfer -// true on success, false if there is on-going control trasnfer -bool tuh_control_xfer (uint8_t daddr, tusb_control_request_t const* request, void* buffer, tuh_control_complete_cb_t complete_cb); +// true on success, false if there is on-going control transfer +// Note: function is blocking if complete callback is NULL +bool tuh_control_xfer (uint8_t daddr, tuh_control_xfer_t const* xfer); + +// Carry out a control transfer +// true on success, false if there is on-going control transfer +// Note: function is blocking if complete callback is NULL +//bool tuh_control_xfer (uint8_t daddr, tusb_control_request_t const* request, void* buffer, +// tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); // Set Configuration // config_num = 0 will un-configure device. Note: config_num = config_descriptor_index + 1 -bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, tuh_control_complete_cb_t complete_cb); +bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, + tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); //------------- descriptors -------------// // Get an descriptor -bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, - void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); +bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len, + tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); // Get device descriptor -bool tuh_descriptor_get_device(uint8_t daddr, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); +bool tuh_descriptor_get_device(uint8_t daddr, void* buffer, uint16_t len, + tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); // Get configuration descriptor -bool tuh_descriptor_get_configuration(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); - -// Get string descriptor -bool tuh_descriptor_get_string(uint8_t daddr, uint16_t language_id, uint8_t index, - void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); - -// Get manufacturer string descriptor -bool tuh_descriptor_get_manufacturer_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); - -// Get product string descriptor -bool tuh_descriptor_get_product_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); - -// Get serial string descriptor -bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); +bool tuh_descriptor_get_configuration(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, + tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); // Get HID report descriptor -bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); +bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, void* buffer, uint16_t len, + tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); + +// Get string descriptor +bool tuh_descriptor_get_string(uint8_t daddr, uint16_t language_id, uint8_t index, void* buffer, uint16_t len, + tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); + +// Get manufacturer string descriptor +bool tuh_descriptor_get_manufacturer_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, + tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); + +// Get product string descriptor +bool tuh_descriptor_get_product_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, + tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); + +// Get serial string descriptor +bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, + tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); //--------------------------------------------------------------------+ // APPLICATION CALLBACK From ec28593ce56a9a1726cfe8a43f6a8c421fd3916b Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 11 Mar 2022 22:13:57 +0700 Subject: [PATCH 232/504] update hid,msc to new usbh control API --- examples/host/cdc_msc_hid/src/main.c | 27 +++-- src/class/cdc/cdc_host.c | 29 ++++-- src/class/hid/hid_host.c | 148 ++++++++++++++++----------- src/class/msc/msc_host.c | 33 +++--- 4 files changed, 139 insertions(+), 98 deletions(-) diff --git a/examples/host/cdc_msc_hid/src/main.c b/examples/host/cdc_msc_hid/src/main.c index a14be05ea..0fc7ef146 100644 --- a/examples/host/cdc_msc_hid/src/main.c +++ b/examples/host/cdc_msc_hid/src/main.c @@ -71,20 +71,6 @@ int main(void) #if CFG_TUH_CDC CFG_TUSB_MEM_SECTION static char serial_in_buffer[64] = { 0 }; -void tuh_mount_cb(uint8_t dev_addr) -{ - // application set-up - printf("A device with address %d is mounted\r\n", dev_addr); - - tuh_cdc_receive(dev_addr, serial_in_buffer, sizeof(serial_in_buffer), true); // schedule first transfer -} - -void tuh_umount_cb(uint8_t dev_addr) -{ - // application tear-down - printf("A device with address %d is unmounted \r\n", dev_addr); -} - // invoked ISR context void tuh_cdc_xfer_isr(uint8_t dev_addr, xfer_result_t event, cdc_pipeid_t pipe_id, uint32_t xferred_bytes) { @@ -109,6 +95,19 @@ void cdc_task(void) // TinyUSB Callbacks //--------------------------------------------------------------------+ +void tuh_mount_cb(uint8_t dev_addr) +{ + // application set-up + printf("A device with address %d is mounted\r\n", dev_addr); +} + +void tuh_umount_cb(uint8_t dev_addr) +{ + // application tear-down + printf("A device with address %d is unmounted \r\n", dev_addr); +} + + //--------------------------------------------------------------------+ // Blinking Task //--------------------------------------------------------------------+ diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 6a29f3f43..8ca3dfbcb 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -123,22 +123,29 @@ bool tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_control_xfer_cb_t complete_cb) { cdch_data_t const * p_cdc = get_itf(dev_addr); - tusb_control_request_t const request = + + tuh_control_xfer_t const xfer = { - .bmRequestType_bit = + .request = { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_OUT + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = CDC_REQUEST_SET_CONTROL_LINE_STATE, + .wValue = (rts ? 2 : 0) | (dtr ? 1 : 0), + .wIndex = p_cdc->itf_num, + .wLength = 0 }, - .bRequest = CDC_REQUEST_SET_CONTROL_LINE_STATE, - .wValue = (rts ? 2 : 0) | (dtr ? 1 : 0), - .wIndex = p_cdc->itf_num, - .wLength = 0 + + .buffer = NULL, + .complete_cb = complete_cb, + .user_arg = 0 }; - TU_ASSERT( tuh_control_xfer(dev_addr, &request, NULL, complete_cb) ); - return true; + return tuh_control_xfer(dev_addr, &xfer); } //--------------------------------------------------------------------+ diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 323debe69..4de3551c2 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -103,13 +103,13 @@ uint8_t tuh_hid_get_protocol(uint8_t dev_addr, uint8_t instance) return hid_itf->protocol_mode; } -static bool set_protocol_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +static bool set_protocol_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { - uint8_t const itf_num = (uint8_t) request->wIndex; + uint8_t const itf_num = (uint8_t) xfer->request.wIndex; uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); hidh_interface_t* hid_itf = get_instance(dev_addr, instance); - if (XFER_RESULT_SUCCESS == result) hid_itf->protocol_mode = (uint8_t) request->wValue; + if (XFER_RESULT_SUCCESS == result) hid_itf->protocol_mode = (uint8_t) xfer->request.wValue; if (tuh_hid_set_protocol_complete_cb) { @@ -126,37 +126,44 @@ bool tuh_hid_set_protocol(uint8_t dev_addr, uint8_t instance, uint8_t protocol) TU_LOG2("HID Set Protocol = %d\r\n", protocol); - tusb_control_request_t const request = + tuh_control_xfer_t const xfer = { - .bmRequestType_bit = + .request = { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_OUT + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HID_REQ_CONTROL_SET_PROTOCOL, + .wValue = protocol, + .wIndex = hid_itf->itf_num, + .wLength = 0 }, - .bRequest = HID_REQ_CONTROL_SET_PROTOCOL, - .wValue = protocol, - .wIndex = hid_itf->itf_num, - .wLength = 0 + + .buffer = NULL, + .complete_cb = set_protocol_complete, + .user_arg = 0 }; - TU_ASSERT( tuh_control_xfer(dev_addr, &request, NULL, set_protocol_complete) ); + TU_ASSERT( tuh_control_xfer(dev_addr, &xfer) ); return true; } -static bool set_report_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +static bool set_report_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { TU_LOG2("HID Set Report complete\r\n"); if (tuh_hid_set_report_complete_cb) { - uint8_t const itf_num = (uint8_t) request->wIndex; + uint8_t const itf_num = (uint8_t) xfer->request.wIndex; uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); - uint8_t const report_type = tu_u16_high(request->wValue); - uint8_t const report_id = tu_u16_low(request->wValue); + uint8_t const report_type = tu_u16_high(xfer->request.wValue); + uint8_t const report_id = tu_u16_low(xfer->request.wValue); - tuh_hid_set_report_complete_cb(dev_addr, instance, report_id, report_type, (result == XFER_RESULT_SUCCESS) ? request->wLength : 0); + tuh_hid_set_report_complete_cb(dev_addr, instance, report_id, report_type, (result == XFER_RESULT_SUCCESS) ? xfer->request.wLength : 0); } return true; @@ -167,21 +174,28 @@ bool tuh_hid_set_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, u hidh_interface_t* hid_itf = get_instance(dev_addr, instance); TU_LOG2("HID Set Report: id = %u, type = %u, len = %u\r\n", report_id, report_type, len); - tusb_control_request_t const request = + tuh_control_xfer_t const xfer = { - .bmRequestType_bit = + .request = { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_OUT + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HID_REQ_CONTROL_SET_REPORT, + .wValue = tu_u16(report_type, report_id), + .wIndex = hid_itf->itf_num, + .wLength = len }, - .bRequest = HID_REQ_CONTROL_SET_REPORT, - .wValue = tu_u16(report_type, report_id), - .wIndex = hid_itf->itf_num, - .wLength = len + + .buffer = report, + .complete_cb = set_report_complete, + .user_arg = 0 }; - TU_ASSERT( tuh_control_xfer(dev_addr, &request, report, set_report_complete) ); + TU_ASSERT( tuh_control_xfer(dev_addr, &xfer) ); return true; } @@ -256,9 +270,9 @@ void hidh_close(uint8_t dev_addr) // Enumeration //--------------------------------------------------------------------+ -static bool config_set_protocol (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); -static bool config_get_report_desc (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); -static bool config_get_report_desc_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +static bool config_set_protocol (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); +static bool config_get_report_desc (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); +static bool config_get_report_desc_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); static void config_driver_mount_complete(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len); @@ -337,65 +351,79 @@ bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num) // SET IDLE request, device can stall if not support this request TU_LOG2("HID Set Idle \r\n"); - tusb_control_request_t const request = + tuh_control_xfer_t const xfer = { - .bmRequestType_bit = + .request = { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_OUT + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HID_REQ_CONTROL_SET_IDLE, + .wValue = idle_rate, + .wIndex = itf_num, + .wLength = 0 }, - .bRequest = HID_REQ_CONTROL_SET_IDLE, - .wValue = idle_rate, - .wIndex = itf_num, - .wLength = 0 + + .buffer = NULL, + .complete_cb = (hid_itf->itf_protocol != HID_ITF_PROTOCOL_NONE) ? config_set_protocol : config_get_report_desc, + .user_arg = 0 }; - TU_ASSERT( tuh_control_xfer(dev_addr, &request, NULL, (hid_itf->itf_protocol != HID_ITF_PROTOCOL_NONE) ? config_set_protocol : config_get_report_desc) ); + TU_ASSERT( tuh_control_xfer(dev_addr, &xfer) ); return true; } // Force device to work in BOOT protocol -static bool config_set_protocol(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +static bool config_set_protocol(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { // Stall is a valid response for SET_IDLE, therefore we could ignore its result (void) result; - uint8_t const itf_num = (uint8_t) request->wIndex; + uint8_t const itf_num = (uint8_t) xfer->request.wIndex; uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); hidh_interface_t* hid_itf = get_instance(dev_addr, instance); TU_LOG2("HID Set Protocol to Boot Mode\r\n"); hid_itf->protocol_mode = HID_PROTOCOL_BOOT; - tusb_control_request_t const new_request = + tuh_control_xfer_t const new_xfer = { - .bmRequestType_bit = + .request = { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_OUT + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HID_REQ_CONTROL_SET_PROTOCOL, + .wValue = HID_PROTOCOL_BOOT, + .wIndex = hid_itf->itf_num, + .wLength = 0 }, - .bRequest = HID_REQ_CONTROL_SET_PROTOCOL, - .wValue = HID_PROTOCOL_BOOT, - .wIndex = hid_itf->itf_num, - .wLength = 0 + + .buffer = NULL, + .complete_cb = config_get_report_desc, + .user_arg = 0 }; - TU_ASSERT( tuh_control_xfer(dev_addr, &new_request, NULL, config_get_report_desc) ); + TU_ASSERT( tuh_control_xfer(dev_addr, &new_xfer) ); return true; } -static bool config_get_report_desc(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +static bool config_get_report_desc(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { // We can be here after SET_IDLE or SET_PROTOCOL (boot device) // Trigger assert if result is not successful with set protocol - if ( request->bRequest != HID_REQ_CONTROL_SET_IDLE ) + if ( xfer->request.bRequest != HID_REQ_CONTROL_SET_IDLE ) { TU_ASSERT(result == XFER_RESULT_SUCCESS); } - uint8_t const itf_num = (uint8_t) request->wIndex; + uint8_t const itf_num = (uint8_t) xfer->request.wIndex; uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); hidh_interface_t* hid_itf = get_instance(dev_addr, instance); @@ -409,21 +437,21 @@ static bool config_get_report_desc(uint8_t dev_addr, tusb_control_request_t cons config_driver_mount_complete(dev_addr, instance, NULL, 0); }else { - TU_ASSERT(tuh_descriptor_get_hid_report(dev_addr, itf_num, hid_itf->report_desc_type, usbh_get_enum_buf(), hid_itf->report_desc_len, config_get_report_desc_complete)); + TU_ASSERT(tuh_descriptor_get_hid_report(dev_addr, itf_num, hid_itf->report_desc_type, usbh_get_enum_buf(), hid_itf->report_desc_len, config_get_report_desc_complete, 0)); } return true; } -static bool config_get_report_desc_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +static bool config_get_report_desc_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { TU_ASSERT(XFER_RESULT_SUCCESS == result); - uint8_t const itf_num = (uint8_t) request->wIndex; + uint8_t const itf_num = (uint8_t) xfer->request.wIndex; uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); uint8_t const* desc_report = usbh_get_enum_buf(); - uint16_t const desc_len = request->wLength; + uint16_t const desc_len = xfer->request.wLength; config_driver_mount_complete(dev_addr, instance, desc_report, desc_len); diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index e4239e375..c009e5088 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -358,7 +358,7 @@ bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32 // MSC Enumeration //--------------------------------------------------------------------+ -static bool config_get_maxlun_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +static bool config_get_maxlun_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); static bool config_test_unit_ready_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); static bool config_request_sense_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); static bool config_read_capacity_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); @@ -405,27 +405,34 @@ bool msch_set_config(uint8_t dev_addr, uint8_t itf_num) //------------- Get Max Lun -------------// TU_LOG2("MSC Get Max Lun\r\n"); - tusb_control_request_t request = + tuh_control_xfer_t const xfer = { - .bmRequestType_bit = + .request = { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_IN + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN + }, + .bRequest = MSC_REQ_GET_MAX_LUN, + .wValue = 0, + .wIndex = itf_num, + .wLength = 1 }, - .bRequest = MSC_REQ_GET_MAX_LUN, - .wValue = 0, - .wIndex = itf_num, - .wLength = 1 + + .buffer = &p_msc->max_lun, + .complete_cb = config_get_maxlun_complete, + .user_arg = 0 }; - TU_ASSERT(tuh_control_xfer(dev_addr, &request, &p_msc->max_lun, config_get_maxlun_complete)); + TU_ASSERT(tuh_control_xfer(dev_addr, &xfer)); return true; } -static bool config_get_maxlun_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +static bool config_get_maxlun_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { - (void) request; + (void) xfer; msch_interface_t* p_msc = get_itf(dev_addr); From a5a565f7eb85c4d1ad43d74b1baf1f61dcf0a5b5 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 12 Mar 2022 14:20:57 +0700 Subject: [PATCH 233/504] rework usbh enumeration process using user arg from control transfer as state --- src/host/hub.c | 30 ++-- src/host/hub.h | 31 +++- src/host/usbh.c | 456 ++++++++++++++++++++++-------------------------- 3 files changed, 251 insertions(+), 266 deletions(-) diff --git a/src/host/hub.c b/src/host/hub.c index a0cf7b7e5..c1909cb5c 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -77,7 +77,8 @@ static char const* const _hub_feature_str[] = //--------------------------------------------------------------------+ // HUB //--------------------------------------------------------------------+ -bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_control_xfer_cb_t complete_cb) +bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, + tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { tuh_control_xfer_t const xfer = { @@ -97,7 +98,7 @@ bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, .buffer = NULL, .complete_cb = complete_cb, - .user_arg = 0 + .user_arg = user_arg }; TU_LOG2("HUB Clear Feature: %s, addr = %u port = %u\r\n", _hub_feature_str[feature], hub_addr, hub_port); @@ -105,7 +106,8 @@ bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, return true; } -bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_control_xfer_cb_t complete_cb) +bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, + tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { tuh_control_xfer_t const xfer = { @@ -125,7 +127,7 @@ bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, t .buffer = NULL, .complete_cb = complete_cb, - .user_arg = 0 + .user_arg = user_arg }; TU_LOG2("HUB Set Feature: %s, addr = %u port = %u\r\n", _hub_feature_str[feature], hub_addr, hub_port); @@ -133,12 +135,8 @@ bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, t return true; } -bool hub_port_reset(uint8_t hub_addr, uint8_t hub_port, tuh_control_xfer_cb_t complete_cb) -{ - return hub_port_set_feature(hub_addr, hub_port, HUB_FEATURE_PORT_RESET, complete_cb); -} - -bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, tuh_control_xfer_cb_t complete_cb) +bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, + tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { tuh_control_xfer_t const xfer = { @@ -158,7 +156,7 @@ bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, tuh_con .buffer = resp, .complete_cb = complete_cb, - .user_arg = 0 + .user_arg = user_arg }; TU_LOG2("HUB Get Port Status: addr = %u port = %u\r\n", hub_addr, hub_port); @@ -271,7 +269,7 @@ static bool config_set_port_power (uint8_t dev_addr, tuh_control_xfer_t const * // Set Port Power to be able to detect connection, starting with port 1 uint8_t const hub_port = 1; - return hub_port_set_feature(dev_addr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete); + return hub_port_set_feature(dev_addr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete, 0); } static bool config_port_power_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) @@ -290,7 +288,7 @@ static bool config_port_power_complete (uint8_t dev_addr, tuh_control_xfer_t con { // power next port uint8_t const hub_port = (uint8_t) (xfer->request.wIndex + 1); - return hub_port_set_feature(dev_addr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete); + return hub_port_set_feature(dev_addr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete, 0); } return true; @@ -320,7 +318,7 @@ bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32 { if ( tu_bit_test(p_hub->status_change, port) ) { - hub_port_get_status(dev_addr, port, &p_hub->port_status, connection_get_status_complete); + hub_port_get_status(dev_addr, port, &p_hub->port_status, connection_get_status_complete, 0); break; } } @@ -344,7 +342,7 @@ static bool connection_get_status_complete (uint8_t dev_addr, tuh_control_xfer_t //TU_VERIFY(port_status.status_current.port_power && port_status.status_current.port_enable, ); // Acknowledge Port Connection Change - hub_port_clear_feature(dev_addr, port_num, HUB_FEATURE_PORT_CONNECTION_CHANGE, connection_clear_conn_change_complete); + hub_port_clear_feature(dev_addr, port_num, HUB_FEATURE_PORT_CONNECTION_CHANGE, connection_clear_conn_change_complete, 0); }else { // Other changes are: Enable, Suspend, Over Current, Reset, L1 state @@ -368,7 +366,7 @@ static bool connection_clear_conn_change_complete (uint8_t dev_addr, tuh_control if ( p_hub->port_status.status.connection ) { // Reset port if attach event - hub_port_reset(dev_addr, port_num, connection_port_reset_complete); + hub_port_reset(dev_addr, port_num, connection_port_reset_complete, 0); }else { // submit detach event diff --git a/src/host/hub.h b/src/host/hub.h index a5d8704d3..30cf3dd1c 100644 --- a/src/host/hub.h +++ b/src/host/hub.h @@ -171,13 +171,36 @@ typedef struct { TU_VERIFY_STATIC( sizeof(hub_port_status_response_t) == 4, "size is not correct"); -bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_control_xfer_cb_t complete_cb); -bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_control_xfer_cb_t complete_cb); +// Clear feature +bool hub_port_clear_feature (uint8_t hub_addr, uint8_t hub_port, uint8_t feature, + tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); -bool hub_port_reset(uint8_t hub_addr, uint8_t hub_port, tuh_control_xfer_cb_t complete_cb); -bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, tuh_control_xfer_cb_t complete_cb); +// Set feature +bool hub_port_set_feature (uint8_t hub_addr, uint8_t hub_port, uint8_t feature, + tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); + +// Get port status +bool hub_port_get_status (uint8_t hub_addr, uint8_t hub_port, void* resp, + tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); + +// Get status from Interrupt endpoint bool hub_edpt_status_xfer(uint8_t dev_addr); +// Reset a port +static inline bool hub_port_reset(uint8_t hub_addr, uint8_t hub_port, + tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) +{ + return hub_port_set_feature(hub_addr, hub_port, HUB_FEATURE_PORT_RESET, complete_cb, user_arg); +} + +// Clear Reset Change +static inline bool hub_port_clear_reset_change(uint8_t hub_addr, uint8_t hub_port, + tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) +{ + return hub_port_clear_feature(hub_addr, hub_port, HUB_FEATURE_PORT_RESET_CHANGE, complete_cb, user_arg); +} + + //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ diff --git a/src/host/usbh.c b/src/host/usbh.c index a8692c8e5..6c38c525e 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -974,114 +974,216 @@ static void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t h //--------------------------------------------------------------------+ // Enumeration Process // is a lengthy process with a series of control transfer to configure -// newly attached device. Each step is handled by a function in this -// section -// TODO due to the shared _usbh_ctrl_buf, we must complete enumerating +// newly attached device. +// NOTE: due to the shared _usbh_ctrl_buf, we must complete enumerating // one device before enumerating another one. //--------------------------------------------------------------------+ -static bool enum_request_addr0_device_desc(void); -static bool enum_get_addr0_device_desc_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); +enum { + ENUM_IDLE, + ENUM_RESET_1, // 1st reset when attached + //ENUM_HUB_GET_STATUS_1, + ENUM_HUB_CLEAR_RESET_1, + ENUM_ADDR0_DEVICE_DESC, + ENUM_RESET_2, // 2nd reset before set address + ENUM_HUB_GET_STATUS_2, + ENUM_HUB_CLEAR_RESET_2, + ENUM_SET_ADDR, + + ENUM_GET_DEVICE_DESC, + ENUM_GET_9BYTE_CONFIG_DESC, + ENUM_GET_FULL_CONFIG_DESC, + ENUM_SET_CONFIG, + ENUM_CONFIG_DRIVER +}; static bool enum_request_set_addr(void); -static bool enum_set_address_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); -static bool enum_get_device_desc_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); -static bool enum_get_9byte_config_desc_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); -static bool enum_get_config_desc_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); -static bool enum_set_config_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); static bool parse_configuration_descriptor (uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg); - -static uint8_t get_new_address(bool is_hub); static void enum_full_complete(void); -#if CFG_TUH_HUB - -// Enum sequence: -// New device (reset on the way) -> Get Status 0 -> Clear Reset 0 -> Get 8byte Device Descriptor -// -> Port Reset 1 -> reset delay -> Get Status 1 -> Clear Reset 1 -> queue hub interrupt endpoint - -static bool enum_hub_get_status0_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); -static bool enum_hub_clear_reset0_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); -static bool enum_hub_set_reset1_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); -static bool enum_hub_get_status1_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); -static bool enum_hub_clear_reset1_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); - -static bool enum_hub_get_status0_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) +// process device enumeration +static bool process_enumeration(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { - (void) dev_addr; (void) xfer; - TU_ASSERT(XFER_RESULT_SUCCESS == result); - - hub_port_status_response_t port_status; - memcpy(&port_status, _usbh_ctrl_buf, sizeof(hub_port_status_response_t)); - - if ( !port_status.status.connection ) + if (XFER_RESULT_SUCCESS != result) { - // device unplugged while delaying, nothing else to do, queue hub status + // stop enumeration, maybe we could retry this enum_full_complete(); return false; } - _dev0.speed = (port_status.status.high_speed) ? TUSB_SPEED_HIGH : - (port_status.status.low_speed ) ? TUSB_SPEED_LOW : TUSB_SPEED_FULL; + uint32_t const state = (uint32_t) xfer->user_arg; - // Acknowledge Port Reset Change - if (port_status.change.reset) + switch(state) { - hub_port_clear_feature(_dev0.hub_addr, _dev0.hub_port, HUB_FEATURE_PORT_RESET_CHANGE, enum_hub_clear_reset0_complete); +#if CFG_TUH_HUB + //case ENUM_HUB_GET_STATUS_1: break; + + case ENUM_HUB_CLEAR_RESET_1: + { + hub_port_status_response_t port_status; + memcpy(&port_status, _usbh_ctrl_buf, sizeof(hub_port_status_response_t)); + + if ( !port_status.status.connection ) + { + // device unplugged while delaying, nothing else to do + enum_full_complete(); + return false; + } + + _dev0.speed = (port_status.status.high_speed) ? TUSB_SPEED_HIGH : + (port_status.status.low_speed ) ? TUSB_SPEED_LOW : TUSB_SPEED_FULL; + + // Acknowledge Port Reset Change + if (port_status.change.reset) + { + hub_port_clear_reset_change(_dev0.hub_addr, _dev0.hub_port, process_enumeration, ENUM_ADDR0_DEVICE_DESC); + } + } + break; + + case ENUM_HUB_GET_STATUS_2: + osal_task_delay(RESET_DELAY); + TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, process_enumeration, ENUM_HUB_CLEAR_RESET_2) ); + break; + + case ENUM_HUB_CLEAR_RESET_2: + { + hub_port_status_response_t port_status; + memcpy(&port_status, _usbh_ctrl_buf, sizeof(hub_port_status_response_t)); + + // Acknowledge Port Reset Change if Reset Successful + if (port_status.change.reset) + { + TU_ASSERT( hub_port_clear_reset_change(_dev0.hub_addr, _dev0.hub_port, process_enumeration, ENUM_SET_ADDR) ); + } + } + break; +#endif + + case ENUM_ADDR0_DEVICE_DESC: + { + // TODO probably doesn't need to open/close each enumeration + uint8_t const addr0 = 0; + TU_ASSERT( usbh_edpt_control_open(addr0, 8) ); + + // Get first 8 bytes of device descriptor for Control Endpoint size + TU_LOG2("Get 8 byte of Device Descriptor\r\n"); + TU_ASSERT(tuh_descriptor_get_device(addr0, _usbh_ctrl_buf, 8, process_enumeration, ENUM_SET_ADDR)); + } + break; + + case ENUM_RESET_2: + // Reset device again before Set Address + TU_LOG2("Port reset \r\n"); + if (_dev0.hub_addr == 0) + { + // connected directly to roothub + hcd_port_reset( _dev0.rhport ); + osal_task_delay(RESET_DELAY); + + // TODO: fall through to SET ADDRESS, refactor later + } + #if CFG_TUH_HUB + else + { + // after RESET_DELAY the hub_port_reset() already complete + TU_ASSERT( hub_port_reset(_dev0.hub_addr, _dev0.hub_port, process_enumeration, ENUM_HUB_GET_STATUS_2) ); + break; + } + __attribute__((fallthrough)); + #endif + + case ENUM_SET_ADDR: + enum_request_set_addr(); + break; + + case ENUM_GET_DEVICE_DESC: + { + uint8_t const new_addr = (uint8_t const) xfer->request.wValue; + + usbh_device_t* new_dev = get_device(new_addr); + new_dev->addressed = 1; + + // TODO close device 0, may not be needed + hcd_device_close(_dev0.rhport, 0); + + // open control pipe for new address + TU_ASSERT( usbh_edpt_control_open(new_addr, new_dev->ep0_size) ); + + // Get full device descriptor + TU_LOG2("Get Device Descriptor\r\n"); + TU_ASSERT(tuh_descriptor_get_device(new_addr, _usbh_ctrl_buf, sizeof(tusb_desc_device_t), process_enumeration, ENUM_GET_9BYTE_CONFIG_DESC)); + } + break; + + case ENUM_GET_9BYTE_CONFIG_DESC: + { + tusb_desc_device_t const * desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; + usbh_device_t* dev = get_device(dev_addr); + + dev->vid = desc_device->idVendor; + dev->pid = desc_device->idProduct; + dev->i_manufacturer = desc_device->iManufacturer; + dev->i_product = desc_device->iProduct; + dev->i_serial = desc_device->iSerialNumber; + + // if (tuh_attach_cb) tuh_attach_cb((tusb_desc_device_t*) _usbh_ctrl_buf); + + // Get 9-byte for total length + uint8_t const config_idx = CONFIG_NUM - 1; + TU_LOG2("Get Configuration[0] Descriptor (9 bytes)\r\n"); + TU_ASSERT( tuh_descriptor_get_configuration(dev_addr, config_idx, _usbh_ctrl_buf, 9, process_enumeration, ENUM_GET_FULL_CONFIG_DESC) ); + } + break; + + case ENUM_GET_FULL_CONFIG_DESC: + { + uint8_t const * desc_config = _usbh_ctrl_buf; + + // Use offsetof to avoid pointer to the odd/misaligned address + uint16_t const total_len = tu_le16toh( tu_unaligned_read16(desc_config + offsetof(tusb_desc_configuration_t, wTotalLength)) ); + + // TODO not enough buffer to hold configuration descriptor + TU_ASSERT(total_len <= CFG_TUH_ENUMERATION_BUFSIZE); + + // Get full configuration descriptor + uint8_t const config_idx = CONFIG_NUM - 1; + TU_LOG2("Get Configuration[0] Descriptor\r\n"); + TU_ASSERT( tuh_descriptor_get_configuration(dev_addr, config_idx, _usbh_ctrl_buf, total_len, process_enumeration, ENUM_SET_CONFIG) ); + } + break; + + case ENUM_SET_CONFIG: + // Parse configuration & set up drivers + // Driver open aren't allowed to make any usb transfer yet + TU_ASSERT( parse_configuration_descriptor(dev_addr, (tusb_desc_configuration_t*) _usbh_ctrl_buf) ); + + TU_ASSERT( tuh_configuration_set(dev_addr, CONFIG_NUM, process_enumeration, ENUM_CONFIG_DRIVER) ); + break; + + case ENUM_CONFIG_DRIVER: + { + TU_LOG2("Device configured\r\n"); + usbh_device_t* dev = get_device(dev_addr); + dev->configured = 1; + + // Start the Set Configuration process for interfaces (itf = DRVID_INVALID) + // Since driver can perform control transfer within its set_config, this is done asynchronously. + // The process continue with next interface when class driver complete its sequence with usbh_driver_set_config_complete() + // TODO use separated API instead of using DRVID_INVALID + usbh_driver_set_config_complete(dev_addr, DRVID_INVALID); + } + break; + + default: + // stop enumeration if unknown state + enum_full_complete(); + break; } return true; } -static bool enum_hub_clear_reset0_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) -{ - (void) dev_addr; (void) xfer; - TU_ASSERT(XFER_RESULT_SUCCESS == result); - enum_request_addr0_device_desc(); - return true; -} - -static bool enum_hub_set_reset1_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) -{ - (void) dev_addr; (void) xfer; - TU_ASSERT(XFER_RESULT_SUCCESS == result); - - osal_task_delay(RESET_DELAY); - - TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, enum_hub_get_status1_complete) ); - - return true; -} - -static bool enum_hub_get_status1_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) -{ - (void) dev_addr; (void) xfer; - TU_ASSERT(XFER_RESULT_SUCCESS == result); - - hub_port_status_response_t port_status; - memcpy(&port_status, _usbh_ctrl_buf, sizeof(hub_port_status_response_t)); - - // Acknowledge Port Reset Change if Reset Successful - if (port_status.change.reset) - { - TU_ASSERT( hub_port_clear_feature(_dev0.hub_addr, _dev0.hub_port, HUB_FEATURE_PORT_RESET_CHANGE, enum_hub_clear_reset1_complete) ); - } - - return true; -} - -static bool enum_hub_clear_reset1_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) -{ - (void) dev_addr; (void) xfer; - TU_ASSERT(XFER_RESULT_SUCCESS == result); - - enum_request_set_addr(); - - return true; -} - -#endif // hub - static bool enum_new_device(hcd_event_t* event) { _dev0.rhport = event->rhport; @@ -1100,7 +1202,14 @@ static bool enum_new_device(hcd_event_t* event) _dev0.speed = hcd_port_speed_get(_dev0.rhport ); TU_LOG2("%s Speed\r\n", tu_str_speed[_dev0.speed]); - enum_request_addr0_device_desc(); + //enum_request_addr0_device_desc(); + tuh_control_xfer_t const xfer = + { + .complete_cb = process_enumeration, + .user_arg = ENUM_ADDR0_DEVICE_DESC + }; + process_enumeration(0, &xfer, XFER_RESULT_SUCCESS); + } #if CFG_TUH_HUB else @@ -1108,61 +1217,27 @@ static bool enum_new_device(hcd_event_t* event) // connected/disconnected via external hub // wait until device is stable osal_task_delay(RESET_DELAY); - TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, enum_hub_get_status0_complete) ); + + // ENUM_HUB_GET_STATUS + //TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, enum_hub_get_status0_complete, 0) ); + TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, process_enumeration, ENUM_HUB_CLEAR_RESET_1) ); } #endif // hub return true; } -static bool enum_request_addr0_device_desc(void) +static uint8_t get_new_address(bool is_hub) { - // TODO probably doesn't need to open/close each enumeration - uint8_t const addr0 = 0; - TU_ASSERT( usbh_edpt_control_open(addr0, 8) ); + uint8_t const start = (is_hub ? CFG_TUH_DEVICE_MAX : 0) + 1; + uint8_t const count = (is_hub ? CFG_TUH_HUB : CFG_TUH_DEVICE_MAX); - // Get first 8 bytes of device descriptor for Control Endpoint size - TU_LOG2("Get 8 byte of Device Descriptor\r\n"); - TU_ASSERT(tuh_descriptor_get_device(addr0, _usbh_ctrl_buf, 8, enum_get_addr0_device_desc_complete, 0)); - return true; -} - -// After Get Device Descriptor of Address 0 -static bool enum_get_addr0_device_desc_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) -{ - (void) xfer; - TU_ASSERT(0 == dev_addr); - - if (XFER_RESULT_SUCCESS != result) + for (uint8_t i=0; i < count; i++) { - // stop enumeration, maybe we could retry this - enum_full_complete(); - return false; + uint8_t const addr = start + i; + if (!get_device(addr)->connected) return addr; } - - tusb_desc_device_t const * desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; - TU_ASSERT( tu_desc_type(desc_device) == TUSB_DESC_DEVICE ); - - // Reset device again before Set Address - TU_LOG2("Port reset \r\n"); - - if (_dev0.hub_addr == 0) - { - // connected directly to roothub - hcd_port_reset( _dev0.rhport ); - osal_task_delay(RESET_DELAY); - - enum_request_set_addr(); - } -#if CFG_TUH_HUB - else - { - // after RESET_DELAY the hub_port_reset() already complete - TU_ASSERT( hub_port_reset(_dev0.hub_addr, _dev0.hub_port, enum_hub_set_reset1_complete) ); - } -#endif // hub - - return true; + return ADDR_INVALID; } static bool enum_request_set_addr(void) @@ -1201,8 +1276,8 @@ static bool enum_request_set_addr(void) }, .buffer = NULL, - .complete_cb = enum_set_address_complete, - .user_arg = 0 + .complete_cb = process_enumeration, + .user_arg = ENUM_GET_DEVICE_DESC }; uint8_t const addr0 = 0; @@ -1211,104 +1286,6 @@ static bool enum_request_set_addr(void) return true; } -// After SET_ADDRESS is complete -static bool enum_set_address_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) -{ - TU_ASSERT(0 == dev_addr); - TU_ASSERT(XFER_RESULT_SUCCESS == result); - - uint8_t const new_addr = (uint8_t const) xfer->request.wValue; - - usbh_device_t* new_dev = get_device(new_addr); - new_dev->addressed = 1; - - // TODO close device 0, may not be needed - hcd_device_close(_dev0.rhport, 0); - - // open control pipe for new address - TU_ASSERT( usbh_edpt_control_open(new_addr, new_dev->ep0_size) ); - - // Get full device descriptor - TU_LOG2("Get Device Descriptor\r\n"); - - TU_ASSERT(tuh_descriptor_get_device(new_addr, _usbh_ctrl_buf, sizeof(tusb_desc_device_t), enum_get_device_desc_complete, 0)); - return true; -} - -static bool enum_get_device_desc_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) -{ - (void) xfer; - TU_ASSERT(XFER_RESULT_SUCCESS == result); - - tusb_desc_device_t const * desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; - usbh_device_t* dev = get_device(dev_addr); - - dev->vid = desc_device->idVendor; - dev->pid = desc_device->idProduct; - dev->i_manufacturer = desc_device->iManufacturer; - dev->i_product = desc_device->iProduct; - dev->i_serial = desc_device->iSerialNumber; - -// if (tuh_attach_cb) tuh_attach_cb((tusb_desc_device_t*) _usbh_ctrl_buf); - - // Get 9-byte for total length - uint8_t const config_idx = CONFIG_NUM - 1; - TU_LOG2("Get Configuration[0] Descriptor (9 bytes)\r\n"); - TU_ASSERT( tuh_descriptor_get_configuration(dev_addr, config_idx, _usbh_ctrl_buf, 9, enum_get_9byte_config_desc_complete, 0) ); - return true; -} - -static bool enum_get_9byte_config_desc_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) -{ - (void) xfer; - TU_ASSERT(XFER_RESULT_SUCCESS == result); - - // TODO not enough buffer to hold configuration descriptor - uint8_t const * desc_config = _usbh_ctrl_buf; - - // Use offsetof to avoid pointer to the odd/misaligned address - uint16_t const total_len = tu_le16toh( tu_unaligned_read16(desc_config + offsetof(tusb_desc_configuration_t, wTotalLength)) ); - - TU_ASSERT(total_len <= CFG_TUH_ENUMERATION_BUFSIZE); - - // Get full configuration descriptor - uint8_t const config_idx = CONFIG_NUM - 1; - TU_LOG2("Get Configuration[0] Descriptor\r\n"); - TU_ASSERT( tuh_descriptor_get_configuration(dev_addr, config_idx, _usbh_ctrl_buf, total_len, enum_get_config_desc_complete, 0) ); - return true; -} - -static bool enum_get_config_desc_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) -{ - (void) xfer; - TU_ASSERT(XFER_RESULT_SUCCESS == result); - - // Parse configuration & set up drivers - // Driver open aren't allowed to make any usb transfer yet - TU_ASSERT( parse_configuration_descriptor(dev_addr, (tusb_desc_configuration_t*) _usbh_ctrl_buf) ); - - TU_ASSERT( tuh_configuration_set(dev_addr, CONFIG_NUM, enum_set_config_complete, 0) ); - return true; -} - -static bool enum_set_config_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) -{ - (void) xfer; - TU_ASSERT(XFER_RESULT_SUCCESS == result); - - TU_LOG2("Device configured\r\n"); - usbh_device_t* dev = get_device(dev_addr); - dev->configured = 1; - - // Start the Set Configuration process for interfaces (itf = DRVID_INVALID) - // Since driver can perform control transfer within its set_config, this is done asynchronously. - // The process continue with next interface when class driver complete its sequence with usbh_driver_set_config_complete() - // TODO use separated API instead of using DRVID_INVALID - usbh_driver_set_config_complete(dev_addr, DRVID_INVALID); - - return true; -} - static bool parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg) { usbh_device_t* dev = get_device(dev_addr); @@ -1439,17 +1416,4 @@ static void enum_full_complete(void) } -static uint8_t get_new_address(bool is_hub) -{ - uint8_t const start = (is_hub ? CFG_TUH_DEVICE_MAX : 0) + 1; - uint8_t const count = (is_hub ? CFG_TUH_HUB : CFG_TUH_DEVICE_MAX); - - for (uint8_t i=0; i < count; i++) - { - uint8_t const addr = start + i; - if (!get_device(addr)->connected) return addr; - } - return ADDR_INVALID; -} - #endif From ac4483a7c53cd35b61b59cf69168e31ceac977a1 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 12 Mar 2022 14:26:48 +0700 Subject: [PATCH 234/504] misplace fallthrough --- src/host/usbh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index 6c38c525e..16366b33f 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -1090,8 +1090,8 @@ static bool process_enumeration(uint8_t dev_addr, tuh_control_xfer_t const * xfe TU_ASSERT( hub_port_reset(_dev0.hub_addr, _dev0.hub_port, process_enumeration, ENUM_HUB_GET_STATUS_2) ); break; } - __attribute__((fallthrough)); #endif + __attribute__((fallthrough)); case ENUM_SET_ADDR: enum_request_set_addr(); From 56695569e7d9ebf39ffb2152aba4b4b9f0801d2d Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 12 Mar 2022 14:28:24 +0700 Subject: [PATCH 235/504] minor changes --- src/host/usbh.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index 16366b33f..7485bb065 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -1011,8 +1011,7 @@ static bool process_enumeration(uint8_t dev_addr, tuh_control_xfer_t const * xfe return false; } - uint32_t const state = (uint32_t) xfer->user_arg; - + uintptr_t const state = xfer->user_arg; switch(state) { #if CFG_TUH_HUB From 228e185a1535ed61d3b5eee6219ad1af1b637f4a Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Sat, 12 Mar 2022 16:58:37 +0700 Subject: [PATCH 236/504] Update bug_report.yml --- .github/ISSUE_TEMPLATE/bug_report.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index fc41d8ff1..c0b520e35 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -60,11 +60,12 @@ body: - type: textarea attributes: - label: Debug Log + label: Debug Log as txt file placeholder: | - TinyUSB debug log where the issue occurred as attached txt file, best with comments to explain the actual events. - - Note: To enable logging, add `LOG=3` to to the make command if building with stock examples or set `CFG_TUSB_DEBUG=3` in your tusb_config.h. + Attach your debug log txt file here, where the issue occurred, best with comments to explain the actual events. + + Note1: Please DO NOT paste your lengthy log contents here since it hurts the readibility. + Note2: To enable logging, add `LOG=3` to to the make command if building with stock examples or set `CFG_TUSB_DEBUG=3` in your tusb_config.h. More information can be found at [example's readme](https://github.com/hathach/tinyusb/blob/master/docs/getting_started.md) validations: required: false From 2929afe2fa2fc8425dcd1390cb3119bb1bd3b42b Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 13 Mar 2022 17:45:46 +0700 Subject: [PATCH 237/504] add synchronous (blocking) support for usbh control transfer - add synchronous version of all get descriptor API - update bare example to use sync API for string descriptor - change order of index, language_id in tuh_descriptor_get_string() to match similar API of libusb - add index to tuh_descriptor_get_hid_report() --- examples/host/bare_api/src/main.c | 43 +++----- src/class/hid/hid_host.c | 2 +- src/common/tusb_types.h | 2 + src/host/usbh.c | 172 +++++++++++++++++++++++------- src/host/usbh.h | 98 ++++++++++++----- src/tusb_option.h | 2 +- 6 files changed, 224 insertions(+), 95 deletions(-) diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index 6888d13a2..9e6209991 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -66,17 +66,9 @@ int main(void) #define LANGUAGE_ID 0x0409 //uint8_t usb_buf[256] TU_ATTR_ALIGNED(4); +TU_ATTR_ALIGNED(4) tusb_desc_device_t desc_device; -static volatile xfer_result_t _get_string_result; - -static bool _transfer_done_cb(uint8_t daddr, tuh_control_xfer_t const *xfer, xfer_result_t result) { - (void)daddr; - (void)xfer; - _get_string_result = result; - return true; -} - static void _convert_utf16le_to_utf8(const uint16_t *utf16, size_t utf16_len, uint8_t *utf8, size_t utf8_len) { // TODO: Check for runover. (void)utf8_len; @@ -116,14 +108,7 @@ static int _count_utf8_bytes(const uint16_t *buf, size_t len) { return total_bytes; } -static void _wait_and_convert(uint16_t *temp_buf, size_t buf_len) { - while (_get_string_result == 0xff) { - tuh_task(); - } - if (_get_string_result != XFER_RESULT_SUCCESS) { - temp_buf[0] = 0; - return; - } +static void utf16_to_utf8(uint16_t *temp_buf, size_t buf_len) { size_t utf16_len = ((temp_buf[0] & 0xff) - 2) / sizeof(uint16_t); size_t utf8_len = _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); @@ -153,31 +138,29 @@ bool print_device_descriptor(uint8_t daddr, tuh_control_xfer_t const * xfer, xfe printf(" idProduct 0x%04x\r\n" , desc_device.idProduct); printf(" bcdDevice %04x\r\n" , desc_device.bcdDevice); - _get_string_result = 0xff; + uint32_t timeout_ms = 10; uint16_t temp_buf[128]; printf(" iManufacturer %u " , desc_device.iManufacturer); - temp_buf[0] = 0; - if (tuh_descriptor_get_manufacturer_string(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb, 0)) { - _wait_and_convert(temp_buf, TU_ARRAY_SIZE(temp_buf)); + if (XFER_RESULT_SUCCESS == tuh_descriptor_get_manufacturer_string_sync(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf), timeout_ms) ) + { + utf16_to_utf8(temp_buf, TU_ARRAY_SIZE(temp_buf)); printf((const char*) temp_buf); } printf("\r\n"); printf(" iProduct %u " , desc_device.iProduct); - _get_string_result = 0xff; - temp_buf[0] = 0; - if (tuh_descriptor_get_product_string(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb, 0)) { - _wait_and_convert(temp_buf, TU_ARRAY_SIZE(temp_buf)); + if (XFER_RESULT_SUCCESS == tuh_descriptor_get_product_string_sync(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf), timeout_ms)) + { + utf16_to_utf8(temp_buf, TU_ARRAY_SIZE(temp_buf)); printf((const char*) temp_buf); } printf("\r\n"); printf(" iSerialNumber %u " , desc_device.iSerialNumber); - _get_string_result = 0xff; - temp_buf[0] = 0; - if (tuh_descriptor_get_serial_string(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb, 0)) { - _wait_and_convert(temp_buf, TU_ARRAY_SIZE(temp_buf)); + if (XFER_RESULT_SUCCESS == tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf), timeout_ms)) + { + utf16_to_utf8(temp_buf, TU_ARRAY_SIZE(temp_buf)); printf((const char*) temp_buf); } printf("\r\n"); @@ -192,7 +175,7 @@ void tuh_mount_cb (uint8_t daddr) { printf("Device attached, address = %d\r\n", daddr); - // Get Device Descriptor + // Get Device Descriptor using asynchronous API tuh_descriptor_get_device(daddr, &desc_device, 18, print_device_descriptor, 0); } diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 4de3551c2..a825858ab 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -437,7 +437,7 @@ static bool config_get_report_desc(uint8_t dev_addr, tuh_control_xfer_t const * config_driver_mount_complete(dev_addr, instance, NULL, 0); }else { - TU_ASSERT(tuh_descriptor_get_hid_report(dev_addr, itf_num, hid_itf->report_desc_type, usbh_get_enum_buf(), hid_itf->report_desc_len, config_get_report_desc_complete, 0)); + TU_ASSERT(tuh_descriptor_get_hid_report(dev_addr, itf_num, hid_itf->report_desc_type, 0, usbh_get_enum_buf(), hid_itf->report_desc_len, config_get_report_desc_complete, 0)); } return true; diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index da164145b..e2fa17532 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -228,6 +228,8 @@ typedef enum XFER_RESULT_SUCCESS, XFER_RESULT_FAILED, XFER_RESULT_STALLED, + XFER_RESULT_TIMEOUT, + XFER_RESULT_INVALID }xfer_result_t; enum // TODO remove diff --git a/src/host/usbh.c b/src/host/usbh.c index 7485bb065..c7dfaddf6 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -243,7 +243,7 @@ struct { tuh_control_xfer_t xfer; uint8_t daddr; // device address that is transferring - uint8_t stage; + volatile uint8_t stage; }_ctrl_xfer; //------------- Helper Function -------------// @@ -300,8 +300,8 @@ void osal_task_delay(uint32_t msec) // Descriptors //--------------------------------------------------------------------+ -bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len, - tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) +static bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t language_id, void* buffer, uint16_t len, + tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { tuh_control_xfer_t const xfer = { @@ -315,7 +315,7 @@ bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, void* buffer }, .bRequest = TUSB_REQ_GET_DESCRIPTOR, .wValue = tu_htole16( TU_U16(type, index) ), - .wIndex = 0, + .wIndex = tu_htole16(language_id), .wLength = tu_htole16(len) }, @@ -327,6 +327,12 @@ bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, void* buffer return tuh_control_xfer(daddr, &xfer); } +bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len, + tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) +{ + return _get_descriptor(daddr, type, index, 0x0000, buffer, len, complete_cb, user_arg); +} + bool tuh_descriptor_get_device(uint8_t daddr, void* buffer, uint16_t len, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { @@ -340,31 +346,12 @@ bool tuh_descriptor_get_configuration(uint8_t daddr, uint8_t index, void* buffer return tuh_descriptor_get(daddr, TUSB_DESC_CONFIGURATION, index, buffer, len, complete_cb, user_arg); } -bool tuh_descriptor_get_string(uint8_t daddr, uint16_t language_id, uint8_t index, void* buffer, uint16_t len, +//------------- String Descriptor -------------// + +bool tuh_descriptor_get_string(uint8_t daddr, uint8_t index, uint16_t language_id, void* buffer, uint16_t len, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { - tuh_control_xfer_t const xfer = - { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_DEVICE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_IN - }, - .bRequest = TUSB_REQ_GET_DESCRIPTOR, - .wValue = tu_htole16( TU_U16(TUSB_DESC_STRING, index) ), - .wIndex = tu_htole16(language_id), - .wLength = tu_htole16(len) - }, - - .buffer = buffer, - .complete_cb = complete_cb, - .user_arg = user_arg - }; - - return tuh_control_xfer(daddr, &xfer); + return _get_descriptor(daddr, TUSB_DESC_STRING, index, language_id, buffer, len, complete_cb, user_arg); } // Get manufacturer string descriptor @@ -376,7 +363,7 @@ bool tuh_descriptor_get_manufacturer_string(uint8_t daddr, uint16_t language_id, if (dev->i_manufacturer == 0) { return false; } - return tuh_descriptor_get_string(daddr, language_id, dev->i_manufacturer, buffer, len, complete_cb, user_arg); + return tuh_descriptor_get_string(daddr, dev->i_manufacturer, language_id, buffer, len, complete_cb, user_arg); } // Get product string descriptor @@ -388,7 +375,7 @@ bool tuh_descriptor_get_product_string(uint8_t daddr, uint16_t language_id, void if (dev->i_product == 0) { return false; } - return tuh_descriptor_get_string(daddr, language_id, dev->i_product, buffer, len, complete_cb, user_arg); + return tuh_descriptor_get_string(daddr, dev->i_product, language_id, buffer, len, complete_cb, user_arg); } // Get serial string descriptor @@ -400,11 +387,11 @@ bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void* if (dev->i_serial == 0) { return false; } - return tuh_descriptor_get_string(daddr, language_id, dev->i_serial, buffer, len, complete_cb, user_arg); + return tuh_descriptor_get_string(daddr, dev->i_serial, language_id, buffer, len, complete_cb, user_arg); } // Get HID report descriptor -bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, void* buffer, uint16_t len, +bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, void* buffer, uint16_t len, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { TU_LOG2("HID Get Report Descriptor\r\n"); @@ -419,8 +406,8 @@ bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_ .direction = TUSB_DIR_IN }, .bRequest = TUSB_REQ_GET_DESCRIPTOR, - .wValue = tu_htole16(TU_U16(desc_type, 0)), - .wIndex = itf_num, + .wValue = tu_htole16(TU_U16(desc_type, index)), + .wIndex = tu_htole16((uint16_t) itf_num), .wLength = len }, @@ -461,6 +448,58 @@ bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, return tuh_control_xfer(daddr, &xfer); } +//--------------------------------------------------------------------+ +// Asynchronous +//--------------------------------------------------------------------+ + +#define _CONTROL_SYNC_API(_async_func, _timeout, ...) \ + (void) _timeout; \ + xfer_result_t result = XFER_RESULT_INVALID;\ + /* TODO use timeout to wait */ \ + TU_VERIFY(_async_func(__VA_ARGS__, NULL, (uintptr_t) &result), XFER_RESULT_TIMEOUT); \ + return (uint8_t) result + +uint8_t tuh_descriptor_get_sync(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len, uint8_t timeout_ms) +{ + _CONTROL_SYNC_API(tuh_descriptor_get, timeout_ms, daddr, type, index, buffer, len); +} + +uint8_t tuh_descriptor_get_device_sync(uint8_t daddr, void* buffer, uint16_t len, uint8_t timeout_ms) +{ + len = tu_min16(len, sizeof(tusb_desc_device_t)); + return tuh_descriptor_get_sync(daddr, TUSB_DESC_DEVICE, 0, buffer, len, timeout_ms); +} + +uint8_t tuh_descriptor_get_configuration_sync(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, uint8_t timeout_ms) +{ + return tuh_descriptor_get_sync(daddr, TUSB_DESC_CONFIGURATION, index, buffer, len, timeout_ms); +} + +uint8_t tuh_descriptor_get_hid_report_sync(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, void* buffer, uint16_t len, uint8_t timeout_ms) +{ + _CONTROL_SYNC_API(tuh_descriptor_get_hid_report, timeout_ms, daddr, itf_num, desc_type, index, buffer, len); +} + +uint8_t tuh_descriptor_get_string_sync(uint8_t daddr, uint8_t index, uint16_t language_id, void* buffer, uint16_t len, uint8_t timeout_ms) +{ + _CONTROL_SYNC_API(tuh_descriptor_get_string, timeout_ms, daddr, index, language_id, buffer, len); +} + +uint8_t tuh_descriptor_get_manufacturer_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, uint8_t timeout_ms) +{ + _CONTROL_SYNC_API(tuh_descriptor_get_manufacturer_string, timeout_ms, daddr, language_id, buffer, len); +} + +uint8_t tuh_descriptor_get_product_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, uint8_t timeout_ms) +{ + _CONTROL_SYNC_API(tuh_descriptor_get_product_string, timeout_ms, daddr, language_id, buffer, len); +} + +uint8_t tuh_descriptor_get_serial_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, uint8_t timeout_ms) +{ + _CONTROL_SYNC_API(tuh_descriptor_get_serial_string, timeout_ms, daddr, language_id, buffer, len); +} + //--------------------------------------------------------------------+ // CLASS-USBD API (don't require to verify parameters) //--------------------------------------------------------------------+ @@ -833,11 +872,22 @@ bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) // Control transfer //--------------------------------------------------------------------+ +static bool _control_blocking_complete_cb(uint8_t daddr, tuh_control_xfer_t const * xfer, xfer_result_t result) +{ + (void) daddr; + + // update result + *((xfer_result_t*) xfer->user_arg) = result; + + return true; +} + bool tuh_control_xfer (uint8_t daddr, tuh_control_xfer_t const* xfer) { // pre-check to help reducing mutex lock TU_VERIFY(_ctrl_xfer.stage == CONTROL_STAGE_IDLE); + // TODO probably better to use semaphore as resource management than mutex usbh_lock(); bool const is_idle = (_ctrl_xfer.stage == CONTROL_STAGE_IDLE); @@ -855,7 +905,52 @@ bool tuh_control_xfer (uint8_t daddr, tuh_control_xfer_t const* xfer) _ctrl_xfer.daddr = daddr; _ctrl_xfer.xfer = (*xfer); - return hcd_setup_send(rhport, daddr, (uint8_t*) &_ctrl_xfer.xfer.request); + + if (xfer->complete_cb) + { + TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t*) &_ctrl_xfer.xfer.request) ); + }else + { + // user_arg must point to xfer_result_t to hold result + TU_VERIFY(xfer->user_arg); + + // blocking if complete callback is not provided + // change callback to internal blocking, and result as user argument + volatile xfer_result_t* result = (volatile xfer_result_t*) xfer->user_arg; + + _ctrl_xfer.xfer.complete_cb = _control_blocking_complete_cb; + *result = XFER_RESULT_INVALID; + + TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t*) &_ctrl_xfer.xfer.request) ); + + while ((*result) == XFER_RESULT_INVALID) + { + // only need to call task if not preempted RTOS + #if CFG_TUSB_OS == OPT_OS_NONE || CFG_TUSB_OS == OPT_OS_PICO + tuh_task(); + #endif + + // TODO probably some timeout to prevent hanged + } + } + + return true; +} + +uint8_t tuh_control_xfer_sync(uint8_t daddr, tuh_control_xfer_t const* xfer, uint32_t timeout_ms) +{ + (void) timeout_ms; + + xfer_result_t result = XFER_RESULT_INVALID; + tuh_control_xfer_t xfer_sync = (*xfer); + + xfer_sync.complete_cb = NULL; + xfer_sync.user_arg = (uintptr_t) &result; + + // TODO use timeout to wait + TU_VERIFY(tuh_control_xfer(daddr, &xfer_sync), XFER_RESULT_TIMEOUT); + + return result; } TU_ATTR_ALWAYS_INLINE static inline void set_control_xfer_stage(uint8_t stage) @@ -869,15 +964,16 @@ static void _xfer_complete(uint8_t dev_addr, xfer_result_t result) { TU_LOG2("\r\n"); + // duplicate xfer since user can execute control transfer within callback + tuh_control_xfer_t const xfer_temp = _ctrl_xfer.xfer; + usbh_lock(); _ctrl_xfer.stage = CONTROL_STAGE_IDLE; usbh_unlock(); - if (_ctrl_xfer.xfer.complete_cb) + if (xfer_temp.complete_cb) { - // duplicate xfer since user can execute control transfer within callback - tuh_control_xfer_t const xfer_temp = _ctrl_xfer.xfer; - _ctrl_xfer.xfer.complete_cb(dev_addr, &xfer_temp, result); + xfer_temp.complete_cb(dev_addr, &xfer_temp, result); } } diff --git a/src/host/usbh.h b/src/host/usbh.h index d836d9593..3bd40c50d 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -52,6 +52,18 @@ struct tuh_control_xfer_s uintptr_t user_arg; }; +//--------------------------------------------------------------------+ +// APPLICATION CALLBACK +//--------------------------------------------------------------------+ + +//TU_ATTR_WEAK uint8_t tuh_attach_cb (tusb_desc_device_t const *desc_device); + +// Invoked when device is mounted (configured) +TU_ATTR_WEAK void tuh_mount_cb (uint8_t daddr); + +/// Invoked when device is unmounted (bus reset/unplugged) +TU_ATTR_WEAK void tuh_umount_cb(uint8_t daddr); + //--------------------------------------------------------------------+ // APPLICATION API //--------------------------------------------------------------------+ @@ -93,65 +105,101 @@ static inline bool tuh_ready(uint8_t daddr) } // Carry out a control transfer -// true on success, false if there is on-going control transfer -// Note: function is blocking if complete callback is NULL +// true on success, false if there is on-going control transfer or incorrect parameters +// Blocking if complete callback is NULL, in this case 'user_arg' must contain xfer_result_t variable bool tuh_control_xfer (uint8_t daddr, tuh_control_xfer_t const* xfer); -// Carry out a control transfer -// true on success, false if there is on-going control transfer -// Note: function is blocking if complete callback is NULL -//bool tuh_control_xfer (uint8_t daddr, tusb_control_request_t const* request, void* buffer, -// tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); +// Sync (blocking) version of tuh_control_xfer() +// return transfer result +uint8_t tuh_control_xfer_sync(uint8_t daddr, tuh_control_xfer_t const* xfer, uint32_t timeout_ms); -// Set Configuration +// Set Configuration (control transfer) // config_num = 0 will un-configure device. Note: config_num = config_descriptor_index + 1 +// true on success, false if there is on-going control transfer or incorrect parameters +// Blocking if complete callback is NULL, in this case 'user_arg' must contain xfer_result_t variable bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); -//------------- descriptors -------------// +//--------------------------------------------------------------------+ +// Descriptors Asynchronous (non-blocking) +//--------------------------------------------------------------------+ -// Get an descriptor +// Get an descriptor (control transfer) +// true on success, false if there is on-going control transfer or incorrect parameters bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); -// Get device descriptor +// Get device descriptor (control transfer) +// true on success, false if there is on-going control transfer or incorrect parameters bool tuh_descriptor_get_device(uint8_t daddr, void* buffer, uint16_t len, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); -// Get configuration descriptor +// Get configuration descriptor (control transfer) +// true on success, false if there is on-going control transfer or incorrect parameters bool tuh_descriptor_get_configuration(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); -// Get HID report descriptor -bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, void* buffer, uint16_t len, +// Get HID report descriptor (control transfer) +// true on success, false if there is on-going control transfer or incorrect parameters +bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, void* buffer, uint16_t len, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); -// Get string descriptor -bool tuh_descriptor_get_string(uint8_t daddr, uint16_t language_id, uint8_t index, void* buffer, uint16_t len, +// Get string descriptor (control transfer) +// true on success, false if there is on-going control transfer or incorrect parameters +// Blocking if complete callback is NULL, in this case 'user_arg' must contain xfer_result_t variable +bool tuh_descriptor_get_string(uint8_t daddr, uint8_t index, uint16_t language_id, void* buffer, uint16_t len, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); -// Get manufacturer string descriptor +// Get manufacturer string descriptor (control transfer) +// true on success, false if there is on-going control transfer or incorrect parameters bool tuh_descriptor_get_manufacturer_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); -// Get product string descriptor +// Get product string descriptor (control transfer) +// true on success, false if there is on-going control transfer or incorrect parameters bool tuh_descriptor_get_product_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); -// Get serial string descriptor +// Get serial string descriptor (control transfer) +// true on success, false if there is on-going control transfer or incorrect parameters bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); //--------------------------------------------------------------------+ -// APPLICATION CALLBACK +// Descriptors Synchronous (blocking) //--------------------------------------------------------------------+ -//TU_ATTR_WEAK uint8_t tuh_attach_cb (tusb_desc_device_t const *desc_device); -// Invoked when device is mounted (configured) -TU_ATTR_WEAK void tuh_mount_cb (uint8_t daddr); +// Sync (blocking) version of tuh_descriptor_get() +// return transfer result +uint8_t tuh_descriptor_get_sync(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len, uint8_t timeout_ms); -/// Invoked when device is unmounted (bus reset/unplugged) -TU_ATTR_WEAK void tuh_umount_cb(uint8_t daddr); +// Sync (blocking) version of tuh_descriptor_get_device() +// return transfer result +uint8_t tuh_descriptor_get_device_sync(uint8_t daddr, void* buffer, uint16_t len, uint8_t timeout_ms); + +// Sync (blocking) version of tuh_descriptor_get_configuration() +// return transfer result +uint8_t tuh_descriptor_get_configuration_sync(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, uint8_t timeout_ms); + +// Sync (blocking) version of tuh_descriptor_get_hid_report() +// return transfer result +uint8_t tuh_descriptor_get_hid_report_sync(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, void* buffer, uint16_t len, uint8_t timeout_ms); + +// Sync (blocking) version of tuh_descriptor_get_string() +// return transfer result +uint8_t tuh_descriptor_get_string_sync(uint8_t daddr, uint8_t index, uint16_t language_id, void* buffer, uint16_t len, uint8_t timeout_ms); + +// Sync (blocking) version of tuh_descriptor_get_manufacturer_string() +// return transfer result +uint8_t tuh_descriptor_get_manufacturer_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, uint8_t timeout_ms); + +// Sync (blocking) version of tuh_descriptor_get_product_string() +// return transfer result +uint8_t tuh_descriptor_get_product_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, uint8_t timeout_ms); + +// Sync (blocking) version of tuh_descriptor_get_serial_string() +// return transfer result +uint8_t tuh_descriptor_get_serial_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, uint8_t timeout_ms); #ifdef __cplusplus } diff --git a/src/tusb_option.h b/src/tusb_option.h index e5351b1c4..0352faaed 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -285,7 +285,7 @@ #define CFG_TUSB_OS_INC_PATH #endif -// mutex is only needed for RTOS +// mutex is only needed for RTOS TODO also required with multiple core MCUs #define TUSB_OPT_MUTEX (CFG_TUSB_OS != OPT_OS_NONE) //-------------------------------------------------------------------- From f212899b54740479eff225d89432d88f0a14f17e Mon Sep 17 00:00:00 2001 From: Reinhard Panhuber Date: Mon, 14 Mar 2022 20:40:33 +0100 Subject: [PATCH 238/504] Add SOF callback function for feedback value determination in uac - wip! --- src/class/audio/audio_device.c | 83 +++++++++++++++++++++++++++ src/class/audio/audio_device.h | 23 +++++++- src/device/usbd.c | 22 ++++++- src/device/usbd_pvt.h | 5 +- src/portable/synopsys/dwc2/dcd_dwc2.c | 32 +++++++++-- 5 files changed, 156 insertions(+), 9 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 06979b09e..0828f2e6f 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -306,6 +306,13 @@ typedef struct #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR + uint8_t n_frames; // Number of (micro)frames used to estimate feedback value + uint8_t n_frames_current; // Current (micro)frame number + uint32_t feeback_param_factor; // TODO: Set this value within some new tud_audio_set_feedback_params_fm_fs function as feeback_param_factor = f_s / (f_cpu * n_frames)! +#endif + #endif #endif @@ -421,6 +428,10 @@ static inline uint8_t tu_desc_subtype(void const* desc) } #endif +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +static bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); +#endif + bool tud_audio_n_mounted(uint8_t func_id) { TU_VERIFY(func_id < CFG_TUD_AUDIO); @@ -1658,6 +1669,11 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * { audio->ep_fb = ep_addr; +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR + usbd_sof_enable(rhport, true); // Enable SOF interrupt + audio->n_frames_current = 0; +#endif + // Invoke callback after ep_out is set if (audio->ep_out != 0) { @@ -1682,6 +1698,23 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * p_desc = tu_desc_next(p_desc); } + // Disable SOF interrupt if no driver has any enabled feedback EP +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR + + bool disable = true; + + for(uint8_t i=0; i < CFG_TUD_AUDIO; i++) + { + if (_audiod_fct[i].ep_fb != 0) + { + disable = false; + } + } + + if (disable) usbd_sof_enable(rhport, false); + +#endif + tud_control_status(rhport, p_request); return true; @@ -1970,6 +2003,52 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 return false; } +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +bool tud_audio_set_feedback_params_fm_fs(uint8_t func_id, uint32_t f_m, uint32_t f_s) +{ + audiod_function_t* audio = &_audiod_fct[func_id]; + uint8_t n_frame = 1; // TODO: finalize that + audio->n_frames = n_frame; + audio->feeback_param_factor = f_s / f_m / n_frame; // TODO: Check the 16.16 precision! + return true; +} +#endif + +void audiod_sof (uint8_t rhport, uint32_t frame_count) +{ + (void) rhport; + (void) frame_count; + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR + + // Determine feedback value - The feedback method is described in 5.12.4.2 of the USB 2.0 spec + // Boiled down, the feedback value Ff = n_samples / (micro)frame. + // Since an accuracy of less than 1 Sample / second is desired, at least n_frames = ceil(2^K * f_s / f_cpu) frames need to be measured, where K = 10 for full speed and K = 13 for high speed, f_s is the sampling frequency e.g. 48 kHz and f_cpu is the cpu clock frequency e.g. 100 MHz (or any other master clock whose clock count is available and locked to f_s) + // The update interval in the (4.10.2.1) Feedback Endpoint Descriptor must be less or equal to 2^(K - P), where P = min( ceil(log2(f_cpu / f_s)), K) + // Ff = n_cycles / n_frames * f_s / f_cpu in 16.16 format, where n_cycles are the number of CPU cycles within n_frames + + // Iterate over audio functions and set feedback value + for(uint8_t i=0; i < CFG_TUD_AUDIO; i++) + { + audiod_function_t* audio = &_audiod_fct[i]; + + if (audio->ep_fb != 0) + { + audio->n_frames_current++; + if (audio->n_frames_current == audio->n_frames) + { + uint32_t n_cylces = tud_audio_n_get_fm_n_cycles_cb(rhport, audio->ep_fb); + uint32_t feedback = n_cylces * audio->feeback_param_factor; + + tud_audio_n_fb_set(i, feedback); + audio->n_frames_current = 0; + } + } + } + +#endif +} + bool tud_audio_buffer_and_schedule_control_xfer(uint8_t rhport, tusb_control_request_t const * p_request, void* data, uint16_t len) { // Handles only sending of data not receiving @@ -2247,7 +2326,11 @@ static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +static bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) +#else bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) +#endif { TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index f406cf281..c9d711a36 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -191,6 +191,11 @@ #define CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION 0 // 0 or 1 #endif +// Determine feedback value within SOF ISR within audio driver - if disabled the user has to call tud_audio_n_fb_set() with a suitable feedback value on its own. If done within audio driver SOF ISR, tud_audio_n_fb_set() is disabled for user +#ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR 1 // 0 or 1 +#endif + // Audio interrupt control EP size - disabled if 0 #ifndef CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN #define CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN 0 // Audio interrupt control - if required - 6 Bytes according to UAC 2 specification (p. 74) @@ -468,8 +473,23 @@ TU_ATTR_WEAK bool tud_audio_fb_done_cb(uint8_t rhport); // // Note that due to a bug in its USB Audio 2.0 driver, Windows currently requires 16.16 format for _all_ USB 2.0 devices. On Linux and macOS it seems the // driver can work with either format. So a good compromise is to keep format correction disabled and stick to 16.16 format. + +// Feedback value can be determined from within the SOF ISR of the audio driver. This should reduce jitter. If the feature is used, the user can not set the feedback value. +# if !CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); static inline bool tud_audio_fb_set(uint32_t feedback); +# else + +// This callback function is called once the feedback value needs to be updated within the SOF ISR in the audio class. To determine the feedback value, some +// parameters need to be given. The user must implement this callback function and provide the current cycle count of the master clock. +// The feedback endpoint number can be used to identify the correct audio function in case multiple audio functions were defined. +TU_ATTR_WEAK uint32_t tud_audio_n_get_fm_n_cycles_cb(uint8_t rhport, uint8_t ep_fb); + +// f_m : Main clock frequency in Hz i.e. master clock to which sample clock is locked +// f_s : Current sample rate in Hz +bool tud_audio_set_feedback_params_fm_fs(uint8_t func_id, uint32_t f_m, uint32_t f_s); +#endif + #endif #if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN @@ -611,7 +631,7 @@ static inline uint16_t tud_audio_int_ctr_write(uint8_t const* buffer, uint16_t l } #endif -#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && !CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR static inline bool tud_audio_fb_set(uint32_t feedback) { return tud_audio_n_fb_set(0, feedback); @@ -626,6 +646,7 @@ void audiod_reset (uint8_t rhport); uint16_t audiod_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool audiod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); bool audiod_xfer_cb (uint8_t rhport, uint8_t edpt_addr, xfer_result_t result, uint32_t xferred_bytes); +void audiod_sof (uint8_t rhport, uint32_t frame_count); #ifdef __cplusplus } diff --git a/src/device/usbd.c b/src/device/usbd.c index 8662d5b84..170342072 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -139,7 +139,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = audiod_open, .control_xfer_cb = audiod_control_xfer_cb, .xfer_cb = audiod_xfer_cb, - .sof = NULL + .sof = audiod_sof }, #endif @@ -612,7 +612,7 @@ void tud_task (void) for ( uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++ ) { usbd_class_driver_t const * driver = get_driver(i); - if ( driver->sof ) driver->sof(event.rhport); + if ( driver->sof ) driver->sof(event.rhport, event.sof.frame_count); } break; @@ -1131,7 +1131,18 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr) break; case DCD_EVENT_SOF: - // SOF Handler + // SOF driver handler in ISR context + for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) + { + usbd_class_driver_t const * driver = get_driver(i); + if (driver->sof) + { + driver->sof(event->rhport, event->sof.frame_count); + // TU_LOG2("%s sof\r\n", driver->name); // too demanding + } + } + + // SOF user handler in ISR context if (_sof_isr) _sof_isr(event->sof.frame_count); // Some MCUs after running dcd_remote_wakeup() does not have way to detect the end of remote wakeup @@ -1441,4 +1452,9 @@ void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr) return; } +void usbd_sof_enable(uint8_t rhport, bool en) +{ + dcd_sof_enable(rhport, en); +} + #endif diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index dae95cebb..f9fb543df 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -48,7 +48,7 @@ typedef struct uint16_t (* open ) (uint8_t rhport, tusb_desc_interface_t const * desc_intf, uint16_t max_len); bool (* control_xfer_cb ) (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); bool (* xfer_cb ) (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); - void (* sof ) (uint8_t rhport); /* optional */ + void (* sof ) (uint8_t rhport, uint32_t frame_count); /* optional */ } usbd_class_driver_t; // Invoked when initializing device stack to get additional class drivers. @@ -102,6 +102,9 @@ bool usbd_edpt_ready(uint8_t rhport, uint8_t ep_addr) return !usbd_edpt_busy(rhport, ep_addr) && !usbd_edpt_stalled(rhport, ep_addr); } +// Enable SOF interrupt +void usbd_sof_enable(uint8_t rhport, bool en); + /*------------------------------------------------------------------*/ /* Helper *------------------------------------------------------------------*/ diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 37712d2d9..d92b17703 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -93,6 +93,9 @@ static uint16_t ep0_pending[2]; // Index determines direction static uint16_t _allocated_fifo_words_tx; // TX FIFO size in words (IN EPs) static bool _out_ep_closed; // Flag to check if RX FIFO size needs an update (reduce its size) +// SOF enabling flag - required for SOF to not get disabled in ISR when SOF was enabled by +static bool _sof_en; + // Calculate the RX FIFO size according to recommendations from reference manual static inline uint16_t calc_rx_ff_size(uint16_t ep_size) { @@ -126,6 +129,8 @@ static void bus_reset(uint8_t rhport) tu_memclr(xfer_status, sizeof(xfer_status)); _out_ep_closed = false; + _sof_en = false; + // clear device address dwc2->dcfg &= ~DCFG_DAD_Msk; @@ -588,12 +593,23 @@ void dcd_disconnect(uint8_t rhport) dwc2->dctl |= DCTL_SDIS; } +// Be advised: audio, video and possibly other iso-ep classes use dcd_sof_enable() to enable/disable its corresponding ISR on purpose! void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; - (void) en; + dwc2_regs_t * dwc2 = DWC2_REG(rhport); - // TODO implement later + _sof_en = en; + + if (en) + { + dwc2->gintsts = GINTSTS_SOF; + dwc2->gintmsk |= GINTMSK_SOFM; + } + else + { + dwc2->gintmsk &= ~GINTMSK_SOFM; + } } /*------------------------------------------------------------------*/ @@ -1258,8 +1274,16 @@ void dcd_int_handler(uint8_t rhport) { dwc2->gotgint = GINTSTS_SOF; - // Disable SOF interrupt since currently only used for remote wakeup detection - dwc2->gintmsk &= ~GINTMSK_SOFM; + if (_sof_en) + { + uint32_t frame = (dwc2->dsts & (USB_OTG_DSTS_FNSOF)) >> 8; + dcd_event_sof(rhport, frame, true); + } + else + { + // Disable SOF interrupt if SOF was not explicitly enabled. SOF was used for remote wakeup detection + dwc2->gintmsk &= ~GINTMSK_SOFM; + } dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); } From c9b444e771e138ee50ed8cbff67d895722b46008 Mon Sep 17 00:00:00 2001 From: Reinhard Panhuber Date: Tue, 15 Mar 2022 20:30:31 +0100 Subject: [PATCH 239/504] Implement 16.16 fixed point feedback value calculation --- src/class/audio/audio_device.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 0828f2e6f..5ca95658e 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -310,7 +310,8 @@ typedef struct #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR uint8_t n_frames; // Number of (micro)frames used to estimate feedback value uint8_t n_frames_current; // Current (micro)frame number - uint32_t feeback_param_factor; // TODO: Set this value within some new tud_audio_set_feedback_params_fm_fs function as feeback_param_factor = f_s / (f_cpu * n_frames)! + uint32_t feeback_param_factor_N; // Numerator of feedback parameter coefficient + uint32_t feeback_param_factor_D; // Denominator of feedback parameter coefficient #endif #endif @@ -2004,12 +2005,16 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 } #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +// f_s max is 2^19-1 = 524287 Hz +// n_frames_min is ceil(2^10 * f_s / f_m) for full speed and ceil(2^13 * f_s / f_m) for high speed +// f_m max is 2^29/(1 ms * n_frames) for full speed and 2^29/(125 us * n_frames) for high speed bool tud_audio_set_feedback_params_fm_fs(uint8_t func_id, uint32_t f_m, uint32_t f_s) { audiod_function_t* audio = &_audiod_fct[func_id]; uint8_t n_frame = 1; // TODO: finalize that audio->n_frames = n_frame; - audio->feeback_param_factor = f_s / f_m / n_frame; // TODO: Check the 16.16 precision! + audio->feeback_param_factor_N = f_s << 13; + audio->feeback_param_factor_D = f_m * n_frame; return true; } #endif @@ -2023,7 +2028,7 @@ void audiod_sof (uint8_t rhport, uint32_t frame_count) // Determine feedback value - The feedback method is described in 5.12.4.2 of the USB 2.0 spec // Boiled down, the feedback value Ff = n_samples / (micro)frame. - // Since an accuracy of less than 1 Sample / second is desired, at least n_frames = ceil(2^K * f_s / f_cpu) frames need to be measured, where K = 10 for full speed and K = 13 for high speed, f_s is the sampling frequency e.g. 48 kHz and f_cpu is the cpu clock frequency e.g. 100 MHz (or any other master clock whose clock count is available and locked to f_s) + // Since an accuracy of less than 1 Sample / second is desired, at least n_frames = ceil(2^K * f_s / f_m) frames need to be measured, where K = 10 for full speed and K = 13 for high speed, f_s is the sampling frequency e.g. 48 kHz and f_cpu is the cpu clock frequency e.g. 100 MHz (or any other master clock whose clock count is available and locked to f_s) // The update interval in the (4.10.2.1) Feedback Endpoint Descriptor must be less or equal to 2^(K - P), where P = min( ceil(log2(f_cpu / f_s)), K) // Ff = n_cycles / n_frames * f_s / f_cpu in 16.16 format, where n_cycles are the number of CPU cycles within n_frames @@ -2038,7 +2043,7 @@ void audiod_sof (uint8_t rhport, uint32_t frame_count) if (audio->n_frames_current == audio->n_frames) { uint32_t n_cylces = tud_audio_n_get_fm_n_cycles_cb(rhport, audio->ep_fb); - uint32_t feedback = n_cylces * audio->feeback_param_factor; + uint32_t feedback = (n_cylces << 3) * audio->feeback_param_factor_N / audio->feeback_param_factor_D; // feeback_param_factor_N has scaling factor of 13 bits, n_cycles 3 and feeback_param_factor_D 1, hence 16.16 precision tud_audio_n_fb_set(i, feedback); audio->n_frames_current = 0; From 90502739c34b8cbcf37229031eb4f575c33311fa Mon Sep 17 00:00:00 2001 From: Reinhard Panhuber Date: Tue, 15 Mar 2022 20:45:06 +0100 Subject: [PATCH 240/504] Fix cycle count calculation --- src/class/audio/audio_device.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 5ca95658e..1dbeb7643 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -310,6 +310,7 @@ typedef struct #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR uint8_t n_frames; // Number of (micro)frames used to estimate feedback value uint8_t n_frames_current; // Current (micro)frame number + uint32_t n_cycles_old; // Old cycle count uint32_t feeback_param_factor_N; // Numerator of feedback parameter coefficient uint32_t feeback_param_factor_D; // Denominator of feedback parameter coefficient #endif @@ -1673,6 +1674,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR usbd_sof_enable(rhport, true); // Enable SOF interrupt audio->n_frames_current = 0; + audio->n_cycles_old = 0; #endif // Invoke callback after ep_out is set @@ -2043,10 +2045,11 @@ void audiod_sof (uint8_t rhport, uint32_t frame_count) if (audio->n_frames_current == audio->n_frames) { uint32_t n_cylces = tud_audio_n_get_fm_n_cycles_cb(rhport, audio->ep_fb); - uint32_t feedback = (n_cylces << 3) * audio->feeback_param_factor_N / audio->feeback_param_factor_D; // feeback_param_factor_N has scaling factor of 13 bits, n_cycles 3 and feeback_param_factor_D 1, hence 16.16 precision + uint32_t feedback = ((n_cylces - audio->n_cycles_old) << 3) * audio->feeback_param_factor_N / audio->feeback_param_factor_D; // feeback_param_factor_N has scaling factor of 13 bits, n_cycles 3 and feeback_param_factor_D 1, hence 16.16 precision tud_audio_n_fb_set(i, feedback); audio->n_frames_current = 0; + audio->n_cycles_old = n_cylces; } } } From fd2ea2605e67673d4264b56649612b34fa93807d Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 16 Mar 2022 10:55:18 +0700 Subject: [PATCH 241/504] fix -Wnull-dereference warnings --- src/host/usbh.c | 86 +++++++++++++++++++++++++++---------------------- src/host/usbh.h | 4 +++ 2 files changed, 51 insertions(+), 39 deletions(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index c7dfaddf6..418642891 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -251,7 +251,7 @@ struct TU_ATTR_ALWAYS_INLINE static inline usbh_device_t* get_device(uint8_t dev_addr) { - TU_ASSERT(dev_addr, NULL); + TU_VERIFY(dev_addr > 0 && dev_addr <= TOTAL_DEVICES, NULL); return &_usbh_devices[dev_addr-1]; } @@ -265,15 +265,15 @@ static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t //--------------------------------------------------------------------+ bool tuh_mounted(uint8_t dev_addr) { - return get_device(dev_addr)->configured; + usbh_device_t* dev = get_device(dev_addr); + TU_VERIFY(dev); + return dev->configured; } bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t* vid, uint16_t* pid) { - *vid = *pid = 0; - - TU_VERIFY(tuh_mounted(dev_addr)); usbh_device_t const* dev = get_device(dev_addr); + TU_VERIFY(dev && dev->configured); *vid = dev->vid; *pid = dev->pid; @@ -283,7 +283,8 @@ bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t* vid, uint16_t* pid) tusb_speed_t tuh_speed_get (uint8_t dev_addr) { - return (tusb_speed_t) (dev_addr ? get_device(dev_addr)->speed : _dev0.speed); + usbh_device_t* dev = get_device(dev_addr); + return (tusb_speed_t) (dev ? get_device(dev_addr)->speed : _dev0.speed); } #if CFG_TUSB_OS == OPT_OS_NONE @@ -358,11 +359,8 @@ bool tuh_descriptor_get_string(uint8_t daddr, uint8_t index, uint16_t language_i bool tuh_descriptor_get_manufacturer_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { - TU_VERIFY(tuh_mounted(daddr)); usbh_device_t const* dev = get_device(daddr); - if (dev->i_manufacturer == 0) { - return false; - } + TU_VERIFY(dev && dev->i_manufacturer); return tuh_descriptor_get_string(daddr, dev->i_manufacturer, language_id, buffer, len, complete_cb, user_arg); } @@ -370,11 +368,8 @@ bool tuh_descriptor_get_manufacturer_string(uint8_t daddr, uint16_t language_id, bool tuh_descriptor_get_product_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { - TU_VERIFY(tuh_mounted(daddr)); usbh_device_t const* dev = get_device(daddr); - if (dev->i_product == 0) { - return false; - } + TU_VERIFY(dev && dev->i_product); return tuh_descriptor_get_string(daddr, dev->i_product, language_id, buffer, len, complete_cb, user_arg); } @@ -382,11 +377,8 @@ bool tuh_descriptor_get_product_string(uint8_t daddr, uint16_t language_id, void bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { - TU_VERIFY(tuh_mounted(daddr)); usbh_device_t const* dev = get_device(daddr); - if (dev->i_serial == 0) { - return false; - } + TU_VERIFY(dev && dev->i_serial); return tuh_descriptor_get_string(daddr, dev->i_serial, language_id, buffer, len, complete_cb, user_arg); } @@ -629,6 +621,8 @@ void tuh_task(void) else { usbh_device_t* dev = get_device(event.dev_addr); + TU_ASSERT(dev, ); + dev->ep_status[epnum][ep_dir].busy = 0; dev->ep_status[epnum][ep_dir].claimed = 0; @@ -662,7 +656,8 @@ void tuh_task(void) uint8_t usbh_get_rhport(uint8_t dev_addr) { - return (dev_addr == 0) ? _dev0.rhport : get_device(dev_addr)->rhport; + usbh_device_t* dev = get_device(dev_addr); + return dev ? dev->rhport : _dev0.rhport; } uint8_t* usbh_get_enum_buf(void) @@ -688,10 +683,10 @@ void usbh_int_set(bool enabled) void hcd_devtree_get_info(uint8_t dev_addr, hcd_devtree_info_t* devtree_info) { - if (dev_addr) - { - usbh_device_t const* dev = get_device(dev_addr); + usbh_device_t const* dev = get_device(dev_addr); + if (dev) + { devtree_info->rhport = dev->rhport; devtree_info->hub_addr = dev->hub_addr; devtree_info->hub_port = dev->hub_port; @@ -768,10 +763,11 @@ void hcd_event_device_remove(uint8_t hostid, bool in_isr) // TODO has some duplication code with device, refactor later bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr) { - // addr0 is always available - if (dev_addr == 0) return true; - usbh_device_t* dev = get_device(dev_addr); + + // addr0 only use tuh_control_xfer + TU_ASSERT(dev); + uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); tu_edpt_state_t* ep_state = &dev->ep_status[epnum][dir]; @@ -804,11 +800,12 @@ bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr) // TODO has some duplication code with device, refactor later bool usbh_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) { + usbh_device_t* dev = get_device(dev_addr); + TU_VERIFY(dev); + uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); - usbh_device_t* dev = get_device(dev_addr); - TU_LOG2(" Queue EP %02X with %u bytes ... ", ep_addr, total_bytes); // Attempt to transfer on a busy endpoint, sound like an race condition ! @@ -827,7 +824,7 @@ bool usbh_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_ // HCD error, mark endpoint as ready to allow next transfer dev->ep_status[epnum][dir].busy = false; dev->ep_status[epnum][dir].claimed = 0; - TU_LOG2("failed\r\n"); + TU_LOG1("failed\r\n"); TU_BREAKPOINT(); return false; } @@ -852,9 +849,7 @@ static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size) bool usbh_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep) { - usbh_device_t* dev = get_device(dev_addr); - TU_ASSERT(tu_edpt_validate(desc_ep, (tusb_speed_t) dev->speed)); - + TU_ASSERT( tu_edpt_validate(desc_ep, tuh_speed_get(dev_addr)) ); return hcd_edpt_open(rhport, dev_addr, desc_ep); } @@ -864,6 +859,7 @@ bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) uint8_t const dir = tu_edpt_dir(ep_addr); usbh_device_t* dev = get_device(dev_addr); + TU_VERIFY(dev); return dev->ep_status[epnum][dir].busy; } @@ -1094,7 +1090,7 @@ enum { }; static bool enum_request_set_addr(void); -static bool parse_configuration_descriptor (uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg); +static bool parse_configuration_descriptor (uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg); static void enum_full_complete(void); // process device enumeration @@ -1194,9 +1190,10 @@ static bool process_enumeration(uint8_t dev_addr, tuh_control_xfer_t const * xfe case ENUM_GET_DEVICE_DESC: { - uint8_t const new_addr = (uint8_t const) xfer->request.wValue; + uint8_t const new_addr = (uint8_t) tu_le16toh(xfer->request.wValue); usbh_device_t* new_dev = get_device(new_addr); + TU_ASSERT(new_dev); new_dev->addressed = 1; // TODO close device 0, may not be needed @@ -1215,6 +1212,7 @@ static bool process_enumeration(uint8_t dev_addr, tuh_control_xfer_t const * xfe { tusb_desc_device_t const * desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; usbh_device_t* dev = get_device(dev_addr); + TU_ASSERT(dev); dev->vid = desc_device->idVendor; dev->pid = desc_device->idProduct; @@ -1260,6 +1258,8 @@ static bool process_enumeration(uint8_t dev_addr, tuh_control_xfer_t const * xfe { TU_LOG2("Device configured\r\n"); usbh_device_t* dev = get_device(dev_addr); + TU_ASSERT(dev); + dev->configured = 1; // Start the Set Configuration process for interfaces (itf = DRVID_INVALID) @@ -1324,13 +1324,21 @@ static bool enum_new_device(hcd_event_t* event) static uint8_t get_new_address(bool is_hub) { - uint8_t const start = (is_hub ? CFG_TUH_DEVICE_MAX : 0) + 1; - uint8_t const count = (is_hub ? CFG_TUH_HUB : CFG_TUH_DEVICE_MAX); - - for (uint8_t i=0; i < count; i++) + uint8_t start; + uint8_t end; + if ( is_hub ) { - uint8_t const addr = start + i; - if (!get_device(addr)->connected) return addr; + start = CFG_TUH_DEVICE_MAX; + end = start + CFG_TUH_HUB; + }else + { + start = 0; + end = start + CFG_TUH_DEVICE_MAX; + } + + for ( uint8_t idx = start; idx < end; idx++) + { + if (!_usbh_devices[idx].connected) return (idx+1); } return ADDR_INVALID; } diff --git a/src/host/usbh.h b/src/host/usbh.h index 3bd40c50d..fc0590190 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -201,6 +201,10 @@ uint8_t tuh_descriptor_get_product_string_sync(uint8_t daddr, uint16_t language_ // return transfer result uint8_t tuh_descriptor_get_serial_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, uint8_t timeout_ms); +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ + #ifdef __cplusplus } #endif From 92ac041869b79aba6948e6440bbfc51ba77130ac Mon Sep 17 00:00:00 2001 From: Reinhard Panhuber Date: Wed, 16 Mar 2022 07:13:38 +0100 Subject: [PATCH 242/504] Add todos and comments --- src/class/audio/audio_device.c | 2 ++ src/device/usbd.c | 12 +++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 1dbeb7643..37bf76135 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -2047,6 +2047,8 @@ void audiod_sof (uint8_t rhport, uint32_t frame_count) uint32_t n_cylces = tud_audio_n_get_fm_n_cycles_cb(rhport, audio->ep_fb); uint32_t feedback = ((n_cylces - audio->n_cycles_old) << 3) * audio->feeback_param_factor_N / audio->feeback_param_factor_D; // feeback_param_factor_N has scaling factor of 13 bits, n_cycles 3 and feeback_param_factor_D 1, hence 16.16 precision + // TODO: Implement fast computation in case n_frames * f_s / f_m is a power of two + tud_audio_n_fb_set(i, feedback); audio->n_frames_current = 0; audio->n_cycles_old = n_cylces; diff --git a/src/device/usbd.c b/src/device/usbd.c index 6170c2bda..96ac19c8d 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -587,11 +587,12 @@ void tud_task (void) case DCD_EVENT_SOF: TU_LOG2("\r\n"); - for ( uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++ ) - { - usbd_class_driver_t const * driver = get_driver(i); - if ( driver->sof ) driver->sof(event.rhport, event.sof.frame_count); - } + // TODO: Should this really be done here in the queue? How to distinguish the calls here from those SOF events which should be handled directly in the ISR routine? If we do it like this, the SOF routines get called two time right now, once in the ISR context and once again here +// for ( uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++ ) +// { +// usbd_class_driver_t const * driver = get_driver(i); +// if ( driver->sof ) driver->sof(event.rhport, event.sof.frame_count); +// } break; case USBD_EVENT_FUNC_CALL: @@ -1410,6 +1411,7 @@ void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr) void usbd_sof_enable(uint8_t rhport, bool en) { + // TODO: Check needed if all drivers including the user sof_cb does not need an active SOF ISR any more. Only if all drivers switched off SOF calls the SOF interrupt may be disabled dcd_sof_enable(rhport, en); } From 9fde8f2d9e311afc6ea3707f1ac3b245e0816a4c Mon Sep 17 00:00:00 2001 From: Reinhard Panhuber Date: Wed, 16 Mar 2022 07:53:47 +0100 Subject: [PATCH 243/504] Fix DSTS_FNSOF in dwc2.c --- src/portable/synopsys/dwc2/dcd_dwc2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index d92b17703..ccc16d643 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -1276,7 +1276,7 @@ void dcd_int_handler(uint8_t rhport) if (_sof_en) { - uint32_t frame = (dwc2->dsts & (USB_OTG_DSTS_FNSOF)) >> 8; + uint32_t frame = (dwc2->dsts & (DSTS_FNSOF)) >> 8; dcd_event_sof(rhport, frame, true); } else From ceac9d64c07b95d2c34263386e212e5480cda97c Mon Sep 17 00:00:00 2001 From: Reinhard Panhuber Date: Wed, 16 Mar 2022 08:05:31 +0100 Subject: [PATCH 244/504] Disable CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR By default disable CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR such that current examples still work. --- src/class/audio/audio_device.c | 2 +- src/class/audio/audio_device.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 37bf76135..f0cab4d93 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -430,7 +430,7 @@ static inline uint8_t tu_desc_subtype(void const* desc) } #endif -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR static bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); #endif diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index c9d711a36..eba8a6488 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -193,7 +193,7 @@ // Determine feedback value within SOF ISR within audio driver - if disabled the user has to call tud_audio_n_fb_set() with a suitable feedback value on its own. If done within audio driver SOF ISR, tud_audio_n_fb_set() is disabled for user #ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR -#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR 1 // 0 or 1 +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR 0 // 0 or 1 #endif // Audio interrupt control EP size - disabled if 0 From 98d4ed05845e3a2efb32b0817d635457698b8cc9 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 16 Mar 2022 15:12:59 +0700 Subject: [PATCH 245/504] update hid host to use new control xfer for set config --- src/class/hid/hid_host.c | 211 +++++++++++++++++++-------------------- src/class/msc/msc_host.c | 2 +- src/host/usbh.c | 10 +- 3 files changed, 108 insertions(+), 115 deletions(-) diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index a825858ab..6bcd2f5d3 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -119,11 +119,9 @@ static bool set_protocol_complete(uint8_t dev_addr, tuh_control_xfer_t const * x return true; } -bool tuh_hid_set_protocol(uint8_t dev_addr, uint8_t instance, uint8_t protocol) -{ - hidh_interface_t* hid_itf = get_instance(dev_addr, instance); - TU_VERIFY(hid_itf->itf_protocol != HID_ITF_PROTOCOL_NONE); +static bool _hidh_set_protocol(uint8_t dev_addr, uint8_t itf_num, uint8_t protocol, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) +{ TU_LOG2("HID Set Protocol = %d\r\n", protocol); tuh_control_xfer_t const xfer = @@ -138,19 +136,27 @@ bool tuh_hid_set_protocol(uint8_t dev_addr, uint8_t instance, uint8_t protocol) }, .bRequest = HID_REQ_CONTROL_SET_PROTOCOL, .wValue = protocol, - .wIndex = hid_itf->itf_num, + .wIndex = itf_num, .wLength = 0 }, .buffer = NULL, - .complete_cb = set_protocol_complete, - .user_arg = 0 + .complete_cb = complete_cb, + .user_arg = user_arg }; TU_ASSERT( tuh_control_xfer(dev_addr, &xfer) ); return true; } +bool tuh_hid_set_protocol(uint8_t dev_addr, uint8_t instance, uint8_t protocol) +{ + hidh_interface_t* hid_itf = get_instance(dev_addr, instance); + TU_VERIFY(hid_itf->itf_protocol != HID_ITF_PROTOCOL_NONE); + + return _hidh_set_protocol(dev_addr, hid_itf->itf_num, protocol, set_protocol_complete, 0); +} + static bool set_report_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { TU_LOG2("HID Set Report complete\r\n"); @@ -199,6 +205,36 @@ bool tuh_hid_set_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, u return true; } +static bool _hidh_set_idle(uint8_t dev_addr, uint8_t itf_num, uint16_t idle_rate, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) +{ + // SET IDLE request, device can stall if not support this request + TU_LOG2("HID Set Idle \r\n"); + tuh_control_xfer_t const xfer = + { + .request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HID_REQ_CONTROL_SET_IDLE, + .wValue = idle_rate, + .wIndex = itf_num, + .wLength = 0 + }, + + .buffer = NULL, + .complete_cb = complete_cb, + .user_arg = user_arg + }; + + TU_ASSERT( tuh_control_xfer(dev_addr, &xfer) ); + + return true; +} + //--------------------------------------------------------------------+ // Interrupt Endpoint API //--------------------------------------------------------------------+ @@ -270,12 +306,6 @@ void hidh_close(uint8_t dev_addr) // Enumeration //--------------------------------------------------------------------+ -static bool config_set_protocol (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); -static bool config_get_report_desc (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); -static bool config_get_report_desc_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); - -static void config_driver_mount_complete(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len); - bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len) { (void) max_len; @@ -341,123 +371,88 @@ bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *de return true; } +//--------------------------------------------------------------------+ +// Set Configure +//--------------------------------------------------------------------+ + +enum { + CONFG_SET_IDLE, + CONFIG_SET_PROTOCOL, + CONFIG_GET_REPORT_DESC, + CONFIG_COMPLETE +}; + +static void config_driver_mount_complete(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len); +static bool process_set_config(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); + bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num) { - uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); - hidh_interface_t* hid_itf = get_instance(dev_addr, instance); + tuh_control_xfer_t xfer; + xfer.request.wIndex = tu_htole16((uint16_t) itf_num); + xfer.user_arg = CONFG_SET_IDLE; - // Idle rate = 0 mean only report when there is changes - uint16_t const idle_rate = 0; - - // SET IDLE request, device can stall if not support this request - TU_LOG2("HID Set Idle \r\n"); - tuh_control_xfer_t const xfer = - { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_OUT - }, - .bRequest = HID_REQ_CONTROL_SET_IDLE, - .wValue = idle_rate, - .wIndex = itf_num, - .wLength = 0 - }, - - .buffer = NULL, - .complete_cb = (hid_itf->itf_protocol != HID_ITF_PROTOCOL_NONE) ? config_set_protocol : config_get_report_desc, - .user_arg = 0 - }; - - TU_ASSERT( tuh_control_xfer(dev_addr, &xfer) ); - - return true; + // start the set config process + return process_set_config(dev_addr, &xfer, XFER_RESULT_SUCCESS); } -// Force device to work in BOOT protocol -static bool config_set_protocol(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) +static bool process_set_config(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { // Stall is a valid response for SET_IDLE, therefore we could ignore its result - (void) result; - - uint8_t const itf_num = (uint8_t) xfer->request.wIndex; - uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); - hidh_interface_t* hid_itf = get_instance(dev_addr, instance); - - TU_LOG2("HID Set Protocol to Boot Mode\r\n"); - hid_itf->protocol_mode = HID_PROTOCOL_BOOT; - tuh_control_xfer_t const new_xfer = - { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_OUT - }, - .bRequest = HID_REQ_CONTROL_SET_PROTOCOL, - .wValue = HID_PROTOCOL_BOOT, - .wIndex = hid_itf->itf_num, - .wLength = 0 - }, - - .buffer = NULL, - .complete_cb = config_get_report_desc, - .user_arg = 0 - }; - - TU_ASSERT( tuh_control_xfer(dev_addr, &new_xfer) ); - return true; -} - -static bool config_get_report_desc(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) -{ - // We can be here after SET_IDLE or SET_PROTOCOL (boot device) - // Trigger assert if result is not successful with set protocol if ( xfer->request.bRequest != HID_REQ_CONTROL_SET_IDLE ) { TU_ASSERT(result == XFER_RESULT_SUCCESS); } - uint8_t const itf_num = (uint8_t) xfer->request.wIndex; + uintptr_t const state = xfer->user_arg; + uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->request.wIndex); uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); hidh_interface_t* hid_itf = get_instance(dev_addr, instance); - // Get Report Descriptor if possible - // using usbh enumeration buffer since report descriptor can be very long - if( hid_itf->report_desc_len > CFG_TUH_ENUMERATION_BUFSIZE ) + switch(state) { - TU_LOG2("HID Skip Report Descriptor since it is too large %u bytes\r\n", hid_itf->report_desc_len); + case CONFG_SET_IDLE: + { + // Idle rate = 0 mean only report when there is changes + const uint16_t idle_rate = 0; + const uintptr_t next_state = (hid_itf->itf_protocol != HID_ITF_PROTOCOL_NONE) ? CONFIG_SET_PROTOCOL : CONFIG_GET_REPORT_DESC; + TU_VERIFY( _hidh_set_idle(dev_addr, itf_num, idle_rate, process_set_config, next_state) ); + } + break; - // Driver is mounted without report descriptor - config_driver_mount_complete(dev_addr, instance, NULL, 0); - }else - { - TU_ASSERT(tuh_descriptor_get_hid_report(dev_addr, itf_num, hid_itf->report_desc_type, 0, usbh_get_enum_buf(), hid_itf->report_desc_len, config_get_report_desc_complete, 0)); + case CONFIG_SET_PROTOCOL: + TU_VERIFY(_hidh_set_protocol(dev_addr, hid_itf->itf_num, HID_PROTOCOL_BOOT, process_set_config, CONFIG_GET_REPORT_DESC)); + break; + + case CONFIG_GET_REPORT_DESC: + // Get Report Descriptor if possible + // using usbh enumeration buffer since report descriptor can be very long + if( hid_itf->report_desc_len > CFG_TUH_ENUMERATION_BUFSIZE ) + { + TU_LOG2("HID Skip Report Descriptor since it is too large %u bytes\r\n", hid_itf->report_desc_len); + + // Driver is mounted without report descriptor + config_driver_mount_complete(dev_addr, instance, NULL, 0); + }else + { + TU_ASSERT(tuh_descriptor_get_hid_report(dev_addr, itf_num, hid_itf->report_desc_type, 0, usbh_get_enum_buf(), hid_itf->report_desc_len, process_set_config, CONFIG_COMPLETE)); + } + break; + + case CONFIG_COMPLETE: + { + uint8_t const* desc_report = usbh_get_enum_buf(); + uint16_t const desc_len = xfer->request.wLength; + + config_driver_mount_complete(dev_addr, instance, desc_report, desc_len); + } + break; + + default: break; } return true; } -static bool config_get_report_desc_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) -{ - TU_ASSERT(XFER_RESULT_SUCCESS == result); - - uint8_t const itf_num = (uint8_t) xfer->request.wIndex; - uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); - - uint8_t const* desc_report = usbh_get_enum_buf(); - uint16_t const desc_len = xfer->request.wLength; - - config_driver_mount_complete(dev_addr, instance, desc_report, desc_len); - - return true; -} - static void config_driver_mount_complete(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len) { hidh_interface_t* hid_itf = get_instance(dev_addr, instance); diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index c009e5088..b3af65942 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -483,7 +483,7 @@ static bool config_read_capacity_complete(uint8_t dev_addr, msc_cbw_t const* cbw // Capacity response field: Block size and Last LBA are both Big-Endian scsi_read_capacity10_resp_t* resp = (scsi_read_capacity10_resp_t*) ((void*) _msch_buffer); p_msc->capacity[cbw->lun].block_count = tu_ntohl(resp->last_lba) + 1; - p_msc->capacity[cbw->lun].block_size = tu_ntohl(resp->block_size); + p_msc->capacity[cbw->lun].block_size = tu_ntohl(resp->block_size); // Mark enumeration is complete p_msc->mounted = true; diff --git a/src/host/usbh.c b/src/host/usbh.c index 418642891..83bca2205 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -1297,12 +1297,10 @@ static bool enum_new_device(hcd_event_t* event) _dev0.speed = hcd_port_speed_get(_dev0.rhport ); TU_LOG2("%s Speed\r\n", tu_str_speed[_dev0.speed]); - //enum_request_addr0_device_desc(); - tuh_control_xfer_t const xfer = - { - .complete_cb = process_enumeration, - .user_arg = ENUM_ADDR0_DEVICE_DESC - }; + // start the enumeration process + tuh_control_xfer_t xfer; + xfer.user_arg = ENUM_ADDR0_DEVICE_DESC; + process_enumeration(0, &xfer, XFER_RESULT_SUCCESS); } From 68bfd048a54d1ff2def4cb1ee5285eacdb55f143 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 17 Mar 2022 12:53:52 +0700 Subject: [PATCH 246/504] change tuh_control_xfer_t struct --- src/class/cdc/cdc_host.c | 30 ++++--- src/class/hid/hid_host.c | 115 +++++++++++++------------ src/class/msc/msc_host.c | 30 ++++--- src/host/hub.c | 130 +++++++++++++++------------- src/host/usbh.c | 182 ++++++++++++++++++++++++--------------- src/host/usbh.h | 27 ++++-- 6 files changed, 292 insertions(+), 222 deletions(-) diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 8ca3dfbcb..9838df818 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -124,22 +124,24 @@ bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_co { cdch_data_t const * p_cdc = get_itf(dev_addr); + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = CDC_REQUEST_SET_CONTROL_LINE_STATE, + .wValue = (rts ? 2 : 0) | (dtr ? 1 : 0), + .wIndex = p_cdc->itf_num, + .wLength = 0 + }; + tuh_control_xfer_t const xfer = { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_OUT - }, - .bRequest = CDC_REQUEST_SET_CONTROL_LINE_STATE, - .wValue = (rts ? 2 : 0) | (dtr ? 1 : 0), - .wIndex = p_cdc->itf_num, - .wLength = 0 - }, - + .ep_addr = 0, + .setup = &request, .buffer = NULL, .complete_cb = complete_cb, .user_arg = 0 diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 6bcd2f5d3..8c1a5ebc9 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -105,11 +105,11 @@ uint8_t tuh_hid_get_protocol(uint8_t dev_addr, uint8_t instance) static bool set_protocol_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { - uint8_t const itf_num = (uint8_t) xfer->request.wIndex; + uint8_t const itf_num = (uint8_t) xfer->setup->wIndex; uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); hidh_interface_t* hid_itf = get_instance(dev_addr, instance); - if (XFER_RESULT_SUCCESS == result) hid_itf->protocol_mode = (uint8_t) xfer->request.wValue; + if (XFER_RESULT_SUCCESS == result) hid_itf->protocol_mode = (uint8_t) xfer->setup->wValue; if (tuh_hid_set_protocol_complete_cb) { @@ -124,22 +124,24 @@ static bool _hidh_set_protocol(uint8_t dev_addr, uint8_t itf_num, uint8_t protoc { TU_LOG2("HID Set Protocol = %d\r\n", protocol); + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HID_REQ_CONTROL_SET_PROTOCOL, + .wValue = protocol, + .wIndex = itf_num, + .wLength = 0 + }; + tuh_control_xfer_t const xfer = { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_OUT - }, - .bRequest = HID_REQ_CONTROL_SET_PROTOCOL, - .wValue = protocol, - .wIndex = itf_num, - .wLength = 0 - }, - + .ep_addr = 0, + .setup = &request, .buffer = NULL, .complete_cb = complete_cb, .user_arg = user_arg @@ -163,13 +165,13 @@ static bool set_report_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfe if (tuh_hid_set_report_complete_cb) { - uint8_t const itf_num = (uint8_t) xfer->request.wIndex; + uint8_t const itf_num = (uint8_t) xfer->setup->wIndex; uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); - uint8_t const report_type = tu_u16_high(xfer->request.wValue); - uint8_t const report_id = tu_u16_low(xfer->request.wValue); + uint8_t const report_type = tu_u16_high(xfer->setup->wValue); + uint8_t const report_id = tu_u16_low(xfer->setup->wValue); - tuh_hid_set_report_complete_cb(dev_addr, instance, report_id, report_type, (result == XFER_RESULT_SUCCESS) ? xfer->request.wLength : 0); + tuh_hid_set_report_complete_cb(dev_addr, instance, report_id, report_type, (result == XFER_RESULT_SUCCESS) ? xfer->setup->wLength : 0); } return true; @@ -180,22 +182,24 @@ bool tuh_hid_set_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, u hidh_interface_t* hid_itf = get_instance(dev_addr, instance); TU_LOG2("HID Set Report: id = %u, type = %u, len = %u\r\n", report_id, report_type, len); + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HID_REQ_CONTROL_SET_REPORT, + .wValue = tu_u16(report_type, report_id), + .wIndex = hid_itf->itf_num, + .wLength = len + }; + tuh_control_xfer_t const xfer = { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_OUT - }, - .bRequest = HID_REQ_CONTROL_SET_REPORT, - .wValue = tu_u16(report_type, report_id), - .wIndex = hid_itf->itf_num, - .wLength = len - }, - + .ep_addr = 0, + .setup = &request, .buffer = report, .complete_cb = set_report_complete, .user_arg = 0 @@ -209,22 +213,24 @@ static bool _hidh_set_idle(uint8_t dev_addr, uint8_t itf_num, uint16_t idle_rate { // SET IDLE request, device can stall if not support this request TU_LOG2("HID Set Idle \r\n"); + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HID_REQ_CONTROL_SET_IDLE, + .wValue = idle_rate, + .wIndex = itf_num, + .wLength = 0 + }; + tuh_control_xfer_t const xfer = { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_OUT - }, - .bRequest = HID_REQ_CONTROL_SET_IDLE, - .wValue = idle_rate, - .wIndex = itf_num, - .wLength = 0 - }, - + .ep_addr = 0, + .setup = &request, .buffer = NULL, .complete_cb = complete_cb, .user_arg = user_arg @@ -387,24 +393,27 @@ static bool process_set_config(uint8_t dev_addr, tuh_control_xfer_t const * xfer bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num) { + tusb_control_request_t request; + request.wIndex = tu_htole16((uint16_t) itf_num); + tuh_control_xfer_t xfer; - xfer.request.wIndex = tu_htole16((uint16_t) itf_num); + xfer.setup = &request; xfer.user_arg = CONFG_SET_IDLE; - // start the set config process + // fake request to start the set config process return process_set_config(dev_addr, &xfer, XFER_RESULT_SUCCESS); } static bool process_set_config(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { // Stall is a valid response for SET_IDLE, therefore we could ignore its result - if ( xfer->request.bRequest != HID_REQ_CONTROL_SET_IDLE ) + if ( xfer->setup->bRequest != HID_REQ_CONTROL_SET_IDLE ) { TU_ASSERT(result == XFER_RESULT_SUCCESS); } uintptr_t const state = xfer->user_arg; - uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->request.wIndex); + uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); hidh_interface_t* hid_itf = get_instance(dev_addr, instance); @@ -441,7 +450,7 @@ static bool process_set_config(uint8_t dev_addr, tuh_control_xfer_t const * xfer case CONFIG_COMPLETE: { uint8_t const* desc_report = usbh_get_enum_buf(); - uint16_t const desc_len = xfer->request.wLength; + uint16_t const desc_len = xfer->setup->wLength; config_driver_mount_complete(dev_addr, instance, desc_report, desc_len); } diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index b3af65942..d8910db0f 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -405,22 +405,24 @@ bool msch_set_config(uint8_t dev_addr, uint8_t itf_num) //------------- Get Max Lun -------------// TU_LOG2("MSC Get Max Lun\r\n"); + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN + }, + .bRequest = MSC_REQ_GET_MAX_LUN, + .wValue = 0, + .wIndex = itf_num, + .wLength = 1 + }; + tuh_control_xfer_t const xfer = { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_IN - }, - .bRequest = MSC_REQ_GET_MAX_LUN, - .wValue = 0, - .wIndex = itf_num, - .wLength = 1 - }, - + .ep_addr = 0, + .setup = &request, .buffer = &p_msc->max_lun, .complete_cb = config_get_maxlun_complete, .user_arg = 0 diff --git a/src/host/hub.c b/src/host/hub.c index c1909cb5c..6ce9e4cc6 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -80,22 +80,24 @@ static char const* const _hub_feature_str[] = bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_OTHER, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HUB_REQUEST_CLEAR_FEATURE, + .wValue = feature, + .wIndex = hub_port, + .wLength = 0 + }; + tuh_control_xfer_t const xfer = { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_OTHER, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_OUT - }, - .bRequest = HUB_REQUEST_CLEAR_FEATURE, - .wValue = feature, - .wIndex = hub_port, - .wLength = 0 - }, - + .ep_addr = 0, + .setup = &request, .buffer = NULL, .complete_cb = complete_cb, .user_arg = user_arg @@ -109,22 +111,24 @@ bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_OTHER, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HUB_REQUEST_SET_FEATURE, + .wValue = feature, + .wIndex = hub_port, + .wLength = 0 + }; + tuh_control_xfer_t const xfer = { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_OTHER, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_OUT - }, - .bRequest = HUB_REQUEST_SET_FEATURE, - .wValue = feature, - .wIndex = hub_port, - .wLength = 0 - }, - + .ep_addr = 0, + .setup = &request, .buffer = NULL, .complete_cb = complete_cb, .user_arg = user_arg @@ -138,22 +142,24 @@ bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_OTHER, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN + }, + .bRequest = HUB_REQUEST_GET_STATUS, + .wValue = 0, + .wIndex = hub_port, + .wLength = 4 + }; + tuh_control_xfer_t const xfer = { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_OTHER, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_IN - }, - .bRequest = HUB_REQUEST_GET_STATUS, - .wValue = 0, - .wIndex = hub_port, - .wLength = 4 - }, - + .ep_addr = 0, + .setup = &request, .buffer = resp, .complete_cb = complete_cb, .user_arg = user_arg @@ -228,22 +234,24 @@ bool hub_set_config(uint8_t dev_addr, uint8_t itf_num) TU_ASSERT(itf_num == p_hub->itf_num); // Get Hub Descriptor + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN + }, + .bRequest = HUB_REQUEST_GET_DESCRIPTOR, + .wValue = 0, + .wIndex = 0, + .wLength = sizeof(descriptor_hub_desc_t) + }; + tuh_control_xfer_t const xfer = { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_DEVICE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_IN - }, - .bRequest = HUB_REQUEST_GET_DESCRIPTOR, - .wValue = 0, - .wIndex = 0, - .wLength = sizeof(descriptor_hub_desc_t) - }, - + .ep_addr = 0, + .setup = &request, .buffer = _hub_buffer, .complete_cb = config_set_port_power, .user_arg = 0 @@ -277,7 +285,7 @@ static bool config_port_power_complete (uint8_t dev_addr, tuh_control_xfer_t con TU_ASSERT(XFER_RESULT_SUCCESS == result); hub_interface_t* p_hub = get_itf(dev_addr); - if (xfer->request.wIndex == p_hub->port_count) + if (xfer->setup->wIndex == p_hub->port_count) { // All ports are power -> queue notification status endpoint and // complete the SET CONFIGURATION @@ -287,7 +295,7 @@ static bool config_port_power_complete (uint8_t dev_addr, tuh_control_xfer_t con }else { // power next port - uint8_t const hub_port = (uint8_t) (xfer->request.wIndex + 1); + uint8_t const hub_port = (uint8_t) (xfer->setup->wIndex + 1); return hub_port_set_feature(dev_addr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete, 0); } @@ -333,7 +341,7 @@ static bool connection_get_status_complete (uint8_t dev_addr, tuh_control_xfer_t TU_ASSERT(result == XFER_RESULT_SUCCESS); hub_interface_t* p_hub = get_itf(dev_addr); - uint8_t const port_num = (uint8_t) xfer->request.wIndex; + uint8_t const port_num = (uint8_t) xfer->setup->wIndex; // Connection change if (p_hub->port_status.change.connection) @@ -361,7 +369,7 @@ static bool connection_clear_conn_change_complete (uint8_t dev_addr, tuh_control TU_ASSERT(result == XFER_RESULT_SUCCESS); hub_interface_t* p_hub = get_itf(dev_addr); - uint8_t const port_num = (uint8_t) xfer->request.wIndex; + uint8_t const port_num = (uint8_t) xfer->setup->wIndex; if ( p_hub->port_status.status.connection ) { @@ -392,7 +400,7 @@ static bool connection_port_reset_complete (uint8_t dev_addr, tuh_control_xfer_t TU_ASSERT(result == XFER_RESULT_SUCCESS); // hub_interface_t* p_hub = get_itf(dev_addr); - uint8_t const port_num = (uint8_t) xfer->request.wIndex; + uint8_t const port_num = (uint8_t) xfer->setup->wIndex; // submit attach event hcd_event_t event = diff --git a/src/host/usbh.c b/src/host/usbh.c index 83bca2205..d2d819ec2 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -109,6 +109,10 @@ typedef struct { tu_edpt_state_t ep_status[CFG_TUH_ENDPOINT_MAX][2]; +#if CFG_TUH_BARE + +#endif + } usbh_device_t; //--------------------------------------------------------------------+ @@ -241,7 +245,11 @@ static uint8_t _usbh_ctrl_buf[CFG_TUH_ENUMERATION_BUFSIZE]; // We will only execute control transfer one at a time. struct { - tuh_control_xfer_t xfer; + tusb_control_request_t request TU_ATTR_ALIGNED(4); + uint8_t* buffer; + tuh_control_xfer_cb_t complete_cb; + uintptr_t user_arg; + uint8_t daddr; // device address that is transferring volatile uint8_t stage; }_ctrl_xfer; @@ -304,22 +312,24 @@ void osal_task_delay(uint32_t msec) static bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t language_id, void* buffer, uint16_t len, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_IN + }, + .bRequest = TUSB_REQ_GET_DESCRIPTOR, + .wValue = tu_htole16( TU_U16(type, index) ), + .wIndex = tu_htole16(language_id), + .wLength = tu_htole16(len) + }; + tuh_control_xfer_t const xfer = { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_DEVICE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_IN - }, - .bRequest = TUSB_REQ_GET_DESCRIPTOR, - .wValue = tu_htole16( TU_U16(type, index) ), - .wIndex = tu_htole16(language_id), - .wLength = tu_htole16(len) - }, - + .ep_addr = 0, + .setup = &request, .buffer = buffer, .complete_cb = complete_cb, .user_arg = user_arg @@ -387,22 +397,24 @@ bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_ tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { TU_LOG2("HID Get Report Descriptor\r\n"); + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_IN + }, + .bRequest = TUSB_REQ_GET_DESCRIPTOR, + .wValue = tu_htole16(TU_U16(desc_type, index)), + .wIndex = tu_htole16((uint16_t) itf_num), + .wLength = len + }; + tuh_control_xfer_t const xfer = { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_IN - }, - .bRequest = TUSB_REQ_GET_DESCRIPTOR, - .wValue = tu_htole16(TU_U16(desc_type, index)), - .wIndex = tu_htole16((uint16_t) itf_num), - .wLength = len - }, - + .ep_addr = 0, + .setup = &request, .buffer = buffer, .complete_cb = complete_cb, .user_arg = user_arg @@ -416,22 +428,24 @@ bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, { TU_LOG2("Set Configuration = %d\r\n", config_num); + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_OUT + }, + .bRequest = TUSB_REQ_SET_CONFIGURATION, + .wValue = tu_htole16(config_num), + .wIndex = 0, + .wLength = 0 + }; + tuh_control_xfer_t const xfer = { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_DEVICE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_OUT - }, - .bRequest = TUSB_REQ_SET_CONFIGURATION, - .wValue = tu_htole16(config_num), - .wIndex = 0, - .wLength = 0 - }, - + .ep_addr = 0, + .setup = &request, .buffer = NULL, .complete_cb = complete_cb, .user_arg = user_arg @@ -895,16 +909,19 @@ bool tuh_control_xfer (uint8_t daddr, tuh_control_xfer_t const* xfer) const uint8_t rhport = usbh_get_rhport(daddr); - TU_LOG2("[%u:%u] %s: ", rhport, daddr, xfer->request.bRequest <= TUSB_REQ_SYNCH_FRAME ? tu_str_std_request[xfer->request.bRequest] : "Unknown Request"); - TU_LOG2_VAR(&xfer->request); + TU_LOG2("[%u:%u] %s: ", rhport, daddr, xfer->setup->bRequest <= TUSB_REQ_SYNCH_FRAME ? tu_str_std_request[xfer->setup->bRequest] : "Unknown Request"); + TU_LOG2_VAR(&xfer->setup); TU_LOG2("\r\n"); - _ctrl_xfer.daddr = daddr; - _ctrl_xfer.xfer = (*xfer); + _ctrl_xfer.daddr = daddr; + _ctrl_xfer.request = (*xfer->setup); + _ctrl_xfer.buffer = xfer->buffer; + _ctrl_xfer.complete_cb = xfer->complete_cb; + _ctrl_xfer.user_arg = xfer->user_arg; if (xfer->complete_cb) { - TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t*) &_ctrl_xfer.xfer.request) ); + TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t*) &_ctrl_xfer.request) ); }else { // user_arg must point to xfer_result_t to hold result @@ -914,10 +931,10 @@ bool tuh_control_xfer (uint8_t daddr, tuh_control_xfer_t const* xfer) // change callback to internal blocking, and result as user argument volatile xfer_result_t* result = (volatile xfer_result_t*) xfer->user_arg; - _ctrl_xfer.xfer.complete_cb = _control_blocking_complete_cb; + _ctrl_xfer.complete_cb = _control_blocking_complete_cb; *result = XFER_RESULT_INVALID; - TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t*) &_ctrl_xfer.xfer.request) ); + TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t*) &_ctrl_xfer.request) ); while ((*result) == XFER_RESULT_INVALID) { @@ -961,7 +978,16 @@ static void _xfer_complete(uint8_t dev_addr, xfer_result_t result) TU_LOG2("\r\n"); // duplicate xfer since user can execute control transfer within callback - tuh_control_xfer_t const xfer_temp = _ctrl_xfer.xfer; + tusb_control_request_t const request = _ctrl_xfer.request; + tuh_control_xfer_t const xfer_temp = + { + .ep_addr = 0, + .setup = &request, + .actual_len = 0, + .buffer = _ctrl_xfer.buffer, + .complete_cb = _ctrl_xfer.complete_cb, + .user_arg = _ctrl_xfer.user_arg + }; usbh_lock(); _ctrl_xfer.stage = CONTROL_STAGE_IDLE; @@ -979,7 +1005,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result (void) xferred_bytes; const uint8_t rhport = usbh_get_rhport(dev_addr); - tusb_control_request_t const * request = &_ctrl_xfer.xfer.request; + tusb_control_request_t const * request = &_ctrl_xfer.request; if (XFER_RESULT_SUCCESS != result) { @@ -996,7 +1022,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result { // DATA stage: initial data toggle is always 1 set_control_xfer_stage(CONTROL_STAGE_DATA); - return hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.xfer.buffer, request->wLength); + return hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.buffer, request->wLength); } __attribute__((fallthrough)); @@ -1004,7 +1030,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result if (request->wLength) { TU_LOG2("[%u:%u] Control data:\r\n", rhport, dev_addr); - TU_LOG2_MEM(_ctrl_xfer.xfer.buffer, request->wLength, 2); + TU_LOG2_MEM(_ctrl_xfer.buffer, request->wLength, 2); } // ACK stage: toggle is always 1 @@ -1190,7 +1216,7 @@ static bool process_enumeration(uint8_t dev_addr, tuh_control_xfer_t const * xfe case ENUM_GET_DEVICE_DESC: { - uint8_t const new_addr = (uint8_t) tu_le16toh(xfer->request.wValue); + uint8_t const new_addr = (uint8_t) tu_le16toh(xfer->setup->wValue); usbh_device_t* new_dev = get_device(new_addr); TU_ASSERT(new_dev); @@ -1320,6 +1346,12 @@ static bool enum_new_device(hcd_event_t* event) return true; } +TU_ATTR_ALWAYS_INLINE +static inline bool is_hub_addr(uint8_t daddr) +{ + return daddr > CFG_TUH_DEVICE_MAX; +} + static uint8_t get_new_address(bool is_hub) { uint8_t start; @@ -1360,22 +1392,24 @@ static bool enum_request_set_addr(void) new_dev->connected = 1; new_dev->ep0_size = desc_device->bMaxPacketSize0; + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_OUT + }, + .bRequest = TUSB_REQ_SET_ADDRESS, + .wValue = tu_htole16(new_addr), + .wIndex = 0, + .wLength = 0 + }; + tuh_control_xfer_t const xfer = { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_DEVICE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_OUT - }, - .bRequest = TUSB_REQ_SET_ADDRESS, - .wValue = tu_htole16(new_addr), - .wIndex = 0, - .wLength = 0 - }, - + .ep_addr = 0, + .setup = &request, .buffer = NULL, .complete_cb = process_enumeration, .user_arg = ENUM_GET_DEVICE_DESC @@ -1503,8 +1537,14 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) { enum_full_complete(); - // Invoke callback if available - if (tuh_mount_cb) tuh_mount_cb(dev_addr); +#if CFG_TUH_HUB + // skip device mount callback for hub + if ( !is_hub_addr(dev_addr) ) +#endif + { + // Invoke callback if available + if (tuh_mount_cb) tuh_mount_cb(dev_addr); + } } } diff --git a/src/host/usbh.h b/src/host/usbh.h index fc0590190..7dffcb453 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -46,7 +46,10 @@ typedef bool (*tuh_control_xfer_cb_t)(uint8_t daddr, tuh_control_xfer_t const * struct tuh_control_xfer_s { - tusb_control_request_t request TU_ATTR_ALIGNED(4); + uint8_t ep_addr; + tusb_control_request_t const* setup; + uint32_t actual_len; + uint8_t* buffer; tuh_control_xfer_cb_t complete_cb; uintptr_t user_arg; @@ -104,14 +107,16 @@ static inline bool tuh_ready(uint8_t daddr) return tuh_mounted(daddr) && !tuh_suspended(daddr); } +//--------------------------------------------------------------------+ +// Endpoint Asynchronous (non-blocking) +//--------------------------------------------------------------------+ + // Carry out a control transfer // true on success, false if there is on-going control transfer or incorrect parameters // Blocking if complete callback is NULL, in this case 'user_arg' must contain xfer_result_t variable -bool tuh_control_xfer (uint8_t daddr, tuh_control_xfer_t const* xfer); +bool tuh_control_xfer(uint8_t daddr, tuh_control_xfer_t const* xfer); -// Sync (blocking) version of tuh_control_xfer() -// return transfer result -uint8_t tuh_control_xfer_sync(uint8_t daddr, tuh_control_xfer_t const* xfer, uint32_t timeout_ms); +//bool tuh_edpt_xfer(uint8_t daddr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes); // Set Configuration (control transfer) // config_num = 0 will un-configure device. Note: config_num = config_descriptor_index + 1 @@ -120,6 +125,14 @@ uint8_t tuh_control_xfer_sync(uint8_t daddr, tuh_control_xfer_t const* xfer, uin bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); +//--------------------------------------------------------------------+ +// Endpoint Synchronous (blocking) +//--------------------------------------------------------------------+ + +// Sync (blocking) version of tuh_control_xfer() +// return transfer result +uint8_t tuh_control_xfer_sync(uint8_t daddr, tuh_control_xfer_t const* xfer, uint32_t timeout_ms); + //--------------------------------------------------------------------+ // Descriptors Asynchronous (non-blocking) //--------------------------------------------------------------------+ @@ -201,10 +214,6 @@ uint8_t tuh_descriptor_get_product_string_sync(uint8_t daddr, uint16_t language_ // return transfer result uint8_t tuh_descriptor_get_serial_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, uint8_t timeout_ms); -//--------------------------------------------------------------------+ -// -//--------------------------------------------------------------------+ - #ifdef __cplusplus } #endif From 6df420f7f31b4fbf9b95987211e9ed9fef58ac00 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 17 Mar 2022 16:24:43 +0700 Subject: [PATCH 247/504] move result into transfer struct --- examples/host/bare_api/src/main.c | 6 ++---- src/class/hid/hid_host.c | 20 +++++++++++--------- src/class/msc/msc_host.c | 8 +++----- src/host/hub.c | 31 +++++++++++++++---------------- src/host/usbh.c | 26 +++++++++++++------------- src/host/usbh.h | 6 +++++- 6 files changed, 49 insertions(+), 48 deletions(-) diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index 9e6209991..8da7f6a0c 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -115,11 +115,9 @@ static void utf16_to_utf8(uint16_t *temp_buf, size_t buf_len) { ((uint8_t*) temp_buf)[utf8_len] = '\0'; } -bool print_device_descriptor(uint8_t daddr, tuh_control_xfer_t const * xfer, xfer_result_t result) +bool print_device_descriptor(uint8_t daddr, tuh_control_xfer_t const * xfer) { - (void) xfer; - - if ( XFER_RESULT_SUCCESS != result ) + if ( XFER_RESULT_SUCCESS != xfer->result ) { printf("Failed to get device descriptor\r\n"); return false; diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 8c1a5ebc9..564b927e2 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -103,13 +103,13 @@ uint8_t tuh_hid_get_protocol(uint8_t dev_addr, uint8_t instance) return hid_itf->protocol_mode; } -static bool set_protocol_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) +static bool set_protocol_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer) { uint8_t const itf_num = (uint8_t) xfer->setup->wIndex; uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); hidh_interface_t* hid_itf = get_instance(dev_addr, instance); - if (XFER_RESULT_SUCCESS == result) hid_itf->protocol_mode = (uint8_t) xfer->setup->wValue; + if (XFER_RESULT_SUCCESS == xfer->result) hid_itf->protocol_mode = (uint8_t) xfer->setup->wValue; if (tuh_hid_set_protocol_complete_cb) { @@ -159,7 +159,7 @@ bool tuh_hid_set_protocol(uint8_t dev_addr, uint8_t instance, uint8_t protocol) return _hidh_set_protocol(dev_addr, hid_itf->itf_num, protocol, set_protocol_complete, 0); } -static bool set_report_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) +static bool set_report_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer) { TU_LOG2("HID Set Report complete\r\n"); @@ -171,7 +171,8 @@ static bool set_report_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfe uint8_t const report_type = tu_u16_high(xfer->setup->wValue); uint8_t const report_id = tu_u16_low(xfer->setup->wValue); - tuh_hid_set_report_complete_cb(dev_addr, instance, report_id, report_type, (result == XFER_RESULT_SUCCESS) ? xfer->setup->wLength : 0); + tuh_hid_set_report_complete_cb(dev_addr, instance, report_id, report_type, + (xfer->result == XFER_RESULT_SUCCESS) ? xfer->setup->wLength : 0); } return true; @@ -389,7 +390,7 @@ enum { }; static void config_driver_mount_complete(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len); -static bool process_set_config(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); +static bool process_set_config(uint8_t dev_addr, tuh_control_xfer_t const * xfer); bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num) { @@ -397,19 +398,20 @@ bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num) request.wIndex = tu_htole16((uint16_t) itf_num); tuh_control_xfer_t xfer; + xfer.result = XFER_RESULT_SUCCESS; xfer.setup = &request; xfer.user_arg = CONFG_SET_IDLE; - // fake request to start the set config process - return process_set_config(dev_addr, &xfer, XFER_RESULT_SUCCESS); + // fake request to kick-off the set config process + return process_set_config(dev_addr, &xfer); } -static bool process_set_config(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) +static bool process_set_config(uint8_t dev_addr, tuh_control_xfer_t const * xfer) { // Stall is a valid response for SET_IDLE, therefore we could ignore its result if ( xfer->setup->bRequest != HID_REQ_CONTROL_SET_IDLE ) { - TU_ASSERT(result == XFER_RESULT_SUCCESS); + TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS); } uintptr_t const state = xfer->user_arg; diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index d8910db0f..ca1080eba 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -358,7 +358,7 @@ bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32 // MSC Enumeration //--------------------------------------------------------------------+ -static bool config_get_maxlun_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); +static bool config_get_maxlun_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer); static bool config_test_unit_ready_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); static bool config_request_sense_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); static bool config_read_capacity_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); @@ -432,14 +432,12 @@ bool msch_set_config(uint8_t dev_addr, uint8_t itf_num) return true; } -static bool config_get_maxlun_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) +static bool config_get_maxlun_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer) { - (void) xfer; - msch_interface_t* p_msc = get_itf(dev_addr); // STALL means zero - p_msc->max_lun = (XFER_RESULT_SUCCESS == result) ? _msch_buffer[0] : 0; + p_msc->max_lun = (XFER_RESULT_SUCCESS == xfer->result) ? _msch_buffer[0] : 0; p_msc->max_lun++; // MAX LUN is minus 1 by specs // TODO multiple LUN support diff --git a/src/host/hub.c b/src/host/hub.c index 6ce9e4cc6..5255fdf7c 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -225,8 +225,8 @@ bool hub_edpt_status_xfer(uint8_t dev_addr) // Set Configure //--------------------------------------------------------------------+ -static bool config_set_port_power (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); -static bool config_port_power_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); +static bool config_set_port_power (uint8_t dev_addr, tuh_control_xfer_t const * xfer); +static bool config_port_power_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer); bool hub_set_config(uint8_t dev_addr, uint8_t itf_num) { @@ -262,10 +262,9 @@ bool hub_set_config(uint8_t dev_addr, uint8_t itf_num) return true; } -static bool config_set_port_power (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) +static bool config_set_port_power (uint8_t dev_addr, tuh_control_xfer_t const * xfer) { - (void) xfer; - TU_ASSERT(XFER_RESULT_SUCCESS == result); + TU_ASSERT(XFER_RESULT_SUCCESS == xfer->result); hub_interface_t* p_hub = get_itf(dev_addr); @@ -280,9 +279,9 @@ static bool config_set_port_power (uint8_t dev_addr, tuh_control_xfer_t const * return hub_port_set_feature(dev_addr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete, 0); } -static bool config_port_power_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) +static bool config_port_power_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer) { - TU_ASSERT(XFER_RESULT_SUCCESS == result); + TU_ASSERT(XFER_RESULT_SUCCESS == xfer->result); hub_interface_t* p_hub = get_itf(dev_addr); if (xfer->setup->wIndex == p_hub->port_count) @@ -306,9 +305,9 @@ static bool config_port_power_complete (uint8_t dev_addr, tuh_control_xfer_t con // Connection Changes //--------------------------------------------------------------------+ -static bool connection_get_status_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); -static bool connection_clear_conn_change_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); -static bool connection_port_reset_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result); +static bool connection_get_status_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer); +static bool connection_clear_conn_change_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer); +static bool connection_port_reset_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer); // callback as response of interrupt endpoint polling bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) @@ -336,9 +335,9 @@ bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32 return true; } -static bool connection_get_status_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) +static bool connection_get_status_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer) { - TU_ASSERT(result == XFER_RESULT_SUCCESS); + TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS); hub_interface_t* p_hub = get_itf(dev_addr); uint8_t const port_num = (uint8_t) xfer->setup->wIndex; @@ -364,9 +363,9 @@ static bool connection_get_status_complete (uint8_t dev_addr, tuh_control_xfer_t return true; } -static bool connection_clear_conn_change_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) +static bool connection_clear_conn_change_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer) { - TU_ASSERT(result == XFER_RESULT_SUCCESS); + TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS); hub_interface_t* p_hub = get_itf(dev_addr); uint8_t const port_num = (uint8_t) xfer->setup->wIndex; @@ -395,9 +394,9 @@ static bool connection_clear_conn_change_complete (uint8_t dev_addr, tuh_control return true; } -static bool connection_port_reset_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) +static bool connection_port_reset_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer) { - TU_ASSERT(result == XFER_RESULT_SUCCESS); + TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS); // hub_interface_t* p_hub = get_itf(dev_addr); uint8_t const port_num = (uint8_t) xfer->setup->wIndex; diff --git a/src/host/usbh.c b/src/host/usbh.c index d2d819ec2..00afe609f 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -882,12 +882,12 @@ bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) // Control transfer //--------------------------------------------------------------------+ -static bool _control_blocking_complete_cb(uint8_t daddr, tuh_control_xfer_t const * xfer, xfer_result_t result) +static bool _control_blocking_complete_cb(uint8_t daddr, tuh_control_xfer_t const * xfer) { (void) daddr; // update result - *((xfer_result_t*) xfer->user_arg) = result; + *((xfer_result_t*) xfer->user_arg) = xfer->result; return true; } @@ -924,19 +924,17 @@ bool tuh_control_xfer (uint8_t daddr, tuh_control_xfer_t const* xfer) TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t*) &_ctrl_xfer.request) ); }else { - // user_arg must point to xfer_result_t to hold result - TU_VERIFY(xfer->user_arg); - // blocking if complete callback is not provided // change callback to internal blocking, and result as user argument - volatile xfer_result_t* result = (volatile xfer_result_t*) xfer->user_arg; + volatile xfer_result_t result = XFER_RESULT_INVALID; + // use user_arg to point to xfer_result_t + _ctrl_xfer.user_arg = (uintptr_t) &result; _ctrl_xfer.complete_cb = _control_blocking_complete_cb; - *result = XFER_RESULT_INVALID; TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t*) &_ctrl_xfer.request) ); - while ((*result) == XFER_RESULT_INVALID) + while (result == XFER_RESULT_INVALID) { // only need to call task if not preempted RTOS #if CFG_TUSB_OS == OPT_OS_NONE || CFG_TUSB_OS == OPT_OS_PICO @@ -982,6 +980,7 @@ static void _xfer_complete(uint8_t dev_addr, xfer_result_t result) tuh_control_xfer_t const xfer_temp = { .ep_addr = 0, + .result = result, .setup = &request, .actual_len = 0, .buffer = _ctrl_xfer.buffer, @@ -995,7 +994,7 @@ static void _xfer_complete(uint8_t dev_addr, xfer_result_t result) if (xfer_temp.complete_cb) { - xfer_temp.complete_cb(dev_addr, &xfer_temp, result); + xfer_temp.complete_cb(dev_addr, &xfer_temp); } } @@ -1120,9 +1119,9 @@ static bool parse_configuration_descriptor (uint8_t dev_addr, tusb_desc_configur static void enum_full_complete(void); // process device enumeration -static bool process_enumeration(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) +static bool process_enumeration(uint8_t dev_addr, tuh_control_xfer_t const * xfer) { - if (XFER_RESULT_SUCCESS != result) + if (XFER_RESULT_SUCCESS != xfer->result) { // stop enumeration, maybe we could retry this enum_full_complete(); @@ -1323,11 +1322,12 @@ static bool enum_new_device(hcd_event_t* event) _dev0.speed = hcd_port_speed_get(_dev0.rhport ); TU_LOG2("%s Speed\r\n", tu_str_speed[_dev0.speed]); - // start the enumeration process + // fake transfer to kick-off the enumeration process tuh_control_xfer_t xfer; + xfer.result = XFER_RESULT_SUCCESS; xfer.user_arg = ENUM_ADDR0_DEVICE_DESC; - process_enumeration(0, &xfer, XFER_RESULT_SUCCESS); + process_enumeration(0, &xfer); } #if CFG_TUH_HUB diff --git a/src/host/usbh.h b/src/host/usbh.h index 7dffcb453..a2372ad01 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -42,15 +42,19 @@ struct tuh_control_xfer_s; typedef struct tuh_control_xfer_s tuh_control_xfer_t; -typedef bool (*tuh_control_xfer_cb_t)(uint8_t daddr, tuh_control_xfer_t const * xfer, xfer_result_t result); +typedef bool (*tuh_control_xfer_cb_t)(uint8_t daddr, tuh_control_xfer_t const * xfer); struct tuh_control_xfer_s { uint8_t ep_addr; + xfer_result_t result; + tusb_control_request_t const* setup; uint32_t actual_len; uint8_t* buffer; + + tuh_control_xfer_cb_t complete_cb; uintptr_t user_arg; }; From deab8c276a41577eef3d4f4bd3663a5e1860a76a Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 17 Mar 2022 16:53:54 +0700 Subject: [PATCH 248/504] remove const in xfer callback --- src/class/hid/hid_host.c | 8 ++++---- src/class/msc/msc_host.c | 4 ++-- src/host/hub.c | 20 ++++++++++---------- src/host/usbh.c | 11 +++++++---- src/host/usbh.h | 4 ++-- 5 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 564b927e2..45090d193 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -103,7 +103,7 @@ uint8_t tuh_hid_get_protocol(uint8_t dev_addr, uint8_t instance) return hid_itf->protocol_mode; } -static bool set_protocol_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer) +static bool set_protocol_complete(uint8_t dev_addr, tuh_control_xfer_t* xfer) { uint8_t const itf_num = (uint8_t) xfer->setup->wIndex; uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); @@ -159,7 +159,7 @@ bool tuh_hid_set_protocol(uint8_t dev_addr, uint8_t instance, uint8_t protocol) return _hidh_set_protocol(dev_addr, hid_itf->itf_num, protocol, set_protocol_complete, 0); } -static bool set_report_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer) +static bool set_report_complete(uint8_t dev_addr, tuh_control_xfer_t* xfer) { TU_LOG2("HID Set Report complete\r\n"); @@ -390,7 +390,7 @@ enum { }; static void config_driver_mount_complete(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len); -static bool process_set_config(uint8_t dev_addr, tuh_control_xfer_t const * xfer); +static bool process_set_config(uint8_t dev_addr, tuh_control_xfer_t* xfer); bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num) { @@ -406,7 +406,7 @@ bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num) return process_set_config(dev_addr, &xfer); } -static bool process_set_config(uint8_t dev_addr, tuh_control_xfer_t const * xfer) +static bool process_set_config(uint8_t dev_addr, tuh_control_xfer_t* xfer) { // Stall is a valid response for SET_IDLE, therefore we could ignore its result if ( xfer->setup->bRequest != HID_REQ_CONTROL_SET_IDLE ) diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index ca1080eba..0a3deb2c9 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -358,7 +358,7 @@ bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32 // MSC Enumeration //--------------------------------------------------------------------+ -static bool config_get_maxlun_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer); +static bool config_get_maxlun_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer); static bool config_test_unit_ready_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); static bool config_request_sense_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); static bool config_read_capacity_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); @@ -432,7 +432,7 @@ bool msch_set_config(uint8_t dev_addr, uint8_t itf_num) return true; } -static bool config_get_maxlun_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer) +static bool config_get_maxlun_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer) { msch_interface_t* p_msc = get_itf(dev_addr); diff --git a/src/host/hub.c b/src/host/hub.c index 5255fdf7c..75596d748 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -225,8 +225,8 @@ bool hub_edpt_status_xfer(uint8_t dev_addr) // Set Configure //--------------------------------------------------------------------+ -static bool config_set_port_power (uint8_t dev_addr, tuh_control_xfer_t const * xfer); -static bool config_port_power_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer); +static bool config_set_port_power (uint8_t dev_addr, tuh_control_xfer_t* xfer); +static bool config_port_power_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer); bool hub_set_config(uint8_t dev_addr, uint8_t itf_num) { @@ -262,7 +262,7 @@ bool hub_set_config(uint8_t dev_addr, uint8_t itf_num) return true; } -static bool config_set_port_power (uint8_t dev_addr, tuh_control_xfer_t const * xfer) +static bool config_set_port_power (uint8_t dev_addr, tuh_control_xfer_t* xfer) { TU_ASSERT(XFER_RESULT_SUCCESS == xfer->result); @@ -279,7 +279,7 @@ static bool config_set_port_power (uint8_t dev_addr, tuh_control_xfer_t const * return hub_port_set_feature(dev_addr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete, 0); } -static bool config_port_power_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer) +static bool config_port_power_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer) { TU_ASSERT(XFER_RESULT_SUCCESS == xfer->result); hub_interface_t* p_hub = get_itf(dev_addr); @@ -305,9 +305,9 @@ static bool config_port_power_complete (uint8_t dev_addr, tuh_control_xfer_t con // Connection Changes //--------------------------------------------------------------------+ -static bool connection_get_status_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer); -static bool connection_clear_conn_change_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer); -static bool connection_port_reset_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer); +static bool connection_get_status_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer); +static bool connection_clear_conn_change_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer); +static bool connection_port_reset_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer); // callback as response of interrupt endpoint polling bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) @@ -335,7 +335,7 @@ bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32 return true; } -static bool connection_get_status_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer) +static bool connection_get_status_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer) { TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS); @@ -363,7 +363,7 @@ static bool connection_get_status_complete (uint8_t dev_addr, tuh_control_xfer_t return true; } -static bool connection_clear_conn_change_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer) +static bool connection_clear_conn_change_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer) { TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS); @@ -394,7 +394,7 @@ static bool connection_clear_conn_change_complete (uint8_t dev_addr, tuh_control return true; } -static bool connection_port_reset_complete (uint8_t dev_addr, tuh_control_xfer_t const * xfer) +static bool connection_port_reset_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer) { TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS); diff --git a/src/host/usbh.c b/src/host/usbh.c index 00afe609f..09b4c0487 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -882,7 +882,7 @@ bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) // Control transfer //--------------------------------------------------------------------+ -static bool _control_blocking_complete_cb(uint8_t daddr, tuh_control_xfer_t const * xfer) +static bool _control_blocking_complete_cb(uint8_t daddr, tuh_control_xfer_t* xfer) { (void) daddr; @@ -943,12 +943,15 @@ bool tuh_control_xfer (uint8_t daddr, tuh_control_xfer_t const* xfer) // TODO probably some timeout to prevent hanged } + + // update result + //xfer->result = result; } return true; } -uint8_t tuh_control_xfer_sync(uint8_t daddr, tuh_control_xfer_t const* xfer, uint32_t timeout_ms) +bool tuh_control_xfer_sync(uint8_t daddr, tuh_control_xfer_t* xfer, uint32_t timeout_ms) { (void) timeout_ms; @@ -977,7 +980,7 @@ static void _xfer_complete(uint8_t dev_addr, xfer_result_t result) // duplicate xfer since user can execute control transfer within callback tusb_control_request_t const request = _ctrl_xfer.request; - tuh_control_xfer_t const xfer_temp = + tuh_control_xfer_t xfer_temp = { .ep_addr = 0, .result = result, @@ -1119,7 +1122,7 @@ static bool parse_configuration_descriptor (uint8_t dev_addr, tusb_desc_configur static void enum_full_complete(void); // process device enumeration -static bool process_enumeration(uint8_t dev_addr, tuh_control_xfer_t const * xfer) +static bool process_enumeration(uint8_t dev_addr, tuh_control_xfer_t* xfer) { if (XFER_RESULT_SUCCESS != xfer->result) { diff --git a/src/host/usbh.h b/src/host/usbh.h index a2372ad01..e5f86d73d 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -42,7 +42,7 @@ struct tuh_control_xfer_s; typedef struct tuh_control_xfer_s tuh_control_xfer_t; -typedef bool (*tuh_control_xfer_cb_t)(uint8_t daddr, tuh_control_xfer_t const * xfer); +typedef bool (*tuh_control_xfer_cb_t)(uint8_t daddr, tuh_control_xfer_t* xfer); struct tuh_control_xfer_s { @@ -135,7 +135,7 @@ bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, // Sync (blocking) version of tuh_control_xfer() // return transfer result -uint8_t tuh_control_xfer_sync(uint8_t daddr, tuh_control_xfer_t const* xfer, uint32_t timeout_ms); +bool tuh_control_xfer_sync(uint8_t daddr, tuh_control_xfer_t * xfer, uint32_t timeout_ms); //--------------------------------------------------------------------+ // Descriptors Asynchronous (non-blocking) From 66942b814b6e24ecfe7db567b29f2e1d114071c1 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 17 Mar 2022 16:55:29 +0700 Subject: [PATCH 249/504] change return type of callback to void --- src/class/hid/hid_host.c | 35 ++++++++++++++-------------- src/class/msc/msc_host.c | 6 ++--- src/host/hub.c | 50 +++++++++++++++++----------------------- src/host/usbh.c | 43 +++++++++++++++------------------- src/host/usbh.h | 2 +- 5 files changed, 60 insertions(+), 76 deletions(-) diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 45090d193..7986ffc1a 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -103,20 +103,21 @@ uint8_t tuh_hid_get_protocol(uint8_t dev_addr, uint8_t instance) return hid_itf->protocol_mode; } -static bool set_protocol_complete(uint8_t dev_addr, tuh_control_xfer_t* xfer) +static void set_protocol_complete(uint8_t dev_addr, tuh_control_xfer_t* xfer) { - uint8_t const itf_num = (uint8_t) xfer->setup->wIndex; + uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); hidh_interface_t* hid_itf = get_instance(dev_addr, instance); - if (XFER_RESULT_SUCCESS == xfer->result) hid_itf->protocol_mode = (uint8_t) xfer->setup->wValue; + if (XFER_RESULT_SUCCESS == xfer->result) + { + hid_itf->protocol_mode = (uint8_t) tu_le16toh(xfer->setup->wValue); + } if (tuh_hid_set_protocol_complete_cb) { tuh_hid_set_protocol_complete_cb(dev_addr, instance, hid_itf->protocol_mode); } - - return true; } @@ -159,13 +160,13 @@ bool tuh_hid_set_protocol(uint8_t dev_addr, uint8_t instance, uint8_t protocol) return _hidh_set_protocol(dev_addr, hid_itf->itf_num, protocol, set_protocol_complete, 0); } -static bool set_report_complete(uint8_t dev_addr, tuh_control_xfer_t* xfer) +static void set_report_complete(uint8_t dev_addr, tuh_control_xfer_t* xfer) { TU_LOG2("HID Set Report complete\r\n"); if (tuh_hid_set_report_complete_cb) { - uint8_t const itf_num = (uint8_t) xfer->setup->wIndex; + uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); uint8_t const report_type = tu_u16_high(xfer->setup->wValue); @@ -174,8 +175,6 @@ static bool set_report_complete(uint8_t dev_addr, tuh_control_xfer_t* xfer) tuh_hid_set_report_complete_cb(dev_addr, instance, report_id, report_type, (xfer->result == XFER_RESULT_SUCCESS) ? xfer->setup->wLength : 0); } - - return true; } bool tuh_hid_set_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, uint8_t report_type, void* report, uint16_t len) @@ -390,7 +389,7 @@ enum { }; static void config_driver_mount_complete(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len); -static bool process_set_config(uint8_t dev_addr, tuh_control_xfer_t* xfer); +static void process_set_config(uint8_t dev_addr, tuh_control_xfer_t* xfer); bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num) { @@ -403,15 +402,17 @@ bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num) xfer.user_arg = CONFG_SET_IDLE; // fake request to kick-off the set config process - return process_set_config(dev_addr, &xfer); + process_set_config(dev_addr, &xfer); + + return true; } -static bool process_set_config(uint8_t dev_addr, tuh_control_xfer_t* xfer) +static void process_set_config(uint8_t dev_addr, tuh_control_xfer_t* xfer) { // Stall is a valid response for SET_IDLE, therefore we could ignore its result if ( xfer->setup->bRequest != HID_REQ_CONTROL_SET_IDLE ) { - TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS); + TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, ); } uintptr_t const state = xfer->user_arg; @@ -426,12 +427,12 @@ static bool process_set_config(uint8_t dev_addr, tuh_control_xfer_t* xfer) // Idle rate = 0 mean only report when there is changes const uint16_t idle_rate = 0; const uintptr_t next_state = (hid_itf->itf_protocol != HID_ITF_PROTOCOL_NONE) ? CONFIG_SET_PROTOCOL : CONFIG_GET_REPORT_DESC; - TU_VERIFY( _hidh_set_idle(dev_addr, itf_num, idle_rate, process_set_config, next_state) ); + _hidh_set_idle(dev_addr, itf_num, idle_rate, process_set_config, next_state); } break; case CONFIG_SET_PROTOCOL: - TU_VERIFY(_hidh_set_protocol(dev_addr, hid_itf->itf_num, HID_PROTOCOL_BOOT, process_set_config, CONFIG_GET_REPORT_DESC)); + _hidh_set_protocol(dev_addr, hid_itf->itf_num, HID_PROTOCOL_BOOT, process_set_config, CONFIG_GET_REPORT_DESC); break; case CONFIG_GET_REPORT_DESC: @@ -445,7 +446,7 @@ static bool process_set_config(uint8_t dev_addr, tuh_control_xfer_t* xfer) config_driver_mount_complete(dev_addr, instance, NULL, 0); }else { - TU_ASSERT(tuh_descriptor_get_hid_report(dev_addr, itf_num, hid_itf->report_desc_type, 0, usbh_get_enum_buf(), hid_itf->report_desc_len, process_set_config, CONFIG_COMPLETE)); + tuh_descriptor_get_hid_report(dev_addr, itf_num, hid_itf->report_desc_type, 0, usbh_get_enum_buf(), hid_itf->report_desc_len, process_set_config, CONFIG_COMPLETE); } break; @@ -460,8 +461,6 @@ static bool process_set_config(uint8_t dev_addr, tuh_control_xfer_t* xfer) default: break; } - - return true; } static void config_driver_mount_complete(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len) diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index 0a3deb2c9..ca51d63fa 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -358,7 +358,7 @@ bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32 // MSC Enumeration //--------------------------------------------------------------------+ -static bool config_get_maxlun_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer); +static void config_get_maxlun_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer); static bool config_test_unit_ready_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); static bool config_request_sense_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); static bool config_read_capacity_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); @@ -432,7 +432,7 @@ bool msch_set_config(uint8_t dev_addr, uint8_t itf_num) return true; } -static bool config_get_maxlun_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer) +static void config_get_maxlun_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer) { msch_interface_t* p_msc = get_itf(dev_addr); @@ -444,8 +444,6 @@ static bool config_get_maxlun_complete (uint8_t dev_addr, tuh_control_xfer_t* xf TU_LOG2("SCSI Test Unit Ready\r\n"); uint8_t const lun = 0; tuh_msc_test_unit_ready(dev_addr, lun, config_test_unit_ready_complete); - - return true; } static bool config_test_unit_ready_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw) diff --git a/src/host/hub.c b/src/host/hub.c index 75596d748..9f17b7eda 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -225,8 +225,8 @@ bool hub_edpt_status_xfer(uint8_t dev_addr) // Set Configure //--------------------------------------------------------------------+ -static bool config_set_port_power (uint8_t dev_addr, tuh_control_xfer_t* xfer); -static bool config_port_power_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer); +static void config_set_port_power (uint8_t dev_addr, tuh_control_xfer_t* xfer); +static void config_port_power_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer); bool hub_set_config(uint8_t dev_addr, uint8_t itf_num) { @@ -262,9 +262,9 @@ bool hub_set_config(uint8_t dev_addr, uint8_t itf_num) return true; } -static bool config_set_port_power (uint8_t dev_addr, tuh_control_xfer_t* xfer) +static void config_set_port_power (uint8_t dev_addr, tuh_control_xfer_t* xfer) { - TU_ASSERT(XFER_RESULT_SUCCESS == xfer->result); + TU_ASSERT(XFER_RESULT_SUCCESS == xfer->result, ); hub_interface_t* p_hub = get_itf(dev_addr); @@ -276,38 +276,36 @@ static bool config_set_port_power (uint8_t dev_addr, tuh_control_xfer_t* xfer) // Set Port Power to be able to detect connection, starting with port 1 uint8_t const hub_port = 1; - return hub_port_set_feature(dev_addr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete, 0); + hub_port_set_feature(dev_addr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete, 0); } -static bool config_port_power_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer) +static void config_port_power_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer) { - TU_ASSERT(XFER_RESULT_SUCCESS == xfer->result); + TU_ASSERT(XFER_RESULT_SUCCESS == xfer->result, ); hub_interface_t* p_hub = get_itf(dev_addr); if (xfer->setup->wIndex == p_hub->port_count) { // All ports are power -> queue notification status endpoint and // complete the SET CONFIGURATION - TU_ASSERT( usbh_edpt_xfer(dev_addr, p_hub->ep_in, &p_hub->status_change, 1) ); + TU_ASSERT( usbh_edpt_xfer(dev_addr, p_hub->ep_in, &p_hub->status_change, 1), ); usbh_driver_set_config_complete(dev_addr, p_hub->itf_num); }else { // power next port uint8_t const hub_port = (uint8_t) (xfer->setup->wIndex + 1); - return hub_port_set_feature(dev_addr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete, 0); + hub_port_set_feature(dev_addr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete, 0); } - - return true; } //--------------------------------------------------------------------+ // Connection Changes //--------------------------------------------------------------------+ -static bool connection_get_status_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer); -static bool connection_clear_conn_change_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer); -static bool connection_port_reset_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer); +static void connection_get_status_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer); +static void connection_clear_conn_change_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer); +static void connection_port_reset_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer); // callback as response of interrupt endpoint polling bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) @@ -335,12 +333,12 @@ bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32 return true; } -static bool connection_get_status_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer) +static void connection_get_status_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer) { - TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS); + TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, ); hub_interface_t* p_hub = get_itf(dev_addr); - uint8_t const port_num = (uint8_t) xfer->setup->wIndex; + uint8_t const port_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); // Connection change if (p_hub->port_status.change.connection) @@ -359,16 +357,14 @@ static bool connection_get_status_complete (uint8_t dev_addr, tuh_control_xfer_t // TODO continue with status_change, or maybe we can do it again with status hub_edpt_status_xfer(dev_addr); } - - return true; } -static bool connection_clear_conn_change_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer) +static void connection_clear_conn_change_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer) { - TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS); + TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, ); hub_interface_t* p_hub = get_itf(dev_addr); - uint8_t const port_num = (uint8_t) xfer->setup->wIndex; + uint8_t const port_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); if ( p_hub->port_status.status.connection ) { @@ -390,16 +386,14 @@ static bool connection_clear_conn_change_complete (uint8_t dev_addr, tuh_control hcd_event_handler(&event, false); } - - return true; } -static bool connection_port_reset_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer) +static void connection_port_reset_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer) { - TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS); + TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, ); // hub_interface_t* p_hub = get_itf(dev_addr); - uint8_t const port_num = (uint8_t) xfer->setup->wIndex; + uint8_t const port_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); // submit attach event hcd_event_t event = @@ -414,8 +408,6 @@ static bool connection_port_reset_complete (uint8_t dev_addr, tuh_control_xfer_t }; hcd_event_handler(&event, false); - - return true; } #endif diff --git a/src/host/usbh.c b/src/host/usbh.c index 09b4c0487..3ab72ac0e 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -882,14 +882,11 @@ bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) // Control transfer //--------------------------------------------------------------------+ -static bool _control_blocking_complete_cb(uint8_t daddr, tuh_control_xfer_t* xfer) +static void _control_blocking_complete_cb(uint8_t daddr, tuh_control_xfer_t* xfer) { (void) daddr; - // update result *((xfer_result_t*) xfer->user_arg) = xfer->result; - - return true; } bool tuh_control_xfer (uint8_t daddr, tuh_control_xfer_t const* xfer) @@ -1122,13 +1119,13 @@ static bool parse_configuration_descriptor (uint8_t dev_addr, tusb_desc_configur static void enum_full_complete(void); // process device enumeration -static bool process_enumeration(uint8_t dev_addr, tuh_control_xfer_t* xfer) +static void process_enumeration(uint8_t dev_addr, tuh_control_xfer_t* xfer) { if (XFER_RESULT_SUCCESS != xfer->result) { // stop enumeration, maybe we could retry this enum_full_complete(); - return false; + return; } uintptr_t const state = xfer->user_arg; @@ -1146,7 +1143,7 @@ static bool process_enumeration(uint8_t dev_addr, tuh_control_xfer_t* xfer) { // device unplugged while delaying, nothing else to do enum_full_complete(); - return false; + return; } _dev0.speed = (port_status.status.high_speed) ? TUSB_SPEED_HIGH : @@ -1162,7 +1159,7 @@ static bool process_enumeration(uint8_t dev_addr, tuh_control_xfer_t* xfer) case ENUM_HUB_GET_STATUS_2: osal_task_delay(RESET_DELAY); - TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, process_enumeration, ENUM_HUB_CLEAR_RESET_2) ); + TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, process_enumeration, ENUM_HUB_CLEAR_RESET_2), ); break; case ENUM_HUB_CLEAR_RESET_2: @@ -1173,7 +1170,7 @@ static bool process_enumeration(uint8_t dev_addr, tuh_control_xfer_t* xfer) // Acknowledge Port Reset Change if Reset Successful if (port_status.change.reset) { - TU_ASSERT( hub_port_clear_reset_change(_dev0.hub_addr, _dev0.hub_port, process_enumeration, ENUM_SET_ADDR) ); + TU_ASSERT( hub_port_clear_reset_change(_dev0.hub_addr, _dev0.hub_port, process_enumeration, ENUM_SET_ADDR), ); } } break; @@ -1183,11 +1180,11 @@ static bool process_enumeration(uint8_t dev_addr, tuh_control_xfer_t* xfer) { // TODO probably doesn't need to open/close each enumeration uint8_t const addr0 = 0; - TU_ASSERT( usbh_edpt_control_open(addr0, 8) ); + TU_ASSERT( usbh_edpt_control_open(addr0, 8), ); // Get first 8 bytes of device descriptor for Control Endpoint size TU_LOG2("Get 8 byte of Device Descriptor\r\n"); - TU_ASSERT(tuh_descriptor_get_device(addr0, _usbh_ctrl_buf, 8, process_enumeration, ENUM_SET_ADDR)); + TU_ASSERT(tuh_descriptor_get_device(addr0, _usbh_ctrl_buf, 8, process_enumeration, ENUM_SET_ADDR), ); } break; @@ -1206,7 +1203,7 @@ static bool process_enumeration(uint8_t dev_addr, tuh_control_xfer_t* xfer) else { // after RESET_DELAY the hub_port_reset() already complete - TU_ASSERT( hub_port_reset(_dev0.hub_addr, _dev0.hub_port, process_enumeration, ENUM_HUB_GET_STATUS_2) ); + TU_ASSERT( hub_port_reset(_dev0.hub_addr, _dev0.hub_port, process_enumeration, ENUM_HUB_GET_STATUS_2), ); break; } #endif @@ -1221,18 +1218,18 @@ static bool process_enumeration(uint8_t dev_addr, tuh_control_xfer_t* xfer) uint8_t const new_addr = (uint8_t) tu_le16toh(xfer->setup->wValue); usbh_device_t* new_dev = get_device(new_addr); - TU_ASSERT(new_dev); + TU_ASSERT(new_dev, ); new_dev->addressed = 1; // TODO close device 0, may not be needed hcd_device_close(_dev0.rhport, 0); // open control pipe for new address - TU_ASSERT( usbh_edpt_control_open(new_addr, new_dev->ep0_size) ); + TU_ASSERT( usbh_edpt_control_open(new_addr, new_dev->ep0_size), ); // Get full device descriptor TU_LOG2("Get Device Descriptor\r\n"); - TU_ASSERT(tuh_descriptor_get_device(new_addr, _usbh_ctrl_buf, sizeof(tusb_desc_device_t), process_enumeration, ENUM_GET_9BYTE_CONFIG_DESC)); + TU_ASSERT(tuh_descriptor_get_device(new_addr, _usbh_ctrl_buf, sizeof(tusb_desc_device_t), process_enumeration, ENUM_GET_9BYTE_CONFIG_DESC), ); } break; @@ -1240,7 +1237,7 @@ static bool process_enumeration(uint8_t dev_addr, tuh_control_xfer_t* xfer) { tusb_desc_device_t const * desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; usbh_device_t* dev = get_device(dev_addr); - TU_ASSERT(dev); + TU_ASSERT(dev, ); dev->vid = desc_device->idVendor; dev->pid = desc_device->idProduct; @@ -1253,7 +1250,7 @@ static bool process_enumeration(uint8_t dev_addr, tuh_control_xfer_t* xfer) // Get 9-byte for total length uint8_t const config_idx = CONFIG_NUM - 1; TU_LOG2("Get Configuration[0] Descriptor (9 bytes)\r\n"); - TU_ASSERT( tuh_descriptor_get_configuration(dev_addr, config_idx, _usbh_ctrl_buf, 9, process_enumeration, ENUM_GET_FULL_CONFIG_DESC) ); + TU_ASSERT( tuh_descriptor_get_configuration(dev_addr, config_idx, _usbh_ctrl_buf, 9, process_enumeration, ENUM_GET_FULL_CONFIG_DESC), ); } break; @@ -1265,28 +1262,28 @@ static bool process_enumeration(uint8_t dev_addr, tuh_control_xfer_t* xfer) uint16_t const total_len = tu_le16toh( tu_unaligned_read16(desc_config + offsetof(tusb_desc_configuration_t, wTotalLength)) ); // TODO not enough buffer to hold configuration descriptor - TU_ASSERT(total_len <= CFG_TUH_ENUMERATION_BUFSIZE); + TU_ASSERT(total_len <= CFG_TUH_ENUMERATION_BUFSIZE, ); // Get full configuration descriptor uint8_t const config_idx = CONFIG_NUM - 1; TU_LOG2("Get Configuration[0] Descriptor\r\n"); - TU_ASSERT( tuh_descriptor_get_configuration(dev_addr, config_idx, _usbh_ctrl_buf, total_len, process_enumeration, ENUM_SET_CONFIG) ); + TU_ASSERT( tuh_descriptor_get_configuration(dev_addr, config_idx, _usbh_ctrl_buf, total_len, process_enumeration, ENUM_SET_CONFIG), ); } break; case ENUM_SET_CONFIG: // Parse configuration & set up drivers // Driver open aren't allowed to make any usb transfer yet - TU_ASSERT( parse_configuration_descriptor(dev_addr, (tusb_desc_configuration_t*) _usbh_ctrl_buf) ); + TU_ASSERT( parse_configuration_descriptor(dev_addr, (tusb_desc_configuration_t*) _usbh_ctrl_buf), ); - TU_ASSERT( tuh_configuration_set(dev_addr, CONFIG_NUM, process_enumeration, ENUM_CONFIG_DRIVER) ); + TU_ASSERT( tuh_configuration_set(dev_addr, CONFIG_NUM, process_enumeration, ENUM_CONFIG_DRIVER), ); break; case ENUM_CONFIG_DRIVER: { TU_LOG2("Device configured\r\n"); usbh_device_t* dev = get_device(dev_addr); - TU_ASSERT(dev); + TU_ASSERT(dev, ); dev->configured = 1; @@ -1303,8 +1300,6 @@ static bool process_enumeration(uint8_t dev_addr, tuh_control_xfer_t* xfer) enum_full_complete(); break; } - - return true; } static bool enum_new_device(hcd_event_t* event) diff --git a/src/host/usbh.h b/src/host/usbh.h index e5f86d73d..ec6be67dc 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -42,7 +42,7 @@ struct tuh_control_xfer_s; typedef struct tuh_control_xfer_s tuh_control_xfer_t; -typedef bool (*tuh_control_xfer_cb_t)(uint8_t daddr, tuh_control_xfer_t* xfer); +typedef void (*tuh_control_xfer_cb_t)(uint8_t daddr, tuh_control_xfer_t* xfer); struct tuh_control_xfer_s { From 1ee699d49d6da7ce8b92cde1636e34ed90ff6396 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 17 Mar 2022 16:56:56 +0700 Subject: [PATCH 250/504] update example --- examples/host/bare_api/src/main.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index 8da7f6a0c..3f0b9ef22 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -115,12 +115,12 @@ static void utf16_to_utf8(uint16_t *temp_buf, size_t buf_len) { ((uint8_t*) temp_buf)[utf8_len] = '\0'; } -bool print_device_descriptor(uint8_t daddr, tuh_control_xfer_t const * xfer) +void print_device_descriptor(uint8_t daddr, tuh_control_xfer_t* xfer) { if ( XFER_RESULT_SUCCESS != xfer->result ) { printf("Failed to get device descriptor\r\n"); - return false; + return; } printf("Device %u: ID %04x:%04x\r\n", daddr, desc_device.idVendor, desc_device.idProduct); @@ -164,8 +164,6 @@ bool print_device_descriptor(uint8_t daddr, tuh_control_xfer_t const * xfer) printf("\r\n"); printf(" bNumConfigurations %u\r\n" , desc_device.bNumConfigurations); - - return true; } // Invoked when device is mounted (configured) From 8aedb2ff37901d2d08c28308e2527d73ab179f5c Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 17 Mar 2022 17:25:53 +0700 Subject: [PATCH 251/504] slightly change the signature of tuh_control_xfer --- src/class/cdc/cdc_host.c | 2 +- src/class/hid/hid_host.c | 6 +++--- src/class/msc/msc_host.c | 2 +- src/host/hub.c | 8 ++++---- src/host/usbh.c | 10 +++++----- src/host/usbh.h | 4 +--- 6 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 9838df818..7ae8af77a 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -138,7 +138,7 @@ bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_co .wLength = 0 }; - tuh_control_xfer_t const xfer = + tuh_control_xfer_t xfer = { .ep_addr = 0, .setup = &request, diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 7986ffc1a..65fccd32a 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -139,7 +139,7 @@ static bool _hidh_set_protocol(uint8_t dev_addr, uint8_t itf_num, uint8_t protoc .wLength = 0 }; - tuh_control_xfer_t const xfer = + tuh_control_xfer_t xfer = { .ep_addr = 0, .setup = &request, @@ -196,7 +196,7 @@ bool tuh_hid_set_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, u .wLength = len }; - tuh_control_xfer_t const xfer = + tuh_control_xfer_t xfer = { .ep_addr = 0, .setup = &request, @@ -227,7 +227,7 @@ static bool _hidh_set_idle(uint8_t dev_addr, uint8_t itf_num, uint16_t idle_rate .wLength = 0 }; - tuh_control_xfer_t const xfer = + tuh_control_xfer_t xfer = { .ep_addr = 0, .setup = &request, diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index ca51d63fa..fea587386 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -419,7 +419,7 @@ bool msch_set_config(uint8_t dev_addr, uint8_t itf_num) .wLength = 1 }; - tuh_control_xfer_t const xfer = + tuh_control_xfer_t xfer = { .ep_addr = 0, .setup = &request, diff --git a/src/host/hub.c b/src/host/hub.c index 9f17b7eda..36f27398f 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -94,7 +94,7 @@ bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, .wLength = 0 }; - tuh_control_xfer_t const xfer = + tuh_control_xfer_t xfer = { .ep_addr = 0, .setup = &request, @@ -125,7 +125,7 @@ bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, .wLength = 0 }; - tuh_control_xfer_t const xfer = + tuh_control_xfer_t xfer = { .ep_addr = 0, .setup = &request, @@ -156,7 +156,7 @@ bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, .wLength = 4 }; - tuh_control_xfer_t const xfer = + tuh_control_xfer_t xfer = { .ep_addr = 0, .setup = &request, @@ -248,7 +248,7 @@ bool hub_set_config(uint8_t dev_addr, uint8_t itf_num) .wLength = sizeof(descriptor_hub_desc_t) }; - tuh_control_xfer_t const xfer = + tuh_control_xfer_t xfer = { .ep_addr = 0, .setup = &request, diff --git a/src/host/usbh.c b/src/host/usbh.c index 3ab72ac0e..2d01c9144 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -326,7 +326,7 @@ static bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t .wLength = tu_htole16(len) }; - tuh_control_xfer_t const xfer = + tuh_control_xfer_t xfer = { .ep_addr = 0, .setup = &request, @@ -411,7 +411,7 @@ bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_ .wLength = len }; - tuh_control_xfer_t const xfer = + tuh_control_xfer_t xfer = { .ep_addr = 0, .setup = &request, @@ -442,7 +442,7 @@ bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, .wLength = 0 }; - tuh_control_xfer_t const xfer = + tuh_control_xfer_t xfer = { .ep_addr = 0, .setup = &request, @@ -889,7 +889,7 @@ static void _control_blocking_complete_cb(uint8_t daddr, tuh_control_xfer_t* xfe *((xfer_result_t*) xfer->user_arg) = xfer->result; } -bool tuh_control_xfer (uint8_t daddr, tuh_control_xfer_t const* xfer) +bool tuh_control_xfer (uint8_t daddr, tuh_control_xfer_t* xfer) { // pre-check to help reducing mutex lock TU_VERIFY(_ctrl_xfer.stage == CONTROL_STAGE_IDLE); @@ -1404,7 +1404,7 @@ static bool enum_request_set_addr(void) .wLength = 0 }; - tuh_control_xfer_t const xfer = + tuh_control_xfer_t xfer = { .ep_addr = 0, .setup = &request, diff --git a/src/host/usbh.h b/src/host/usbh.h index ec6be67dc..801938a39 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -53,8 +53,6 @@ struct tuh_control_xfer_s uint32_t actual_len; uint8_t* buffer; - - tuh_control_xfer_cb_t complete_cb; uintptr_t user_arg; }; @@ -118,7 +116,7 @@ static inline bool tuh_ready(uint8_t daddr) // Carry out a control transfer // true on success, false if there is on-going control transfer or incorrect parameters // Blocking if complete callback is NULL, in this case 'user_arg' must contain xfer_result_t variable -bool tuh_control_xfer(uint8_t daddr, tuh_control_xfer_t const* xfer); +bool tuh_control_xfer(uint8_t daddr, tuh_control_xfer_t* xfer); //bool tuh_edpt_xfer(uint8_t daddr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes); From 102b99a0e8b30a03bae917028fd064ff1480275b Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 17 Mar 2022 20:48:32 +0700 Subject: [PATCH 252/504] add actual_len supported --- src/host/usbh.c | 46 ++++++++++++++++++++++++++-------------------- src/host/usbh.h | 8 ++++---- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index 2d01c9144..96dd390b0 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -250,6 +250,7 @@ struct tuh_control_xfer_cb_t complete_cb; uintptr_t user_arg; + volatile uint16_t actual_len; uint8_t daddr; // device address that is transferring volatile uint8_t stage; }_ctrl_xfer; @@ -306,7 +307,7 @@ void osal_task_delay(uint32_t msec) #endif //--------------------------------------------------------------------+ -// Descriptors +// Descriptors Async //--------------------------------------------------------------------+ static bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t language_id, void* buffer, uint16_t len, @@ -455,7 +456,7 @@ bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, } //--------------------------------------------------------------------+ -// Asynchronous +// Descriptor Sync //--------------------------------------------------------------------+ #define _CONTROL_SYNC_API(_async_func, _timeout, ...) \ @@ -903,13 +904,13 @@ bool tuh_control_xfer (uint8_t daddr, tuh_control_xfer_t* xfer) usbh_unlock(); TU_VERIFY(is_idle); - const uint8_t rhport = usbh_get_rhport(daddr); TU_LOG2("[%u:%u] %s: ", rhport, daddr, xfer->setup->bRequest <= TUSB_REQ_SYNCH_FRAME ? tu_str_std_request[xfer->setup->bRequest] : "Unknown Request"); TU_LOG2_VAR(&xfer->setup); TU_LOG2("\r\n"); + _ctrl_xfer.actual_len = 0; _ctrl_xfer.daddr = daddr; _ctrl_xfer.request = (*xfer->setup); _ctrl_xfer.buffer = xfer->buffer; @@ -941,8 +942,15 @@ bool tuh_control_xfer (uint8_t daddr, tuh_control_xfer_t* xfer) // TODO probably some timeout to prevent hanged } - // update result - //xfer->result = result; + // update xfer result + xfer->result = result; + if ( xfer->user_arg ) + { + // if user_arg is not NULL, it is also updated + *((xfer_result_t*) xfer->user_arg) = result; + } + + xfer->actual_len = _ctrl_xfer.actual_len; } return true; @@ -952,19 +960,16 @@ bool tuh_control_xfer_sync(uint8_t daddr, tuh_control_xfer_t* xfer, uint32_t tim { (void) timeout_ms; - xfer_result_t result = XFER_RESULT_INVALID; - tuh_control_xfer_t xfer_sync = (*xfer); - - xfer_sync.complete_cb = NULL; - xfer_sync.user_arg = (uintptr_t) &result; + // clear callback for sync + xfer->complete_cb = NULL; // TODO use timeout to wait - TU_VERIFY(tuh_control_xfer(daddr, &xfer_sync), XFER_RESULT_TIMEOUT); + TU_VERIFY(tuh_control_xfer(daddr, xfer)); - return result; + return true; } -TU_ATTR_ALWAYS_INLINE static inline void set_control_xfer_stage(uint8_t stage) +TU_ATTR_ALWAYS_INLINE static inline void _set_control_xfer_stage(uint8_t stage) { usbh_lock(); _ctrl_xfer.stage = stage; @@ -982,7 +987,7 @@ static void _xfer_complete(uint8_t dev_addr, xfer_result_t result) .ep_addr = 0, .result = result, .setup = &request, - .actual_len = 0, + .actual_len = (uint32_t) _ctrl_xfer.actual_len, .buffer = _ctrl_xfer.buffer, .complete_cb = _ctrl_xfer.complete_cb, .user_arg = _ctrl_xfer.user_arg @@ -1001,7 +1006,6 @@ static void _xfer_complete(uint8_t dev_addr, xfer_result_t result) static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) ep_addr; - (void) xferred_bytes; const uint8_t rhport = usbh_get_rhport(dev_addr); tusb_control_request_t const * request = &_ctrl_xfer.request; @@ -1020,20 +1024,22 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result if (request->wLength) { // DATA stage: initial data toggle is always 1 - set_control_xfer_stage(CONTROL_STAGE_DATA); + _set_control_xfer_stage(CONTROL_STAGE_DATA); return hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.buffer, request->wLength); } __attribute__((fallthrough)); case CONTROL_STAGE_DATA: - if (request->wLength) + if (xferred_bytes) { TU_LOG2("[%u:%u] Control data:\r\n", rhport, dev_addr); - TU_LOG2_MEM(_ctrl_xfer.buffer, request->wLength, 2); + TU_LOG2_MEM(_ctrl_xfer.buffer, xferred_bytes, 2); } + _ctrl_xfer.actual_len = xferred_bytes; + // ACK stage: toggle is always 1 - set_control_xfer_stage(CONTROL_STAGE_ACK); + _set_control_xfer_stage(CONTROL_STAGE_ACK); hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, 1-request->bmRequestType_bit.direction), NULL, 0); break; @@ -1083,7 +1089,7 @@ static void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t h hcd_device_close(rhport, dev_addr); clear_device(dev); // abort on-going control xfer if any - if (_ctrl_xfer.daddr == dev_addr) set_control_xfer_stage(CONTROL_STAGE_IDLE); + if (_ctrl_xfer.daddr == dev_addr) _set_control_xfer_stage(CONTROL_STAGE_IDLE); } } } diff --git a/src/host/usbh.h b/src/host/usbh.h index 801938a39..e6897d8d8 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -50,7 +50,7 @@ struct tuh_control_xfer_s xfer_result_t result; tusb_control_request_t const* setup; - uint32_t actual_len; + uint32_t actual_len; // excluding setup packet uint8_t* buffer; tuh_control_xfer_cb_t complete_cb; @@ -115,7 +115,8 @@ static inline bool tuh_ready(uint8_t daddr) // Carry out a control transfer // true on success, false if there is on-going control transfer or incorrect parameters -// Blocking if complete callback is NULL, in this case 'user_arg' must contain xfer_result_t variable +// Note: blocking if complete callback is NULL. In this case 'xfer->result' will be updated +// and if 'user_arg' point to a xfer_result_t variable, it will be updated as well. bool tuh_control_xfer(uint8_t daddr, tuh_control_xfer_t* xfer); //bool tuh_edpt_xfer(uint8_t daddr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes); @@ -123,7 +124,6 @@ bool tuh_control_xfer(uint8_t daddr, tuh_control_xfer_t* xfer); // Set Configuration (control transfer) // config_num = 0 will un-configure device. Note: config_num = config_descriptor_index + 1 // true on success, false if there is on-going control transfer or incorrect parameters -// Blocking if complete callback is NULL, in this case 'user_arg' must contain xfer_result_t variable bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); @@ -132,7 +132,7 @@ bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, //--------------------------------------------------------------------+ // Sync (blocking) version of tuh_control_xfer() -// return transfer result +// xfer contents will be updated to reflect the transfer bool tuh_control_xfer_sync(uint8_t daddr, tuh_control_xfer_t * xfer, uint32_t timeout_ms); //--------------------------------------------------------------------+ From 55428d7dd215eb2e69a1f654ccc4730525b509d6 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 17 Mar 2022 20:52:16 +0700 Subject: [PATCH 253/504] rename tuh_control_xfer_t to tuh_xfer_t --- examples/host/bare_api/src/main.c | 2 +- src/class/cdc/cdc_host.c | 4 +-- src/class/cdc/cdc_host.h | 6 ++--- src/class/hid/hid_host.c | 20 +++++++------- src/class/msc/msc_host.c | 6 ++--- src/host/hub.c | 34 ++++++++++++------------ src/host/hub.h | 10 +++---- src/host/usbh.c | 44 +++++++++++++++---------------- src/host/usbh.h | 32 +++++++++++----------- 9 files changed, 79 insertions(+), 79 deletions(-) diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index 3f0b9ef22..feb94a6fe 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -115,7 +115,7 @@ static void utf16_to_utf8(uint16_t *temp_buf, size_t buf_len) { ((uint8_t*) temp_buf)[utf8_len] = '\0'; } -void print_device_descriptor(uint8_t daddr, tuh_control_xfer_t* xfer) +void print_device_descriptor(uint8_t daddr, tuh_xfer_t* xfer) { if ( XFER_RESULT_SUCCESS != xfer->result ) { diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 7ae8af77a..a811eb667 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -120,7 +120,7 @@ bool tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is return usbh_edpt_xfer(dev_addr, ep_in, p_buffer, length); } -bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_control_xfer_cb_t complete_cb) +bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_xfer_cb_t complete_cb) { cdch_data_t const * p_cdc = get_itf(dev_addr); @@ -138,7 +138,7 @@ bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_co .wLength = 0 }; - tuh_control_xfer_t xfer = + tuh_xfer_t xfer = { .ep_addr = 0, .setup = &request, diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index 67162a0ca..33dbd2efb 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -42,14 +42,14 @@ * \defgroup CDC_Serial_Host Host * @{ */ -bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_control_xfer_cb_t complete_cb); +bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_xfer_cb_t complete_cb); -static inline bool tuh_cdc_connect(uint8_t dev_addr, tuh_control_xfer_cb_t complete_cb) +static inline bool tuh_cdc_connect(uint8_t dev_addr, tuh_xfer_cb_t complete_cb) { return tuh_cdc_set_control_line_state(dev_addr, true, true, complete_cb); } -static inline bool tuh_cdc_disconnect(uint8_t dev_addr, tuh_control_xfer_cb_t complete_cb) +static inline bool tuh_cdc_disconnect(uint8_t dev_addr, tuh_xfer_cb_t complete_cb) { return tuh_cdc_set_control_line_state(dev_addr, false, false, complete_cb); } diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 65fccd32a..705b73c67 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -103,7 +103,7 @@ uint8_t tuh_hid_get_protocol(uint8_t dev_addr, uint8_t instance) return hid_itf->protocol_mode; } -static void set_protocol_complete(uint8_t dev_addr, tuh_control_xfer_t* xfer) +static void set_protocol_complete(uint8_t dev_addr, tuh_xfer_t* xfer) { uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); @@ -121,7 +121,7 @@ static void set_protocol_complete(uint8_t dev_addr, tuh_control_xfer_t* xfer) } -static bool _hidh_set_protocol(uint8_t dev_addr, uint8_t itf_num, uint8_t protocol, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) +static bool _hidh_set_protocol(uint8_t dev_addr, uint8_t itf_num, uint8_t protocol, tuh_xfer_cb_t complete_cb, uintptr_t user_arg) { TU_LOG2("HID Set Protocol = %d\r\n", protocol); @@ -139,7 +139,7 @@ static bool _hidh_set_protocol(uint8_t dev_addr, uint8_t itf_num, uint8_t protoc .wLength = 0 }; - tuh_control_xfer_t xfer = + tuh_xfer_t xfer = { .ep_addr = 0, .setup = &request, @@ -160,7 +160,7 @@ bool tuh_hid_set_protocol(uint8_t dev_addr, uint8_t instance, uint8_t protocol) return _hidh_set_protocol(dev_addr, hid_itf->itf_num, protocol, set_protocol_complete, 0); } -static void set_report_complete(uint8_t dev_addr, tuh_control_xfer_t* xfer) +static void set_report_complete(uint8_t dev_addr, tuh_xfer_t* xfer) { TU_LOG2("HID Set Report complete\r\n"); @@ -196,7 +196,7 @@ bool tuh_hid_set_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, u .wLength = len }; - tuh_control_xfer_t xfer = + tuh_xfer_t xfer = { .ep_addr = 0, .setup = &request, @@ -209,7 +209,7 @@ bool tuh_hid_set_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, u return true; } -static bool _hidh_set_idle(uint8_t dev_addr, uint8_t itf_num, uint16_t idle_rate, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) +static bool _hidh_set_idle(uint8_t dev_addr, uint8_t itf_num, uint16_t idle_rate, tuh_xfer_cb_t complete_cb, uintptr_t user_arg) { // SET IDLE request, device can stall if not support this request TU_LOG2("HID Set Idle \r\n"); @@ -227,7 +227,7 @@ static bool _hidh_set_idle(uint8_t dev_addr, uint8_t itf_num, uint16_t idle_rate .wLength = 0 }; - tuh_control_xfer_t xfer = + tuh_xfer_t xfer = { .ep_addr = 0, .setup = &request, @@ -389,14 +389,14 @@ enum { }; static void config_driver_mount_complete(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len); -static void process_set_config(uint8_t dev_addr, tuh_control_xfer_t* xfer); +static void process_set_config(uint8_t dev_addr, tuh_xfer_t* xfer); bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num) { tusb_control_request_t request; request.wIndex = tu_htole16((uint16_t) itf_num); - tuh_control_xfer_t xfer; + tuh_xfer_t xfer; xfer.result = XFER_RESULT_SUCCESS; xfer.setup = &request; xfer.user_arg = CONFG_SET_IDLE; @@ -407,7 +407,7 @@ bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num) return true; } -static void process_set_config(uint8_t dev_addr, tuh_control_xfer_t* xfer) +static void process_set_config(uint8_t dev_addr, tuh_xfer_t* xfer) { // Stall is a valid response for SET_IDLE, therefore we could ignore its result if ( xfer->setup->bRequest != HID_REQ_CONTROL_SET_IDLE ) diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index fea587386..789ae9c1a 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -358,7 +358,7 @@ bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32 // MSC Enumeration //--------------------------------------------------------------------+ -static void config_get_maxlun_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer); +static void config_get_maxlun_complete (uint8_t dev_addr, tuh_xfer_t* xfer); static bool config_test_unit_ready_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); static bool config_request_sense_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); static bool config_read_capacity_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); @@ -419,7 +419,7 @@ bool msch_set_config(uint8_t dev_addr, uint8_t itf_num) .wLength = 1 }; - tuh_control_xfer_t xfer = + tuh_xfer_t xfer = { .ep_addr = 0, .setup = &request, @@ -432,7 +432,7 @@ bool msch_set_config(uint8_t dev_addr, uint8_t itf_num) return true; } -static void config_get_maxlun_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer) +static void config_get_maxlun_complete (uint8_t dev_addr, tuh_xfer_t* xfer) { msch_interface_t* p_msc = get_itf(dev_addr); diff --git a/src/host/hub.c b/src/host/hub.c index 36f27398f..03cf0ecb4 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -78,7 +78,7 @@ static char const* const _hub_feature_str[] = // HUB //--------------------------------------------------------------------+ bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, - tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_arg) { tusb_control_request_t const request = { @@ -94,7 +94,7 @@ bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, .wLength = 0 }; - tuh_control_xfer_t xfer = + tuh_xfer_t xfer = { .ep_addr = 0, .setup = &request, @@ -109,7 +109,7 @@ bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, } bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, - tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_arg) { tusb_control_request_t const request = { @@ -125,7 +125,7 @@ bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, .wLength = 0 }; - tuh_control_xfer_t xfer = + tuh_xfer_t xfer = { .ep_addr = 0, .setup = &request, @@ -140,7 +140,7 @@ bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, } bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, - tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_arg) { tusb_control_request_t const request = { @@ -156,7 +156,7 @@ bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, .wLength = 4 }; - tuh_control_xfer_t xfer = + tuh_xfer_t xfer = { .ep_addr = 0, .setup = &request, @@ -225,8 +225,8 @@ bool hub_edpt_status_xfer(uint8_t dev_addr) // Set Configure //--------------------------------------------------------------------+ -static void config_set_port_power (uint8_t dev_addr, tuh_control_xfer_t* xfer); -static void config_port_power_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer); +static void config_set_port_power (uint8_t dev_addr, tuh_xfer_t* xfer); +static void config_port_power_complete (uint8_t dev_addr, tuh_xfer_t* xfer); bool hub_set_config(uint8_t dev_addr, uint8_t itf_num) { @@ -248,7 +248,7 @@ bool hub_set_config(uint8_t dev_addr, uint8_t itf_num) .wLength = sizeof(descriptor_hub_desc_t) }; - tuh_control_xfer_t xfer = + tuh_xfer_t xfer = { .ep_addr = 0, .setup = &request, @@ -262,7 +262,7 @@ bool hub_set_config(uint8_t dev_addr, uint8_t itf_num) return true; } -static void config_set_port_power (uint8_t dev_addr, tuh_control_xfer_t* xfer) +static void config_set_port_power (uint8_t dev_addr, tuh_xfer_t* xfer) { TU_ASSERT(XFER_RESULT_SUCCESS == xfer->result, ); @@ -279,7 +279,7 @@ static void config_set_port_power (uint8_t dev_addr, tuh_control_xfer_t* xfer) hub_port_set_feature(dev_addr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete, 0); } -static void config_port_power_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer) +static void config_port_power_complete (uint8_t dev_addr, tuh_xfer_t* xfer) { TU_ASSERT(XFER_RESULT_SUCCESS == xfer->result, ); hub_interface_t* p_hub = get_itf(dev_addr); @@ -303,9 +303,9 @@ static void config_port_power_complete (uint8_t dev_addr, tuh_control_xfer_t* xf // Connection Changes //--------------------------------------------------------------------+ -static void connection_get_status_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer); -static void connection_clear_conn_change_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer); -static void connection_port_reset_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer); +static void connection_get_status_complete (uint8_t dev_addr, tuh_xfer_t* xfer); +static void connection_clear_conn_change_complete (uint8_t dev_addr, tuh_xfer_t* xfer); +static void connection_port_reset_complete (uint8_t dev_addr, tuh_xfer_t* xfer); // callback as response of interrupt endpoint polling bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) @@ -333,7 +333,7 @@ bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32 return true; } -static void connection_get_status_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer) +static void connection_get_status_complete (uint8_t dev_addr, tuh_xfer_t* xfer) { TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, ); @@ -359,7 +359,7 @@ static void connection_get_status_complete (uint8_t dev_addr, tuh_control_xfer_t } } -static void connection_clear_conn_change_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer) +static void connection_clear_conn_change_complete (uint8_t dev_addr, tuh_xfer_t* xfer) { TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, ); @@ -388,7 +388,7 @@ static void connection_clear_conn_change_complete (uint8_t dev_addr, tuh_control } } -static void connection_port_reset_complete (uint8_t dev_addr, tuh_control_xfer_t* xfer) +static void connection_port_reset_complete (uint8_t dev_addr, tuh_xfer_t* xfer) { TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, ); diff --git a/src/host/hub.h b/src/host/hub.h index 30cf3dd1c..e5e22102a 100644 --- a/src/host/hub.h +++ b/src/host/hub.h @@ -173,29 +173,29 @@ TU_VERIFY_STATIC( sizeof(hub_port_status_response_t) == 4, "size is not correct" // Clear feature bool hub_port_clear_feature (uint8_t hub_addr, uint8_t hub_port, uint8_t feature, - tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); + tuh_xfer_cb_t complete_cb, uintptr_t user_arg); // Set feature bool hub_port_set_feature (uint8_t hub_addr, uint8_t hub_port, uint8_t feature, - tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); + tuh_xfer_cb_t complete_cb, uintptr_t user_arg); // Get port status bool hub_port_get_status (uint8_t hub_addr, uint8_t hub_port, void* resp, - tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); + tuh_xfer_cb_t complete_cb, uintptr_t user_arg); // Get status from Interrupt endpoint bool hub_edpt_status_xfer(uint8_t dev_addr); // Reset a port static inline bool hub_port_reset(uint8_t hub_addr, uint8_t hub_port, - tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_arg) { return hub_port_set_feature(hub_addr, hub_port, HUB_FEATURE_PORT_RESET, complete_cb, user_arg); } // Clear Reset Change static inline bool hub_port_clear_reset_change(uint8_t hub_addr, uint8_t hub_port, - tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_arg) { return hub_port_clear_feature(hub_addr, hub_port, HUB_FEATURE_PORT_RESET_CHANGE, complete_cb, user_arg); } diff --git a/src/host/usbh.c b/src/host/usbh.c index 96dd390b0..534f2458b 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -247,7 +247,7 @@ struct { tusb_control_request_t request TU_ATTR_ALIGNED(4); uint8_t* buffer; - tuh_control_xfer_cb_t complete_cb; + tuh_xfer_cb_t complete_cb; uintptr_t user_arg; volatile uint16_t actual_len; @@ -311,7 +311,7 @@ void osal_task_delay(uint32_t msec) //--------------------------------------------------------------------+ static bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t language_id, void* buffer, uint16_t len, - tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_arg) { tusb_control_request_t const request = { @@ -327,7 +327,7 @@ static bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t .wLength = tu_htole16(len) }; - tuh_control_xfer_t xfer = + tuh_xfer_t xfer = { .ep_addr = 0, .setup = &request, @@ -340,20 +340,20 @@ static bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t } bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len, - tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_arg) { return _get_descriptor(daddr, type, index, 0x0000, buffer, len, complete_cb, user_arg); } bool tuh_descriptor_get_device(uint8_t daddr, void* buffer, uint16_t len, - tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_arg) { len = tu_min16(len, sizeof(tusb_desc_device_t)); return tuh_descriptor_get(daddr, TUSB_DESC_DEVICE, 0, buffer, len, complete_cb, user_arg); } bool tuh_descriptor_get_configuration(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, - tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_arg) { return tuh_descriptor_get(daddr, TUSB_DESC_CONFIGURATION, index, buffer, len, complete_cb, user_arg); } @@ -361,14 +361,14 @@ bool tuh_descriptor_get_configuration(uint8_t daddr, uint8_t index, void* buffer //------------- String Descriptor -------------// bool tuh_descriptor_get_string(uint8_t daddr, uint8_t index, uint16_t language_id, void* buffer, uint16_t len, - tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_arg) { return _get_descriptor(daddr, TUSB_DESC_STRING, index, language_id, buffer, len, complete_cb, user_arg); } // Get manufacturer string descriptor bool tuh_descriptor_get_manufacturer_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, - tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_arg) { usbh_device_t const* dev = get_device(daddr); TU_VERIFY(dev && dev->i_manufacturer); @@ -377,7 +377,7 @@ bool tuh_descriptor_get_manufacturer_string(uint8_t daddr, uint16_t language_id, // Get product string descriptor bool tuh_descriptor_get_product_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, - tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_arg) { usbh_device_t const* dev = get_device(daddr); TU_VERIFY(dev && dev->i_product); @@ -386,7 +386,7 @@ bool tuh_descriptor_get_product_string(uint8_t daddr, uint16_t language_id, void // Get serial string descriptor bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, - tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_arg) { usbh_device_t const* dev = get_device(daddr); TU_VERIFY(dev && dev->i_serial); @@ -395,7 +395,7 @@ bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void* // Get HID report descriptor bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, void* buffer, uint16_t len, - tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_arg) { TU_LOG2("HID Get Report Descriptor\r\n"); tusb_control_request_t const request = @@ -412,7 +412,7 @@ bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_ .wLength = len }; - tuh_control_xfer_t xfer = + tuh_xfer_t xfer = { .ep_addr = 0, .setup = &request, @@ -425,7 +425,7 @@ bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_ } bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, - tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_arg) { TU_LOG2("Set Configuration = %d\r\n", config_num); @@ -443,7 +443,7 @@ bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, .wLength = 0 }; - tuh_control_xfer_t xfer = + tuh_xfer_t xfer = { .ep_addr = 0, .setup = &request, @@ -531,7 +531,7 @@ bool tuh_init(uint8_t rhport) TU_LOG2("USBH init\r\n"); TU_LOG2_INT(sizeof(usbh_device_t)); TU_LOG2_INT(sizeof(hcd_event_t)); - TU_LOG2_INT(sizeof(tuh_control_xfer_t)); + TU_LOG2_INT(sizeof(tuh_xfer_t)); // Event queue _usbh_q = osal_queue_create( &_usbh_qdef ); @@ -883,14 +883,14 @@ bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) // Control transfer //--------------------------------------------------------------------+ -static void _control_blocking_complete_cb(uint8_t daddr, tuh_control_xfer_t* xfer) +static void _control_blocking_complete_cb(uint8_t daddr, tuh_xfer_t* xfer) { (void) daddr; // update result *((xfer_result_t*) xfer->user_arg) = xfer->result; } -bool tuh_control_xfer (uint8_t daddr, tuh_control_xfer_t* xfer) +bool tuh_control_xfer (uint8_t daddr, tuh_xfer_t* xfer) { // pre-check to help reducing mutex lock TU_VERIFY(_ctrl_xfer.stage == CONTROL_STAGE_IDLE); @@ -956,7 +956,7 @@ bool tuh_control_xfer (uint8_t daddr, tuh_control_xfer_t* xfer) return true; } -bool tuh_control_xfer_sync(uint8_t daddr, tuh_control_xfer_t* xfer, uint32_t timeout_ms) +bool tuh_control_xfer_sync(uint8_t daddr, tuh_xfer_t* xfer, uint32_t timeout_ms) { (void) timeout_ms; @@ -982,7 +982,7 @@ static void _xfer_complete(uint8_t dev_addr, xfer_result_t result) // duplicate xfer since user can execute control transfer within callback tusb_control_request_t const request = _ctrl_xfer.request; - tuh_control_xfer_t xfer_temp = + tuh_xfer_t xfer_temp = { .ep_addr = 0, .result = result, @@ -1125,7 +1125,7 @@ static bool parse_configuration_descriptor (uint8_t dev_addr, tusb_desc_configur static void enum_full_complete(void); // process device enumeration -static void process_enumeration(uint8_t dev_addr, tuh_control_xfer_t* xfer) +static void process_enumeration(uint8_t dev_addr, tuh_xfer_t* xfer) { if (XFER_RESULT_SUCCESS != xfer->result) { @@ -1327,7 +1327,7 @@ static bool enum_new_device(hcd_event_t* event) TU_LOG2("%s Speed\r\n", tu_str_speed[_dev0.speed]); // fake transfer to kick-off the enumeration process - tuh_control_xfer_t xfer; + tuh_xfer_t xfer; xfer.result = XFER_RESULT_SUCCESS; xfer.user_arg = ENUM_ADDR0_DEVICE_DESC; @@ -1410,7 +1410,7 @@ static bool enum_request_set_addr(void) .wLength = 0 }; - tuh_control_xfer_t xfer = + tuh_xfer_t xfer = { .ep_addr = 0, .setup = &request, diff --git a/src/host/usbh.h b/src/host/usbh.h index e6897d8d8..73fe2e08f 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -39,12 +39,12 @@ //--------------------------------------------------------------------+ // forward declaration -struct tuh_control_xfer_s; -typedef struct tuh_control_xfer_s tuh_control_xfer_t; +struct tuh_xfer_s; +typedef struct tuh_xfer_s tuh_xfer_t; -typedef void (*tuh_control_xfer_cb_t)(uint8_t daddr, tuh_control_xfer_t* xfer); +typedef void (*tuh_xfer_cb_t)(uint8_t daddr, tuh_xfer_t* xfer); -struct tuh_control_xfer_s +struct tuh_xfer_s { uint8_t ep_addr; xfer_result_t result; @@ -53,7 +53,7 @@ struct tuh_control_xfer_s uint32_t actual_len; // excluding setup packet uint8_t* buffer; - tuh_control_xfer_cb_t complete_cb; + tuh_xfer_cb_t complete_cb; uintptr_t user_arg; }; @@ -117,7 +117,7 @@ static inline bool tuh_ready(uint8_t daddr) // true on success, false if there is on-going control transfer or incorrect parameters // Note: blocking if complete callback is NULL. In this case 'xfer->result' will be updated // and if 'user_arg' point to a xfer_result_t variable, it will be updated as well. -bool tuh_control_xfer(uint8_t daddr, tuh_control_xfer_t* xfer); +bool tuh_control_xfer(uint8_t daddr, tuh_xfer_t* xfer); //bool tuh_edpt_xfer(uint8_t daddr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes); @@ -125,7 +125,7 @@ bool tuh_control_xfer(uint8_t daddr, tuh_control_xfer_t* xfer); // config_num = 0 will un-configure device. Note: config_num = config_descriptor_index + 1 // true on success, false if there is on-going control transfer or incorrect parameters bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, - tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); + tuh_xfer_cb_t complete_cb, uintptr_t user_arg); //--------------------------------------------------------------------+ // Endpoint Synchronous (blocking) @@ -133,7 +133,7 @@ bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, // Sync (blocking) version of tuh_control_xfer() // xfer contents will be updated to reflect the transfer -bool tuh_control_xfer_sync(uint8_t daddr, tuh_control_xfer_t * xfer, uint32_t timeout_ms); +bool tuh_control_xfer_sync(uint8_t daddr, tuh_xfer_t * xfer, uint32_t timeout_ms); //--------------------------------------------------------------------+ // Descriptors Asynchronous (non-blocking) @@ -142,43 +142,43 @@ bool tuh_control_xfer_sync(uint8_t daddr, tuh_control_xfer_t * xfer, uint32_t ti // Get an descriptor (control transfer) // true on success, false if there is on-going control transfer or incorrect parameters bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len, - tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); + tuh_xfer_cb_t complete_cb, uintptr_t user_arg); // Get device descriptor (control transfer) // true on success, false if there is on-going control transfer or incorrect parameters bool tuh_descriptor_get_device(uint8_t daddr, void* buffer, uint16_t len, - tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); + tuh_xfer_cb_t complete_cb, uintptr_t user_arg); // Get configuration descriptor (control transfer) // true on success, false if there is on-going control transfer or incorrect parameters bool tuh_descriptor_get_configuration(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, - tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); + tuh_xfer_cb_t complete_cb, uintptr_t user_arg); // Get HID report descriptor (control transfer) // true on success, false if there is on-going control transfer or incorrect parameters bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, void* buffer, uint16_t len, - tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); + tuh_xfer_cb_t complete_cb, uintptr_t user_arg); // Get string descriptor (control transfer) // true on success, false if there is on-going control transfer or incorrect parameters // Blocking if complete callback is NULL, in this case 'user_arg' must contain xfer_result_t variable bool tuh_descriptor_get_string(uint8_t daddr, uint8_t index, uint16_t language_id, void* buffer, uint16_t len, - tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); + tuh_xfer_cb_t complete_cb, uintptr_t user_arg); // Get manufacturer string descriptor (control transfer) // true on success, false if there is on-going control transfer or incorrect parameters bool tuh_descriptor_get_manufacturer_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, - tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); + tuh_xfer_cb_t complete_cb, uintptr_t user_arg); // Get product string descriptor (control transfer) // true on success, false if there is on-going control transfer or incorrect parameters bool tuh_descriptor_get_product_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, - tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); + tuh_xfer_cb_t complete_cb, uintptr_t user_arg); // Get serial string descriptor (control transfer) // true on success, false if there is on-going control transfer or incorrect parameters bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, - tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); + tuh_xfer_cb_t complete_cb, uintptr_t user_arg); //--------------------------------------------------------------------+ // Descriptors Synchronous (blocking) From 9dd2f11f4a08c337096776eacd919faec3cc939e Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 17 Mar 2022 21:20:20 +0700 Subject: [PATCH 254/504] add CFG_TUH_API_EDPT_XFER to enable generic edpt xfer --- examples/host/bare_api/src/tusb_config.h | 8 ++-- src/host/usbh.c | 47 ++++++++++++++++-------- src/host/usbh.h | 8 +++- src/tusb_option.h | 4 ++ 4 files changed, 46 insertions(+), 21 deletions(-) diff --git a/examples/host/bare_api/src/tusb_config.h b/examples/host/bare_api/src/tusb_config.h index 234eca402..9b789290d 100644 --- a/examples/host/bare_api/src/tusb_config.h +++ b/examples/host/bare_api/src/tusb_config.h @@ -81,11 +81,11 @@ // 1 hub typically has 4 ports #define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB ? 4 : 1) -#define CFG_TUH_ENDPOINT_MAX 8 +// Max endpoint per device +#define CFG_TUH_ENDPOINT_MAX 8 -//------------- HID -------------// - -#define CFG_TUH_HID_EP_BUFSIZE 64 +// Enable tuh_edpt_xfer() API +#define CFG_TUH_API_EDPT_XFER 1 #ifdef __cplusplus } diff --git a/src/host/usbh.c b/src/host/usbh.c index 534f2458b..689634ecd 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -109,8 +109,15 @@ typedef struct { tu_edpt_state_t ep_status[CFG_TUH_ENDPOINT_MAX][2]; -#if CFG_TUH_BARE - +#if CFG_TUH_API_EDPT_XFER +// struct +// { +// uint8_t* buffer; +// tuh_xfer_cb_t complete_cb; +// uintptr_t user_arg; +// +// volatile uint16_t actual_len; +// }ep_xfer; #endif } usbh_device_t; @@ -240,6 +247,16 @@ static osal_queue_t _usbh_q; CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t _usbh_ctrl_buf[CFG_TUH_ENUMERATION_BUFSIZE]; +//// internal version of tuh_xfer_t +//typedef struct +//{ +// uint8_t* buffer; +// tuh_xfer_cb_t complete_cb; +// uintptr_t user_arg; +// +// volatile uint16_t actual_len; +//}usbh_xfer_t; + // Control transfer: since most controller does not support multiple control transfer // on multiple devices concurrently. And control transfer is not used much except enumeration // We will only execute control transfer one at a time. @@ -890,6 +907,19 @@ static void _control_blocking_complete_cb(uint8_t daddr, tuh_xfer_t* xfer) *((xfer_result_t*) xfer->user_arg) = xfer->result; } +bool tuh_control_xfer_sync(uint8_t daddr, tuh_xfer_t* xfer, uint32_t timeout_ms) +{ + (void) timeout_ms; + + // clear callback for sync + xfer->complete_cb = NULL; + + // TODO use timeout to wait + TU_VERIFY(tuh_control_xfer(daddr, xfer)); + + return true; +} + bool tuh_control_xfer (uint8_t daddr, tuh_xfer_t* xfer) { // pre-check to help reducing mutex lock @@ -956,19 +986,6 @@ bool tuh_control_xfer (uint8_t daddr, tuh_xfer_t* xfer) return true; } -bool tuh_control_xfer_sync(uint8_t daddr, tuh_xfer_t* xfer, uint32_t timeout_ms) -{ - (void) timeout_ms; - - // clear callback for sync - xfer->complete_cb = NULL; - - // TODO use timeout to wait - TU_VERIFY(tuh_control_xfer(daddr, xfer)); - - return true; -} - TU_ATTR_ALWAYS_INLINE static inline void _set_control_xfer_stage(uint8_t stage) { usbh_lock(); diff --git a/src/host/usbh.h b/src/host/usbh.h index 73fe2e08f..2021545ba 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -113,13 +113,17 @@ static inline bool tuh_ready(uint8_t daddr) // Endpoint Asynchronous (non-blocking) //--------------------------------------------------------------------+ -// Carry out a control transfer +// Submit a control transfer // true on success, false if there is on-going control transfer or incorrect parameters // Note: blocking if complete callback is NULL. In this case 'xfer->result' will be updated // and if 'user_arg' point to a xfer_result_t variable, it will be updated as well. bool tuh_control_xfer(uint8_t daddr, tuh_xfer_t* xfer); -//bool tuh_edpt_xfer(uint8_t daddr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes); +// Submit a bulk/interrupt transfer +// true on success, false if there is on-going control transfer or incorrect parameters +// Note: blocking if complete callback is NULL. In this case 'xfer->result' will be updated +// and if 'user_arg' point to a xfer_result_t variable, it will be updated as well. +bool tuh_edpt_xfer(uint8_t daddr, tuh_xfer_t* xfer); // Set Configuration (control transfer) // config_num = 0 will un-configure device. Note: config_num = config_descriptor_index + 1 diff --git a/src/tusb_option.h b/src/tusb_option.h index 0352faaed..bd87a953c 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -392,6 +392,10 @@ #define CFG_TUH_VENDOR 0 #endif +#ifndef CFG_TUH_API_EDPT_XFER +#define CFG_TUH_API_EDPT_XFER 0 +#endif + //------------------------------------------------------------------ // Configuration Validation //------------------------------------------------------------------ From f89ff939d8088135cedaa4e4f3885f88d1670529 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 17 Mar 2022 22:37:51 +0700 Subject: [PATCH 255/504] rename user_arg to user_data --- src/class/cdc/cdc_host.c | 2 +- src/class/hid/hid_host.c | 18 ++++---- src/class/msc/msc_host.c | 2 +- src/host/hub.c | 14 +++--- src/host/hub.h | 14 +++--- src/host/usbh.c | 93 ++++++++++++++++++++++------------------ src/host/usbh.h | 37 ++++++++-------- 7 files changed, 95 insertions(+), 85 deletions(-) diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index a811eb667..2795750ed 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -144,7 +144,7 @@ bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_xf .setup = &request, .buffer = NULL, .complete_cb = complete_cb, - .user_arg = 0 + .user_data = 0 }; return tuh_control_xfer(dev_addr, &xfer); diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 705b73c67..0ad917815 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -121,7 +121,7 @@ static void set_protocol_complete(uint8_t dev_addr, tuh_xfer_t* xfer) } -static bool _hidh_set_protocol(uint8_t dev_addr, uint8_t itf_num, uint8_t protocol, tuh_xfer_cb_t complete_cb, uintptr_t user_arg) +static bool _hidh_set_protocol(uint8_t dev_addr, uint8_t itf_num, uint8_t protocol, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG2("HID Set Protocol = %d\r\n", protocol); @@ -145,7 +145,7 @@ static bool _hidh_set_protocol(uint8_t dev_addr, uint8_t itf_num, uint8_t protoc .setup = &request, .buffer = NULL, .complete_cb = complete_cb, - .user_arg = user_arg + .user_data = user_data }; TU_ASSERT( tuh_control_xfer(dev_addr, &xfer) ); @@ -202,14 +202,14 @@ bool tuh_hid_set_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, u .setup = &request, .buffer = report, .complete_cb = set_report_complete, - .user_arg = 0 + .user_data = 0 }; TU_ASSERT( tuh_control_xfer(dev_addr, &xfer) ); return true; } -static bool _hidh_set_idle(uint8_t dev_addr, uint8_t itf_num, uint16_t idle_rate, tuh_xfer_cb_t complete_cb, uintptr_t user_arg) +static bool _hidh_set_idle(uint8_t dev_addr, uint8_t itf_num, uint16_t idle_rate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { // SET IDLE request, device can stall if not support this request TU_LOG2("HID Set Idle \r\n"); @@ -233,7 +233,7 @@ static bool _hidh_set_idle(uint8_t dev_addr, uint8_t itf_num, uint16_t idle_rate .setup = &request, .buffer = NULL, .complete_cb = complete_cb, - .user_arg = user_arg + .user_data = user_data }; TU_ASSERT( tuh_control_xfer(dev_addr, &xfer) ); @@ -397,9 +397,9 @@ bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num) request.wIndex = tu_htole16((uint16_t) itf_num); tuh_xfer_t xfer; - xfer.result = XFER_RESULT_SUCCESS; - xfer.setup = &request; - xfer.user_arg = CONFG_SET_IDLE; + xfer.result = XFER_RESULT_SUCCESS; + xfer.setup = &request; + xfer.user_data = CONFG_SET_IDLE; // fake request to kick-off the set config process process_set_config(dev_addr, &xfer); @@ -415,7 +415,7 @@ static void process_set_config(uint8_t dev_addr, tuh_xfer_t* xfer) TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, ); } - uintptr_t const state = xfer->user_arg; + uintptr_t const state = xfer->user_data; uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); hidh_interface_t* hid_itf = get_instance(dev_addr, instance); diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index 789ae9c1a..5a34f2d56 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -425,7 +425,7 @@ bool msch_set_config(uint8_t dev_addr, uint8_t itf_num) .setup = &request, .buffer = &p_msc->max_lun, .complete_cb = config_get_maxlun_complete, - .user_arg = 0 + .user_data = 0 }; TU_ASSERT(tuh_control_xfer(dev_addr, &xfer)); diff --git a/src/host/hub.c b/src/host/hub.c index 03cf0ecb4..ac24988d8 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -78,7 +78,7 @@ static char const* const _hub_feature_str[] = // HUB //--------------------------------------------------------------------+ bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, - tuh_xfer_cb_t complete_cb, uintptr_t user_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { tusb_control_request_t const request = { @@ -100,7 +100,7 @@ bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, .setup = &request, .buffer = NULL, .complete_cb = complete_cb, - .user_arg = user_arg + .user_data = user_data }; TU_LOG2("HUB Clear Feature: %s, addr = %u port = %u\r\n", _hub_feature_str[feature], hub_addr, hub_port); @@ -109,7 +109,7 @@ bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, } bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, - tuh_xfer_cb_t complete_cb, uintptr_t user_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { tusb_control_request_t const request = { @@ -131,7 +131,7 @@ bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, .setup = &request, .buffer = NULL, .complete_cb = complete_cb, - .user_arg = user_arg + .user_data = user_data }; TU_LOG2("HUB Set Feature: %s, addr = %u port = %u\r\n", _hub_feature_str[feature], hub_addr, hub_port); @@ -140,7 +140,7 @@ bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, } bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, - tuh_xfer_cb_t complete_cb, uintptr_t user_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { tusb_control_request_t const request = { @@ -162,7 +162,7 @@ bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, .setup = &request, .buffer = resp, .complete_cb = complete_cb, - .user_arg = user_arg + .user_data = user_data }; TU_LOG2("HUB Get Port Status: addr = %u port = %u\r\n", hub_addr, hub_port); @@ -254,7 +254,7 @@ bool hub_set_config(uint8_t dev_addr, uint8_t itf_num) .setup = &request, .buffer = _hub_buffer, .complete_cb = config_set_port_power, - .user_arg = 0 + .user_data = 0 }; TU_ASSERT( tuh_control_xfer(dev_addr, &xfer) ); diff --git a/src/host/hub.h b/src/host/hub.h index e5e22102a..390740e1f 100644 --- a/src/host/hub.h +++ b/src/host/hub.h @@ -173,31 +173,31 @@ TU_VERIFY_STATIC( sizeof(hub_port_status_response_t) == 4, "size is not correct" // Clear feature bool hub_port_clear_feature (uint8_t hub_addr, uint8_t hub_port, uint8_t feature, - tuh_xfer_cb_t complete_cb, uintptr_t user_arg); + tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Set feature bool hub_port_set_feature (uint8_t hub_addr, uint8_t hub_port, uint8_t feature, - tuh_xfer_cb_t complete_cb, uintptr_t user_arg); + tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Get port status bool hub_port_get_status (uint8_t hub_addr, uint8_t hub_port, void* resp, - tuh_xfer_cb_t complete_cb, uintptr_t user_arg); + tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Get status from Interrupt endpoint bool hub_edpt_status_xfer(uint8_t dev_addr); // Reset a port static inline bool hub_port_reset(uint8_t hub_addr, uint8_t hub_port, - tuh_xfer_cb_t complete_cb, uintptr_t user_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - return hub_port_set_feature(hub_addr, hub_port, HUB_FEATURE_PORT_RESET, complete_cb, user_arg); + return hub_port_set_feature(hub_addr, hub_port, HUB_FEATURE_PORT_RESET, complete_cb, user_data); } // Clear Reset Change static inline bool hub_port_clear_reset_change(uint8_t hub_addr, uint8_t hub_port, - tuh_xfer_cb_t complete_cb, uintptr_t user_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - return hub_port_clear_feature(hub_addr, hub_port, HUB_FEATURE_PORT_RESET_CHANGE, complete_cb, user_arg); + return hub_port_clear_feature(hub_addr, hub_port, HUB_FEATURE_PORT_RESET_CHANGE, complete_cb, user_data); } diff --git a/src/host/usbh.c b/src/host/usbh.c index 689634ecd..69543854d 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -110,14 +110,14 @@ typedef struct { tu_edpt_state_t ep_status[CFG_TUH_ENDPOINT_MAX][2]; #if CFG_TUH_API_EDPT_XFER -// struct -// { -// uint8_t* buffer; -// tuh_xfer_cb_t complete_cb; -// uintptr_t user_arg; -// -// volatile uint16_t actual_len; -// }ep_xfer; + struct + { + uint8_t* buffer; + tuh_xfer_cb_t complete_cb; + uintptr_t user_data; + uint16_t buflen; + volatile uint16_t actual_len; + }ep_xfer; #endif } usbh_device_t; @@ -252,7 +252,7 @@ static uint8_t _usbh_ctrl_buf[CFG_TUH_ENUMERATION_BUFSIZE]; //{ // uint8_t* buffer; // tuh_xfer_cb_t complete_cb; -// uintptr_t user_arg; +// uintptr_t user_data; // // volatile uint16_t actual_len; //}usbh_xfer_t; @@ -265,7 +265,7 @@ struct tusb_control_request_t request TU_ATTR_ALIGNED(4); uint8_t* buffer; tuh_xfer_cb_t complete_cb; - uintptr_t user_arg; + uintptr_t user_data; volatile uint16_t actual_len; uint8_t daddr; // device address that is transferring @@ -328,7 +328,7 @@ void osal_task_delay(uint32_t msec) //--------------------------------------------------------------------+ static bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t language_id, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { tusb_control_request_t const request = { @@ -350,69 +350,69 @@ static bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t .setup = &request, .buffer = buffer, .complete_cb = complete_cb, - .user_arg = user_arg + .user_data = user_data }; return tuh_control_xfer(daddr, &xfer); } bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - return _get_descriptor(daddr, type, index, 0x0000, buffer, len, complete_cb, user_arg); + return _get_descriptor(daddr, type, index, 0x0000, buffer, len, complete_cb, user_data); } bool tuh_descriptor_get_device(uint8_t daddr, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { len = tu_min16(len, sizeof(tusb_desc_device_t)); - return tuh_descriptor_get(daddr, TUSB_DESC_DEVICE, 0, buffer, len, complete_cb, user_arg); + return tuh_descriptor_get(daddr, TUSB_DESC_DEVICE, 0, buffer, len, complete_cb, user_data); } bool tuh_descriptor_get_configuration(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - return tuh_descriptor_get(daddr, TUSB_DESC_CONFIGURATION, index, buffer, len, complete_cb, user_arg); + return tuh_descriptor_get(daddr, TUSB_DESC_CONFIGURATION, index, buffer, len, complete_cb, user_data); } //------------- String Descriptor -------------// bool tuh_descriptor_get_string(uint8_t daddr, uint8_t index, uint16_t language_id, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - return _get_descriptor(daddr, TUSB_DESC_STRING, index, language_id, buffer, len, complete_cb, user_arg); + return _get_descriptor(daddr, TUSB_DESC_STRING, index, language_id, buffer, len, complete_cb, user_data); } // Get manufacturer string descriptor bool tuh_descriptor_get_manufacturer_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { usbh_device_t const* dev = get_device(daddr); TU_VERIFY(dev && dev->i_manufacturer); - return tuh_descriptor_get_string(daddr, dev->i_manufacturer, language_id, buffer, len, complete_cb, user_arg); + return tuh_descriptor_get_string(daddr, dev->i_manufacturer, 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_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { usbh_device_t const* dev = get_device(daddr); TU_VERIFY(dev && dev->i_product); - return tuh_descriptor_get_string(daddr, dev->i_product, language_id, buffer, len, complete_cb, user_arg); + return tuh_descriptor_get_string(daddr, dev->i_product, 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_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { usbh_device_t const* dev = get_device(daddr); TU_VERIFY(dev && dev->i_serial); - return tuh_descriptor_get_string(daddr, dev->i_serial, language_id, buffer, len, complete_cb, user_arg); + return tuh_descriptor_get_string(daddr, dev->i_serial, language_id, buffer, len, complete_cb, user_data); } // Get HID report descriptor bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG2("HID Get Report Descriptor\r\n"); tusb_control_request_t const request = @@ -435,14 +435,14 @@ bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_ .setup = &request, .buffer = buffer, .complete_cb = complete_cb, - .user_arg = user_arg + .user_data = user_data }; return tuh_control_xfer(daddr, &xfer); } bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, - tuh_xfer_cb_t complete_cb, uintptr_t user_arg) + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG2("Set Configuration = %d\r\n", config_num); @@ -466,7 +466,7 @@ bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, .setup = &request, .buffer = NULL, .complete_cb = complete_cb, - .user_arg = user_arg + .user_data = user_data }; return tuh_control_xfer(daddr, &xfer); @@ -904,7 +904,7 @@ static void _control_blocking_complete_cb(uint8_t daddr, tuh_xfer_t* xfer) { (void) daddr; // update result - *((xfer_result_t*) xfer->user_arg) = xfer->result; + *((xfer_result_t*) xfer->user_data) = xfer->result; } bool tuh_control_xfer_sync(uint8_t daddr, tuh_xfer_t* xfer, uint32_t timeout_ms) @@ -945,7 +945,7 @@ bool tuh_control_xfer (uint8_t daddr, tuh_xfer_t* xfer) _ctrl_xfer.request = (*xfer->setup); _ctrl_xfer.buffer = xfer->buffer; _ctrl_xfer.complete_cb = xfer->complete_cb; - _ctrl_xfer.user_arg = xfer->user_arg; + _ctrl_xfer.user_data = xfer->user_data; if (xfer->complete_cb) { @@ -956,8 +956,8 @@ bool tuh_control_xfer (uint8_t daddr, tuh_xfer_t* xfer) // change callback to internal blocking, and result as user argument volatile xfer_result_t result = XFER_RESULT_INVALID; - // use user_arg to point to xfer_result_t - _ctrl_xfer.user_arg = (uintptr_t) &result; + // use user_data to point to xfer_result_t + _ctrl_xfer.user_data = (uintptr_t) &result; _ctrl_xfer.complete_cb = _control_blocking_complete_cb; TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t*) &_ctrl_xfer.request) ); @@ -974,10 +974,10 @@ bool tuh_control_xfer (uint8_t daddr, tuh_xfer_t* xfer) // update xfer result xfer->result = result; - if ( xfer->user_arg ) + if ( xfer->user_data ) { - // if user_arg is not NULL, it is also updated - *((xfer_result_t*) xfer->user_arg) = result; + // if user_data is not NULL, it is also updated + *((xfer_result_t*) xfer->user_data) = result; } xfer->actual_len = _ctrl_xfer.actual_len; @@ -1007,7 +1007,7 @@ static void _xfer_complete(uint8_t dev_addr, xfer_result_t result) .actual_len = (uint32_t) _ctrl_xfer.actual_len, .buffer = _ctrl_xfer.buffer, .complete_cb = _ctrl_xfer.complete_cb, - .user_arg = _ctrl_xfer.user_arg + .user_data = _ctrl_xfer.user_data }; usbh_lock(); @@ -1075,6 +1075,15 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result // //--------------------------------------------------------------------+ +bool tuh_edpt_xfer(uint8_t daddr, tuh_xfer_t* xfer) +{ + return true; +} + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ + // a device unplugged from rhport:hub_addr:hub_port static void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port) { @@ -1151,7 +1160,7 @@ static void process_enumeration(uint8_t dev_addr, tuh_xfer_t* xfer) return; } - uintptr_t const state = xfer->user_arg; + uintptr_t const state = xfer->user_data; switch(state) { #if CFG_TUH_HUB @@ -1345,8 +1354,8 @@ static bool enum_new_device(hcd_event_t* event) // fake transfer to kick-off the enumeration process tuh_xfer_t xfer; - xfer.result = XFER_RESULT_SUCCESS; - xfer.user_arg = ENUM_ADDR0_DEVICE_DESC; + xfer.result = XFER_RESULT_SUCCESS; + xfer.user_data = ENUM_ADDR0_DEVICE_DESC; process_enumeration(0, &xfer); @@ -1433,7 +1442,7 @@ static bool enum_request_set_addr(void) .setup = &request, .buffer = NULL, .complete_cb = process_enumeration, - .user_arg = ENUM_GET_DEVICE_DESC + .user_data = ENUM_GET_DEVICE_DESC }; uint8_t const addr0 = 0; diff --git a/src/host/usbh.h b/src/host/usbh.h index 2021545ba..30868d2f2 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -47,14 +47,15 @@ typedef void (*tuh_xfer_cb_t)(uint8_t daddr, tuh_xfer_t* xfer); struct tuh_xfer_s { uint8_t ep_addr; - xfer_result_t result; - - tusb_control_request_t const* setup; - uint32_t actual_len; // excluding setup packet - + tusb_control_request_t const* setup; // pointer to setup packet if control transfer + uint32_t buflen; uint8_t* buffer; tuh_xfer_cb_t complete_cb; - uintptr_t user_arg; + uintptr_t user_data; + + // will be updated when transfer is complete + xfer_result_t result; + uint32_t actual_len; // excluding setup packet }; //--------------------------------------------------------------------+ @@ -116,20 +117,20 @@ static inline bool tuh_ready(uint8_t daddr) // Submit a control transfer // true on success, false if there is on-going control transfer or incorrect parameters // Note: blocking if complete callback is NULL. In this case 'xfer->result' will be updated -// and if 'user_arg' point to a xfer_result_t variable, it will be updated as well. +// and if 'user_data' point to a xfer_result_t variable, it will be updated as well. bool tuh_control_xfer(uint8_t daddr, tuh_xfer_t* xfer); // Submit a bulk/interrupt transfer // true on success, false if there is on-going control transfer or incorrect parameters // Note: blocking if complete callback is NULL. In this case 'xfer->result' will be updated -// and if 'user_arg' point to a xfer_result_t variable, it will be updated as well. +// and if 'user_data' point to a xfer_result_t variable, it will be updated as well. bool tuh_edpt_xfer(uint8_t daddr, tuh_xfer_t* xfer); // Set Configuration (control transfer) // config_num = 0 will un-configure device. Note: config_num = config_descriptor_index + 1 // true on success, false if there is on-going control transfer or incorrect parameters bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, - tuh_xfer_cb_t complete_cb, uintptr_t user_arg); + tuh_xfer_cb_t complete_cb, uintptr_t user_data); //--------------------------------------------------------------------+ // Endpoint Synchronous (blocking) @@ -146,43 +147,43 @@ bool tuh_control_xfer_sync(uint8_t daddr, tuh_xfer_t * xfer, uint32_t timeout_ms // Get an descriptor (control transfer) // true on success, false if there is on-going control transfer or incorrect parameters bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_arg); + tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Get device descriptor (control transfer) // true on success, false if there is on-going control transfer or incorrect parameters bool tuh_descriptor_get_device(uint8_t daddr, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_arg); + tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Get configuration descriptor (control transfer) // true on success, false if there is on-going control transfer or incorrect parameters bool tuh_descriptor_get_configuration(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_arg); + tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Get HID report descriptor (control transfer) // true on success, false if there is on-going control transfer or incorrect parameters bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_arg); + tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Get string descriptor (control transfer) // true on success, false if there is on-going control transfer or incorrect parameters -// Blocking if complete callback is NULL, in this case 'user_arg' must contain xfer_result_t variable +// Blocking if complete callback is NULL, in this case 'user_data' must contain xfer_result_t variable bool tuh_descriptor_get_string(uint8_t daddr, uint8_t index, uint16_t language_id, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_arg); + tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Get manufacturer string descriptor (control transfer) // true on success, false if there is on-going control transfer or incorrect parameters bool tuh_descriptor_get_manufacturer_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_arg); + tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Get product string descriptor (control transfer) // true on success, false if there is on-going control transfer or incorrect parameters 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_arg); + tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Get serial string descriptor (control transfer) // true on success, false if there is on-going control transfer or incorrect parameters 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_arg); + tuh_xfer_cb_t complete_cb, uintptr_t user_data); //--------------------------------------------------------------------+ // Descriptors Synchronous (blocking) From c063ab49443924afec43a295871205ed61535622 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 18 Mar 2022 00:56:51 +0700 Subject: [PATCH 256/504] try to fix ci --- src/host/usbh.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index 69543854d..6808a24a1 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -268,7 +268,7 @@ struct uintptr_t user_data; volatile uint16_t actual_len; - uint8_t daddr; // device address that is transferring + uint8_t daddr; // transferring device volatile uint8_t stage; }_ctrl_xfer; @@ -548,7 +548,7 @@ bool tuh_init(uint8_t rhport) TU_LOG2("USBH init\r\n"); TU_LOG2_INT(sizeof(usbh_device_t)); TU_LOG2_INT(sizeof(hcd_event_t)); - TU_LOG2_INT(sizeof(tuh_xfer_t)); + TU_LOG2_INT(sizeof(_ctrl_xfer)); // Event queue _usbh_q = osal_queue_create( &_usbh_qdef ); @@ -1077,6 +1077,8 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result bool tuh_edpt_xfer(uint8_t daddr, tuh_xfer_t* xfer) { + (void) daddr; + (void) xfer; return true; } From 85c6d6d37d3696680b650e211ef8dd279b1f9f26 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 18 Mar 2022 12:51:12 +0700 Subject: [PATCH 257/504] minor update for control xfer --- src/host/usbh.c | 66 +++++++++++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index 6808a24a1..a45ab8efa 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -110,14 +110,14 @@ typedef struct { tu_edpt_state_t ep_status[CFG_TUH_ENDPOINT_MAX][2]; #if CFG_TUH_API_EDPT_XFER - struct - { - uint8_t* buffer; - tuh_xfer_cb_t complete_cb; - uintptr_t user_data; - uint16_t buflen; - volatile uint16_t actual_len; - }ep_xfer; +// struct +// { +// uint8_t* buffer; +// tuh_xfer_cb_t complete_cb; +// uintptr_t user_data; +// uint16_t buflen; +// volatile uint16_t actual_len; +// }ep_xfer[[]]; #endif } usbh_device_t; @@ -247,16 +247,6 @@ static osal_queue_t _usbh_q; CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t _usbh_ctrl_buf[CFG_TUH_ENUMERATION_BUFSIZE]; -//// internal version of tuh_xfer_t -//typedef struct -//{ -// uint8_t* buffer; -// tuh_xfer_cb_t complete_cb; -// uintptr_t user_data; -// -// volatile uint16_t actual_len; -//}usbh_xfer_t; - // Control transfer: since most controller does not support multiple control transfer // on multiple devices concurrently. And control transfer is not used much except enumeration // We will only execute control transfer one at a time. @@ -267,9 +257,9 @@ struct tuh_xfer_cb_t complete_cb; uintptr_t user_data; - volatile uint16_t actual_len; - uint8_t daddr; // transferring device + uint8_t daddr; volatile uint8_t stage; + volatile uint16_t actual_len; }_ctrl_xfer; //------------- Helper Function -------------// @@ -298,6 +288,8 @@ bool tuh_mounted(uint8_t dev_addr) 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->configured); @@ -327,6 +319,8 @@ void osal_task_delay(uint32_t msec) // Descriptors Async //--------------------------------------------------------------------+ +// generic helper to get a descriptor +// if blocking, user_data could be pointed to xfer_result static bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t language_id, void* buffer, uint16_t len, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { @@ -353,7 +347,15 @@ static bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t .user_data = user_data }; - return tuh_control_xfer(daddr, &xfer); + bool const ret = tuh_control_xfer(daddr, &xfer); + + // if blocking, user_data could be pointed to xfer_result + if ( !complete_cb && user_data ) + { + *((xfer_result_t*) user_data) = xfer.result; + } + + return ret; } bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len, @@ -411,6 +413,7 @@ bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void* } // Get HID report descriptor +// if blocking, user_data could be pointed to xfer_result bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, void* buffer, uint16_t len, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { @@ -438,7 +441,15 @@ bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_ .user_data = user_data }; - return tuh_control_xfer(daddr, &xfer); + bool const ret = tuh_control_xfer(daddr, &xfer); + + // if blocking, user_data could be pointed to xfer_result + if ( !complete_cb && user_data ) + { + *((xfer_result_t*) user_data) = xfer.result; + } + + return ret; } bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, @@ -549,6 +560,7 @@ bool tuh_init(uint8_t rhport) TU_LOG2_INT(sizeof(usbh_device_t)); TU_LOG2_INT(sizeof(hcd_event_t)); TU_LOG2_INT(sizeof(_ctrl_xfer)); + TU_LOG2_INT(sizeof(tuh_xfer_t)); // Event queue _usbh_q = osal_queue_create( &_usbh_qdef ); @@ -972,14 +984,8 @@ bool tuh_control_xfer (uint8_t daddr, tuh_xfer_t* xfer) // TODO probably some timeout to prevent hanged } - // update xfer result - xfer->result = result; - if ( xfer->user_data ) - { - // if user_data is not NULL, it is also updated - *((xfer_result_t*) xfer->user_data) = result; - } - + // update transfer result + xfer->result = result; xfer->actual_len = _ctrl_xfer.actual_len; } From 2ff8978dde779607ddf01ba8e9d8dfeb70bfbd03 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 18 Mar 2022 13:38:30 +0700 Subject: [PATCH 258/504] update sync API, move timeout into xfer struct remove tuh_control_xfer_sync() --- examples/host/bare_api/src/main.c | 7 ++--- src/host/usbh.c | 51 +++++++++++-------------------- src/host/usbh.h | 48 ++++++++++++++--------------- 3 files changed, 44 insertions(+), 62 deletions(-) diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index feb94a6fe..b472c40c4 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -136,11 +136,10 @@ void print_device_descriptor(uint8_t daddr, tuh_xfer_t* xfer) printf(" idProduct 0x%04x\r\n" , desc_device.idProduct); printf(" bcdDevice %04x\r\n" , desc_device.bcdDevice); - uint32_t timeout_ms = 10; uint16_t temp_buf[128]; printf(" iManufacturer %u " , desc_device.iManufacturer); - if (XFER_RESULT_SUCCESS == tuh_descriptor_get_manufacturer_string_sync(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf), timeout_ms) ) + if (XFER_RESULT_SUCCESS == tuh_descriptor_get_manufacturer_string_sync(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf)) ) { utf16_to_utf8(temp_buf, TU_ARRAY_SIZE(temp_buf)); printf((const char*) temp_buf); @@ -148,7 +147,7 @@ void print_device_descriptor(uint8_t daddr, tuh_xfer_t* xfer) printf("\r\n"); printf(" iProduct %u " , desc_device.iProduct); - if (XFER_RESULT_SUCCESS == tuh_descriptor_get_product_string_sync(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf), timeout_ms)) + if (XFER_RESULT_SUCCESS == tuh_descriptor_get_product_string_sync(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf))) { utf16_to_utf8(temp_buf, TU_ARRAY_SIZE(temp_buf)); printf((const char*) temp_buf); @@ -156,7 +155,7 @@ void print_device_descriptor(uint8_t daddr, tuh_xfer_t* xfer) printf("\r\n"); printf(" iSerialNumber %u " , desc_device.iSerialNumber); - if (XFER_RESULT_SUCCESS == tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf), timeout_ms)) + if (XFER_RESULT_SUCCESS == tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf))) { utf16_to_utf8(temp_buf, TU_ARRAY_SIZE(temp_buf)); printf((const char*) temp_buf); diff --git a/src/host/usbh.c b/src/host/usbh.c index a45ab8efa..c801707d9 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -487,52 +487,49 @@ bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, // Descriptor Sync //--------------------------------------------------------------------+ -#define _CONTROL_SYNC_API(_async_func, _timeout, ...) \ - (void) _timeout; \ +#define _CONTROL_SYNC_API(_async_func, ...) \ xfer_result_t result = XFER_RESULT_INVALID;\ - /* TODO use timeout to wait */ \ TU_VERIFY(_async_func(__VA_ARGS__, NULL, (uintptr_t) &result), XFER_RESULT_TIMEOUT); \ return (uint8_t) result -uint8_t tuh_descriptor_get_sync(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len, uint8_t timeout_ms) +uint8_t tuh_descriptor_get_sync(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len) { - _CONTROL_SYNC_API(tuh_descriptor_get, timeout_ms, daddr, type, index, buffer, len); + _CONTROL_SYNC_API(tuh_descriptor_get, daddr, type, index, buffer, len); } -uint8_t tuh_descriptor_get_device_sync(uint8_t daddr, void* buffer, uint16_t len, uint8_t timeout_ms) +uint8_t tuh_descriptor_get_device_sync(uint8_t daddr, void* buffer, uint16_t len) { - len = tu_min16(len, sizeof(tusb_desc_device_t)); - return tuh_descriptor_get_sync(daddr, TUSB_DESC_DEVICE, 0, buffer, len, timeout_ms); + _CONTROL_SYNC_API(tuh_descriptor_get_device, daddr, buffer, len); } -uint8_t tuh_descriptor_get_configuration_sync(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, uint8_t timeout_ms) +uint8_t tuh_descriptor_get_configuration_sync(uint8_t daddr, uint8_t index, void* buffer, uint16_t len) { - return tuh_descriptor_get_sync(daddr, TUSB_DESC_CONFIGURATION, index, buffer, len, timeout_ms); + _CONTROL_SYNC_API(tuh_descriptor_get_configuration, daddr, index, buffer, len); } -uint8_t tuh_descriptor_get_hid_report_sync(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, void* buffer, uint16_t len, uint8_t timeout_ms) +uint8_t tuh_descriptor_get_hid_report_sync(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, void* buffer, uint16_t len) { - _CONTROL_SYNC_API(tuh_descriptor_get_hid_report, timeout_ms, daddr, itf_num, desc_type, index, buffer, len); + _CONTROL_SYNC_API(tuh_descriptor_get_hid_report, daddr, itf_num, desc_type, index, buffer, len); } -uint8_t tuh_descriptor_get_string_sync(uint8_t daddr, uint8_t index, uint16_t language_id, void* buffer, uint16_t len, uint8_t timeout_ms) +uint8_t tuh_descriptor_get_string_sync(uint8_t daddr, uint8_t index, uint16_t language_id, void* buffer, uint16_t len) { - _CONTROL_SYNC_API(tuh_descriptor_get_string, timeout_ms, daddr, index, language_id, buffer, len); + _CONTROL_SYNC_API(tuh_descriptor_get_string, daddr, index, language_id, buffer, len); } -uint8_t tuh_descriptor_get_manufacturer_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, uint8_t timeout_ms) +uint8_t tuh_descriptor_get_manufacturer_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len) { - _CONTROL_SYNC_API(tuh_descriptor_get_manufacturer_string, timeout_ms, daddr, language_id, buffer, len); + _CONTROL_SYNC_API(tuh_descriptor_get_manufacturer_string, daddr, language_id, buffer, len); } -uint8_t tuh_descriptor_get_product_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, uint8_t timeout_ms) +uint8_t tuh_descriptor_get_product_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len) { - _CONTROL_SYNC_API(tuh_descriptor_get_product_string, timeout_ms, daddr, language_id, buffer, len); + _CONTROL_SYNC_API(tuh_descriptor_get_product_string, daddr, language_id, buffer, len); } -uint8_t tuh_descriptor_get_serial_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, uint8_t timeout_ms) +uint8_t tuh_descriptor_get_serial_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len) { - _CONTROL_SYNC_API(tuh_descriptor_get_serial_string, timeout_ms, daddr, language_id, buffer, len); + _CONTROL_SYNC_API(tuh_descriptor_get_serial_string, daddr, language_id, buffer, len); } //--------------------------------------------------------------------+ @@ -919,19 +916,7 @@ static void _control_blocking_complete_cb(uint8_t daddr, tuh_xfer_t* xfer) *((xfer_result_t*) xfer->user_data) = xfer->result; } -bool tuh_control_xfer_sync(uint8_t daddr, tuh_xfer_t* xfer, uint32_t timeout_ms) -{ - (void) timeout_ms; - - // clear callback for sync - xfer->complete_cb = NULL; - - // TODO use timeout to wait - TU_VERIFY(tuh_control_xfer(daddr, xfer)); - - return true; -} - +// TODO timeout_ms is not supported yet bool tuh_control_xfer (uint8_t daddr, tuh_xfer_t* xfer) { // pre-check to help reducing mutex lock diff --git a/src/host/usbh.h b/src/host/usbh.h index 30868d2f2..21ef86d5d 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -46,16 +46,23 @@ typedef void (*tuh_xfer_cb_t)(uint8_t daddr, tuh_xfer_t* xfer); struct tuh_xfer_s { + uint8_t daddr; uint8_t ep_addr; - tusb_control_request_t const* setup; // pointer to setup packet if control transfer - uint32_t buflen; + + xfer_result_t result; + uint32_t actual_len; // excluding setup packet + + union + { + tusb_control_request_t const* setup; // setup packet if control transfer + uint32_t buflen; // length if not control transfer + }; + uint8_t* buffer; tuh_xfer_cb_t complete_cb; uintptr_t user_data; - // will be updated when transfer is complete - xfer_result_t result; - uint32_t actual_len; // excluding setup packet + uint32_t timeout_ms; }; //--------------------------------------------------------------------+ @@ -116,14 +123,13 @@ static inline bool tuh_ready(uint8_t daddr) // Submit a control transfer // true on success, false if there is on-going control transfer or incorrect parameters -// Note: blocking if complete callback is NULL. In this case 'xfer->result' will be updated -// and if 'user_data' point to a xfer_result_t variable, it will be updated as well. +// Note: blocking if complete callback is NULL. +// xfer contents will be updated to reflect the result bool tuh_control_xfer(uint8_t daddr, tuh_xfer_t* xfer); // Submit a bulk/interrupt transfer // true on success, false if there is on-going control transfer or incorrect parameters -// Note: blocking if complete callback is NULL. In this case 'xfer->result' will be updated -// and if 'user_data' point to a xfer_result_t variable, it will be updated as well. +// Note: blocking if complete callback is NULL. bool tuh_edpt_xfer(uint8_t daddr, tuh_xfer_t* xfer); // Set Configuration (control transfer) @@ -132,14 +138,6 @@ bool tuh_edpt_xfer(uint8_t daddr, tuh_xfer_t* xfer); bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, tuh_xfer_cb_t complete_cb, uintptr_t user_data); -//--------------------------------------------------------------------+ -// Endpoint Synchronous (blocking) -//--------------------------------------------------------------------+ - -// Sync (blocking) version of tuh_control_xfer() -// xfer contents will be updated to reflect the transfer -bool tuh_control_xfer_sync(uint8_t daddr, tuh_xfer_t * xfer, uint32_t timeout_ms); - //--------------------------------------------------------------------+ // Descriptors Asynchronous (non-blocking) //--------------------------------------------------------------------+ @@ -191,35 +189,35 @@ bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void* // Sync (blocking) version of tuh_descriptor_get() // return transfer result -uint8_t tuh_descriptor_get_sync(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len, uint8_t timeout_ms); +uint8_t tuh_descriptor_get_sync(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len); // Sync (blocking) version of tuh_descriptor_get_device() // return transfer result -uint8_t tuh_descriptor_get_device_sync(uint8_t daddr, void* buffer, uint16_t len, uint8_t timeout_ms); +uint8_t tuh_descriptor_get_device_sync(uint8_t daddr, void* buffer, uint16_t len); // Sync (blocking) version of tuh_descriptor_get_configuration() // return transfer result -uint8_t tuh_descriptor_get_configuration_sync(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, uint8_t timeout_ms); +uint8_t tuh_descriptor_get_configuration_sync(uint8_t daddr, uint8_t index, void* buffer, uint16_t len); // Sync (blocking) version of tuh_descriptor_get_hid_report() // return transfer result -uint8_t tuh_descriptor_get_hid_report_sync(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, void* buffer, uint16_t len, uint8_t timeout_ms); +uint8_t tuh_descriptor_get_hid_report_sync(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, void* buffer, uint16_t len); // Sync (blocking) version of tuh_descriptor_get_string() // return transfer result -uint8_t tuh_descriptor_get_string_sync(uint8_t daddr, uint8_t index, uint16_t language_id, void* buffer, uint16_t len, uint8_t timeout_ms); +uint8_t tuh_descriptor_get_string_sync(uint8_t daddr, uint8_t index, uint16_t language_id, void* buffer, uint16_t len); // Sync (blocking) version of tuh_descriptor_get_manufacturer_string() // return transfer result -uint8_t tuh_descriptor_get_manufacturer_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, uint8_t timeout_ms); +uint8_t tuh_descriptor_get_manufacturer_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len); // Sync (blocking) version of tuh_descriptor_get_product_string() // return transfer result -uint8_t tuh_descriptor_get_product_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, uint8_t timeout_ms); +uint8_t tuh_descriptor_get_product_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len); // Sync (blocking) version of tuh_descriptor_get_serial_string() // return transfer result -uint8_t tuh_descriptor_get_serial_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, uint8_t timeout_ms); +uint8_t tuh_descriptor_get_serial_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len); #ifdef __cplusplus } From 8750e3b57756e4377bb737c578e2742b653c314c Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 18 Mar 2022 16:39:35 +0700 Subject: [PATCH 259/504] move daddr into xfer struct --- examples/host/bare_api/src/main.c | 4 +- src/class/cdc/cdc_host.c | 3 +- src/class/hid/hid_host.c | 53 +++++++++++++---------- src/class/msc/msc_host.c | 12 +++--- src/host/hub.c | 70 +++++++++++++++++------------- src/host/usbh.c | 71 ++++++++++++++++++------------- src/host/usbh.h | 18 ++++---- 7 files changed, 132 insertions(+), 99 deletions(-) diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index b472c40c4..e2e0f4ff3 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -115,7 +115,7 @@ static void utf16_to_utf8(uint16_t *temp_buf, size_t buf_len) { ((uint8_t*) temp_buf)[utf8_len] = '\0'; } -void print_device_descriptor(uint8_t daddr, tuh_xfer_t* xfer) +void print_device_descriptor(tuh_xfer_t* xfer) { if ( XFER_RESULT_SUCCESS != xfer->result ) { @@ -123,6 +123,8 @@ void print_device_descriptor(uint8_t daddr, tuh_xfer_t* xfer) return; } + uint8_t const daddr = xfer->daddr; + printf("Device %u: ID %04x:%04x\r\n", daddr, desc_device.idVendor, desc_device.idProduct); printf("Device Descriptor:\r\n"); printf(" bLength %u\r\n" , desc_device.bLength); diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 2795750ed..f946974e8 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -140,6 +140,7 @@ bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_xf tuh_xfer_t xfer = { + .daddr = dev_addr, .ep_addr = 0, .setup = &request, .buffer = NULL, @@ -147,7 +148,7 @@ bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_xf .user_data = 0 }; - return tuh_control_xfer(dev_addr, &xfer); + return tuh_control_xfer(&xfer); } //--------------------------------------------------------------------+ diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 0ad917815..fa99b37fe 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -103,11 +103,12 @@ uint8_t tuh_hid_get_protocol(uint8_t dev_addr, uint8_t instance) return hid_itf->protocol_mode; } -static void set_protocol_complete(uint8_t dev_addr, tuh_xfer_t* xfer) +static void set_protocol_complete(tuh_xfer_t* xfer) { uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); - uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); - hidh_interface_t* hid_itf = get_instance(dev_addr, instance); + uint8_t const daddr = xfer->daddr; + uint8_t const instance = get_instance_id_by_itfnum(daddr, itf_num); + hidh_interface_t* hid_itf = get_instance(daddr, instance); if (XFER_RESULT_SUCCESS == xfer->result) { @@ -116,7 +117,7 @@ static void set_protocol_complete(uint8_t dev_addr, tuh_xfer_t* xfer) if (tuh_hid_set_protocol_complete_cb) { - tuh_hid_set_protocol_complete_cb(dev_addr, instance, hid_itf->protocol_mode); + tuh_hid_set_protocol_complete_cb(daddr, instance, hid_itf->protocol_mode); } } @@ -141,6 +142,7 @@ static bool _hidh_set_protocol(uint8_t dev_addr, uint8_t itf_num, uint8_t protoc tuh_xfer_t xfer = { + .daddr = dev_addr, .ep_addr = 0, .setup = &request, .buffer = NULL, @@ -148,7 +150,7 @@ static bool _hidh_set_protocol(uint8_t dev_addr, uint8_t itf_num, uint8_t protoc .user_data = user_data }; - TU_ASSERT( tuh_control_xfer(dev_addr, &xfer) ); + TU_ASSERT( tuh_control_xfer(&xfer) ); return true; } @@ -160,19 +162,19 @@ bool tuh_hid_set_protocol(uint8_t dev_addr, uint8_t instance, uint8_t protocol) return _hidh_set_protocol(dev_addr, hid_itf->itf_num, protocol, set_protocol_complete, 0); } -static void set_report_complete(uint8_t dev_addr, tuh_xfer_t* xfer) +static void set_report_complete(tuh_xfer_t* xfer) { TU_LOG2("HID Set Report complete\r\n"); if (tuh_hid_set_report_complete_cb) { uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); - uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); + uint8_t const instance = get_instance_id_by_itfnum(xfer->daddr, itf_num); uint8_t const report_type = tu_u16_high(xfer->setup->wValue); uint8_t const report_id = tu_u16_low(xfer->setup->wValue); - tuh_hid_set_report_complete_cb(dev_addr, instance, report_id, report_type, + tuh_hid_set_report_complete_cb(xfer->daddr, instance, report_id, report_type, (xfer->result == XFER_RESULT_SUCCESS) ? xfer->setup->wLength : 0); } } @@ -198,6 +200,7 @@ bool tuh_hid_set_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, u tuh_xfer_t xfer = { + .daddr = dev_addr, .ep_addr = 0, .setup = &request, .buffer = report, @@ -205,7 +208,7 @@ bool tuh_hid_set_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, u .user_data = 0 }; - TU_ASSERT( tuh_control_xfer(dev_addr, &xfer) ); + TU_ASSERT( tuh_control_xfer(&xfer) ); return true; } @@ -229,6 +232,7 @@ static bool _hidh_set_idle(uint8_t dev_addr, uint8_t itf_num, uint16_t idle_rate tuh_xfer_t xfer = { + .daddr = dev_addr, .ep_addr = 0, .setup = &request, .buffer = NULL, @@ -236,7 +240,7 @@ static bool _hidh_set_idle(uint8_t dev_addr, uint8_t itf_num, uint16_t idle_rate .user_data = user_data }; - TU_ASSERT( tuh_control_xfer(dev_addr, &xfer) ); + TU_ASSERT( tuh_control_xfer(&xfer) ); return true; } @@ -389,7 +393,7 @@ enum { }; static void config_driver_mount_complete(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len); -static void process_set_config(uint8_t dev_addr, tuh_xfer_t* xfer); +static void process_set_config(tuh_xfer_t* xfer); bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num) { @@ -397,17 +401,18 @@ bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num) request.wIndex = tu_htole16((uint16_t) itf_num); tuh_xfer_t xfer; + xfer.daddr = dev_addr; xfer.result = XFER_RESULT_SUCCESS; xfer.setup = &request; xfer.user_data = CONFG_SET_IDLE; // fake request to kick-off the set config process - process_set_config(dev_addr, &xfer); + process_set_config(&xfer); return true; } -static void process_set_config(uint8_t dev_addr, tuh_xfer_t* xfer) +static void process_set_config(tuh_xfer_t* xfer) { // Stall is a valid response for SET_IDLE, therefore we could ignore its result if ( xfer->setup->bRequest != HID_REQ_CONTROL_SET_IDLE ) @@ -415,10 +420,12 @@ static void process_set_config(uint8_t dev_addr, tuh_xfer_t* xfer) TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, ); } - uintptr_t const state = xfer->user_data; - uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); - uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); - hidh_interface_t* hid_itf = get_instance(dev_addr, instance); + uintptr_t const state = xfer->user_data; + uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); + uint8_t const daddr = xfer->daddr; + + uint8_t const instance = get_instance_id_by_itfnum(daddr, itf_num); + hidh_interface_t* hid_itf = get_instance(daddr, instance); switch(state) { @@ -427,12 +434,12 @@ static void process_set_config(uint8_t dev_addr, tuh_xfer_t* xfer) // Idle rate = 0 mean only report when there is changes const uint16_t idle_rate = 0; const uintptr_t next_state = (hid_itf->itf_protocol != HID_ITF_PROTOCOL_NONE) ? CONFIG_SET_PROTOCOL : CONFIG_GET_REPORT_DESC; - _hidh_set_idle(dev_addr, itf_num, idle_rate, process_set_config, next_state); + _hidh_set_idle(daddr, itf_num, idle_rate, process_set_config, next_state); } break; case CONFIG_SET_PROTOCOL: - _hidh_set_protocol(dev_addr, hid_itf->itf_num, HID_PROTOCOL_BOOT, process_set_config, CONFIG_GET_REPORT_DESC); + _hidh_set_protocol(daddr, hid_itf->itf_num, HID_PROTOCOL_BOOT, process_set_config, CONFIG_GET_REPORT_DESC); break; case CONFIG_GET_REPORT_DESC: @@ -443,19 +450,19 @@ static void process_set_config(uint8_t dev_addr, tuh_xfer_t* xfer) TU_LOG2("HID Skip Report Descriptor since it is too large %u bytes\r\n", hid_itf->report_desc_len); // Driver is mounted without report descriptor - config_driver_mount_complete(dev_addr, instance, NULL, 0); + config_driver_mount_complete(daddr, instance, NULL, 0); }else { - tuh_descriptor_get_hid_report(dev_addr, itf_num, hid_itf->report_desc_type, 0, usbh_get_enum_buf(), hid_itf->report_desc_len, process_set_config, CONFIG_COMPLETE); + tuh_descriptor_get_hid_report(daddr, itf_num, hid_itf->report_desc_type, 0, usbh_get_enum_buf(), hid_itf->report_desc_len, process_set_config, CONFIG_COMPLETE); } break; case CONFIG_COMPLETE: { uint8_t const* desc_report = usbh_get_enum_buf(); - uint16_t const desc_len = xfer->setup->wLength; + uint16_t const desc_len = tu_le16toh(xfer->setup->wLength); - config_driver_mount_complete(dev_addr, instance, desc_report, desc_len); + config_driver_mount_complete(daddr, instance, desc_report, desc_len); } break; diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index 5a34f2d56..06af781f5 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -358,7 +358,7 @@ bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32 // MSC Enumeration //--------------------------------------------------------------------+ -static void config_get_maxlun_complete (uint8_t dev_addr, tuh_xfer_t* xfer); +static void config_get_maxlun_complete (tuh_xfer_t* xfer); static bool config_test_unit_ready_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); static bool config_request_sense_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); static bool config_read_capacity_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); @@ -421,20 +421,22 @@ bool msch_set_config(uint8_t dev_addr, uint8_t itf_num) tuh_xfer_t xfer = { + .daddr = dev_addr, .ep_addr = 0, .setup = &request, .buffer = &p_msc->max_lun, .complete_cb = config_get_maxlun_complete, .user_data = 0 }; - TU_ASSERT(tuh_control_xfer(dev_addr, &xfer)); + TU_ASSERT(tuh_control_xfer(&xfer)); return true; } -static void config_get_maxlun_complete (uint8_t dev_addr, tuh_xfer_t* xfer) +static void config_get_maxlun_complete (tuh_xfer_t* xfer) { - msch_interface_t* p_msc = get_itf(dev_addr); + uint8_t const daddr = xfer->daddr; + msch_interface_t* p_msc = get_itf(daddr); // STALL means zero p_msc->max_lun = (XFER_RESULT_SUCCESS == xfer->result) ? _msch_buffer[0] : 0; @@ -443,7 +445,7 @@ static void config_get_maxlun_complete (uint8_t dev_addr, tuh_xfer_t* xfer) // TODO multiple LUN support TU_LOG2("SCSI Test Unit Ready\r\n"); uint8_t const lun = 0; - tuh_msc_test_unit_ready(dev_addr, lun, config_test_unit_ready_complete); + tuh_msc_test_unit_ready(daddr, lun, config_test_unit_ready_complete); } static bool config_test_unit_ready_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw) diff --git a/src/host/hub.c b/src/host/hub.c index ac24988d8..da4f6fe3a 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -96,6 +96,7 @@ bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_xfer_t xfer = { + .daddr = hub_addr, .ep_addr = 0, .setup = &request, .buffer = NULL, @@ -104,7 +105,7 @@ bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, }; TU_LOG2("HUB Clear Feature: %s, addr = %u port = %u\r\n", _hub_feature_str[feature], hub_addr, hub_port); - TU_ASSERT( tuh_control_xfer(hub_addr, &xfer) ); + TU_ASSERT( tuh_control_xfer(&xfer) ); return true; } @@ -127,6 +128,7 @@ bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_xfer_t xfer = { + .daddr = hub_addr, .ep_addr = 0, .setup = &request, .buffer = NULL, @@ -135,7 +137,7 @@ bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, }; TU_LOG2("HUB Set Feature: %s, addr = %u port = %u\r\n", _hub_feature_str[feature], hub_addr, hub_port); - TU_ASSERT( tuh_control_xfer(hub_addr, &xfer) ); + TU_ASSERT( tuh_control_xfer(&xfer) ); return true; } @@ -158,6 +160,7 @@ bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, tuh_xfer_t xfer = { + .daddr = hub_addr, .ep_addr = 0, .setup = &request, .buffer = resp, @@ -166,7 +169,7 @@ bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, }; TU_LOG2("HUB Get Port Status: addr = %u port = %u\r\n", hub_addr, hub_port); - TU_ASSERT( tuh_control_xfer( hub_addr, &xfer) ); + TU_ASSERT( tuh_control_xfer(&xfer) ); return true; } @@ -225,8 +228,8 @@ bool hub_edpt_status_xfer(uint8_t dev_addr) // Set Configure //--------------------------------------------------------------------+ -static void config_set_port_power (uint8_t dev_addr, tuh_xfer_t* xfer); -static void config_port_power_complete (uint8_t dev_addr, tuh_xfer_t* xfer); +static void config_set_port_power (tuh_xfer_t* xfer); +static void config_port_power_complete (tuh_xfer_t* xfer); bool hub_set_config(uint8_t dev_addr, uint8_t itf_num) { @@ -250,6 +253,7 @@ bool hub_set_config(uint8_t dev_addr, uint8_t itf_num) tuh_xfer_t xfer = { + .daddr = dev_addr, .ep_addr = 0, .setup = &request, .buffer = _hub_buffer, @@ -257,16 +261,17 @@ bool hub_set_config(uint8_t dev_addr, uint8_t itf_num) .user_data = 0 }; - TU_ASSERT( tuh_control_xfer(dev_addr, &xfer) ); + TU_ASSERT( tuh_control_xfer(&xfer) ); return true; } -static void config_set_port_power (uint8_t dev_addr, tuh_xfer_t* xfer) +static void config_set_port_power (tuh_xfer_t* xfer) { TU_ASSERT(XFER_RESULT_SUCCESS == xfer->result, ); - hub_interface_t* p_hub = get_itf(dev_addr); + uint8_t const daddr = xfer->daddr; + hub_interface_t* p_hub = get_itf(daddr); // only use number of ports in hub descriptor descriptor_hub_desc_t const* desc_hub = (descriptor_hub_desc_t const*) _hub_buffer; @@ -276,26 +281,28 @@ static void config_set_port_power (uint8_t dev_addr, tuh_xfer_t* xfer) // Set Port Power to be able to detect connection, starting with port 1 uint8_t const hub_port = 1; - hub_port_set_feature(dev_addr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete, 0); + hub_port_set_feature(daddr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete, 0); } -static void config_port_power_complete (uint8_t dev_addr, tuh_xfer_t* xfer) +static void config_port_power_complete (tuh_xfer_t* xfer) { TU_ASSERT(XFER_RESULT_SUCCESS == xfer->result, ); - hub_interface_t* p_hub = get_itf(dev_addr); + + uint8_t const daddr = xfer->daddr; + hub_interface_t* p_hub = get_itf(daddr); if (xfer->setup->wIndex == p_hub->port_count) { // All ports are power -> queue notification status endpoint and // complete the SET CONFIGURATION - TU_ASSERT( usbh_edpt_xfer(dev_addr, p_hub->ep_in, &p_hub->status_change, 1), ); + TU_ASSERT( usbh_edpt_xfer(daddr, p_hub->ep_in, &p_hub->status_change, 1), ); - usbh_driver_set_config_complete(dev_addr, p_hub->itf_num); + usbh_driver_set_config_complete(daddr, p_hub->itf_num); }else { // power next port uint8_t const hub_port = (uint8_t) (xfer->setup->wIndex + 1); - hub_port_set_feature(dev_addr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete, 0); + hub_port_set_feature(daddr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete, 0); } } @@ -303,9 +310,9 @@ static void config_port_power_complete (uint8_t dev_addr, tuh_xfer_t* xfer) // Connection Changes //--------------------------------------------------------------------+ -static void connection_get_status_complete (uint8_t dev_addr, tuh_xfer_t* xfer); -static void connection_clear_conn_change_complete (uint8_t dev_addr, tuh_xfer_t* xfer); -static void connection_port_reset_complete (uint8_t dev_addr, tuh_xfer_t* xfer); +static void connection_get_status_complete (tuh_xfer_t* xfer); +static void connection_clear_conn_change_complete (tuh_xfer_t* xfer); +static void connection_port_reset_complete (tuh_xfer_t* xfer); // callback as response of interrupt endpoint polling bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) @@ -333,11 +340,12 @@ bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32 return true; } -static void connection_get_status_complete (uint8_t dev_addr, tuh_xfer_t* xfer) +static void connection_get_status_complete (tuh_xfer_t* xfer) { TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, ); - hub_interface_t* p_hub = get_itf(dev_addr); + uint8_t const daddr = xfer->daddr; + hub_interface_t* p_hub = get_itf(daddr); uint8_t const port_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); // Connection change @@ -347,7 +355,7 @@ static void connection_get_status_complete (uint8_t dev_addr, tuh_xfer_t* xfer) //TU_VERIFY(port_status.status_current.port_power && port_status.status_current.port_enable, ); // Acknowledge Port Connection Change - hub_port_clear_feature(dev_addr, port_num, HUB_FEATURE_PORT_CONNECTION_CHANGE, connection_clear_conn_change_complete, 0); + hub_port_clear_feature(daddr, port_num, HUB_FEATURE_PORT_CONNECTION_CHANGE, connection_clear_conn_change_complete, 0); }else { // Other changes are: Enable, Suspend, Over Current, Reset, L1 state @@ -355,31 +363,32 @@ static void connection_get_status_complete (uint8_t dev_addr, tuh_xfer_t* xfer) // prepare for next hub status // TODO continue with status_change, or maybe we can do it again with status - hub_edpt_status_xfer(dev_addr); + hub_edpt_status_xfer(daddr); } } -static void connection_clear_conn_change_complete (uint8_t dev_addr, tuh_xfer_t* xfer) +static void connection_clear_conn_change_complete (tuh_xfer_t* xfer) { TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, ); - hub_interface_t* p_hub = get_itf(dev_addr); + uint8_t const daddr = xfer->daddr; + hub_interface_t* p_hub = get_itf(daddr); uint8_t const port_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); if ( p_hub->port_status.status.connection ) { // Reset port if attach event - hub_port_reset(dev_addr, port_num, connection_port_reset_complete, 0); + hub_port_reset(daddr, port_num, connection_port_reset_complete, 0); }else { // submit detach event hcd_event_t event = { - .rhport = usbh_get_rhport(dev_addr), + .rhport = usbh_get_rhport(daddr), .event_id = HCD_EVENT_DEVICE_REMOVE, .connection = { - .hub_addr = dev_addr, + .hub_addr = daddr, .hub_port = port_num } }; @@ -388,21 +397,22 @@ static void connection_clear_conn_change_complete (uint8_t dev_addr, tuh_xfer_t* } } -static void connection_port_reset_complete (uint8_t dev_addr, tuh_xfer_t* xfer) +static void connection_port_reset_complete (tuh_xfer_t* xfer) { TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, ); - // hub_interface_t* p_hub = get_itf(dev_addr); + uint8_t const daddr = xfer->daddr; + // hub_interface_t* p_hub = get_itf(daddr); uint8_t const port_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); // submit attach event hcd_event_t event = { - .rhport = usbh_get_rhport(dev_addr), + .rhport = usbh_get_rhport(daddr), .event_id = HCD_EVENT_DEVICE_ATTACH, .connection = { - .hub_addr = dev_addr, + .hub_addr = daddr, .hub_port = port_num } }; diff --git a/src/host/usbh.c b/src/host/usbh.c index c801707d9..36774d3dc 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -340,6 +340,7 @@ static bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t tuh_xfer_t xfer = { + .daddr = daddr, .ep_addr = 0, .setup = &request, .buffer = buffer, @@ -347,7 +348,7 @@ static bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t .user_data = user_data }; - bool const ret = tuh_control_xfer(daddr, &xfer); + bool const ret = tuh_control_xfer(&xfer); // if blocking, user_data could be pointed to xfer_result if ( !complete_cb && user_data ) @@ -434,6 +435,7 @@ bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_ tuh_xfer_t xfer = { + .daddr = daddr, .ep_addr = 0, .setup = &request, .buffer = buffer, @@ -441,7 +443,7 @@ bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_ .user_data = user_data }; - bool const ret = tuh_control_xfer(daddr, &xfer); + bool const ret = tuh_control_xfer(&xfer); // if blocking, user_data could be pointed to xfer_result if ( !complete_cb && user_data ) @@ -473,6 +475,7 @@ bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, tuh_xfer_t xfer = { + .daddr = daddr, .ep_addr = 0, .setup = &request, .buffer = NULL, @@ -480,7 +483,7 @@ bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, .user_data = user_data }; - return tuh_control_xfer(daddr, &xfer); + return tuh_control_xfer(&xfer); } //--------------------------------------------------------------------+ @@ -909,24 +912,38 @@ bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) // Control transfer //--------------------------------------------------------------------+ -static void _control_blocking_complete_cb(uint8_t daddr, tuh_xfer_t* xfer) +static void _control_blocking_complete_cb(tuh_xfer_t* xfer) { - (void) daddr; // update result *((xfer_result_t*) xfer->user_data) = xfer->result; } // TODO timeout_ms is not supported yet -bool tuh_control_xfer (uint8_t daddr, tuh_xfer_t* xfer) +bool tuh_control_xfer (tuh_xfer_t* xfer) { + // EP0 with setup packet + TU_VERIFY(xfer->ep_addr == 0 && xfer->setup); + // pre-check to help reducing mutex lock TU_VERIFY(_ctrl_xfer.stage == CONTROL_STAGE_IDLE); + uint8_t const daddr = xfer->daddr; + // TODO probably better to use semaphore as resource management than mutex usbh_lock(); bool const is_idle = (_ctrl_xfer.stage == CONTROL_STAGE_IDLE); - if (is_idle) _ctrl_xfer.stage = CONTROL_STAGE_SETUP; + if (is_idle) + { + _ctrl_xfer.stage = CONTROL_STAGE_SETUP; + _ctrl_xfer.daddr = daddr; + _ctrl_xfer.actual_len = 0; + + _ctrl_xfer.request = (*xfer->setup); + _ctrl_xfer.buffer = xfer->buffer; + _ctrl_xfer.complete_cb = xfer->complete_cb; + _ctrl_xfer.user_data = xfer->user_data; + } usbh_unlock(); @@ -937,13 +954,6 @@ bool tuh_control_xfer (uint8_t daddr, tuh_xfer_t* xfer) TU_LOG2_VAR(&xfer->setup); TU_LOG2("\r\n"); - _ctrl_xfer.actual_len = 0; - _ctrl_xfer.daddr = daddr; - _ctrl_xfer.request = (*xfer->setup); - _ctrl_xfer.buffer = xfer->buffer; - _ctrl_xfer.complete_cb = xfer->complete_cb; - _ctrl_xfer.user_data = xfer->user_data; - if (xfer->complete_cb) { TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t*) &_ctrl_xfer.request) ); @@ -984,7 +994,7 @@ TU_ATTR_ALWAYS_INLINE static inline void _set_control_xfer_stage(uint8_t stage) usbh_unlock(); } -static void _xfer_complete(uint8_t dev_addr, xfer_result_t result) +static void _xfer_complete(uint8_t daddr, xfer_result_t result) { TU_LOG2("\r\n"); @@ -992,6 +1002,7 @@ static void _xfer_complete(uint8_t dev_addr, xfer_result_t result) tusb_control_request_t const request = _ctrl_xfer.request; tuh_xfer_t xfer_temp = { + .daddr = daddr, .ep_addr = 0, .result = result, .setup = &request, @@ -1007,7 +1018,7 @@ static void _xfer_complete(uint8_t dev_addr, xfer_result_t result) if (xfer_temp.complete_cb) { - xfer_temp.complete_cb(dev_addr, &xfer_temp); + xfer_temp.complete_cb(&xfer_temp); } } @@ -1066,9 +1077,8 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result // //--------------------------------------------------------------------+ -bool tuh_edpt_xfer(uint8_t daddr, tuh_xfer_t* xfer) +bool tuh_edpt_xfer(tuh_xfer_t* xfer) { - (void) daddr; (void) xfer; return true; } @@ -1144,7 +1154,7 @@ static bool parse_configuration_descriptor (uint8_t dev_addr, tusb_desc_configur static void enum_full_complete(void); // process device enumeration -static void process_enumeration(uint8_t dev_addr, tuh_xfer_t* xfer) +static void process_enumeration(tuh_xfer_t* xfer) { if (XFER_RESULT_SUCCESS != xfer->result) { @@ -1153,7 +1163,9 @@ static void process_enumeration(uint8_t dev_addr, tuh_xfer_t* xfer) return; } + uint8_t const daddr = xfer->daddr; uintptr_t const state = xfer->user_data; + switch(state) { #if CFG_TUH_HUB @@ -1261,7 +1273,7 @@ static void process_enumeration(uint8_t dev_addr, tuh_xfer_t* xfer) case ENUM_GET_9BYTE_CONFIG_DESC: { tusb_desc_device_t const * desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; - usbh_device_t* dev = get_device(dev_addr); + usbh_device_t* dev = get_device(daddr); TU_ASSERT(dev, ); dev->vid = desc_device->idVendor; @@ -1275,7 +1287,7 @@ static void process_enumeration(uint8_t dev_addr, tuh_xfer_t* xfer) // Get 9-byte for total length uint8_t const config_idx = CONFIG_NUM - 1; TU_LOG2("Get Configuration[0] Descriptor (9 bytes)\r\n"); - TU_ASSERT( tuh_descriptor_get_configuration(dev_addr, config_idx, _usbh_ctrl_buf, 9, process_enumeration, ENUM_GET_FULL_CONFIG_DESC), ); + TU_ASSERT( tuh_descriptor_get_configuration(daddr, config_idx, _usbh_ctrl_buf, 9, process_enumeration, ENUM_GET_FULL_CONFIG_DESC), ); } break; @@ -1292,22 +1304,22 @@ static void process_enumeration(uint8_t dev_addr, tuh_xfer_t* xfer) // Get full configuration descriptor uint8_t const config_idx = CONFIG_NUM - 1; TU_LOG2("Get Configuration[0] Descriptor\r\n"); - TU_ASSERT( tuh_descriptor_get_configuration(dev_addr, config_idx, _usbh_ctrl_buf, total_len, process_enumeration, ENUM_SET_CONFIG), ); + TU_ASSERT( tuh_descriptor_get_configuration(daddr, config_idx, _usbh_ctrl_buf, total_len, process_enumeration, ENUM_SET_CONFIG), ); } break; case ENUM_SET_CONFIG: // Parse configuration & set up drivers // Driver open aren't allowed to make any usb transfer yet - TU_ASSERT( parse_configuration_descriptor(dev_addr, (tusb_desc_configuration_t*) _usbh_ctrl_buf), ); + TU_ASSERT( parse_configuration_descriptor(daddr, (tusb_desc_configuration_t*) _usbh_ctrl_buf), ); - TU_ASSERT( tuh_configuration_set(dev_addr, CONFIG_NUM, process_enumeration, ENUM_CONFIG_DRIVER), ); + TU_ASSERT( tuh_configuration_set(daddr, CONFIG_NUM, process_enumeration, ENUM_CONFIG_DRIVER), ); break; case ENUM_CONFIG_DRIVER: { TU_LOG2("Device configured\r\n"); - usbh_device_t* dev = get_device(dev_addr); + usbh_device_t* dev = get_device(daddr); TU_ASSERT(dev, ); dev->configured = 1; @@ -1316,7 +1328,7 @@ static void process_enumeration(uint8_t dev_addr, tuh_xfer_t* xfer) // Since driver can perform control transfer within its set_config, this is done asynchronously. // The process continue with next interface when class driver complete its sequence with usbh_driver_set_config_complete() // TODO use separated API instead of using DRVID_INVALID - usbh_driver_set_config_complete(dev_addr, DRVID_INVALID); + usbh_driver_set_config_complete(daddr, DRVID_INVALID); } break; @@ -1347,10 +1359,11 @@ static bool enum_new_device(hcd_event_t* event) // 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(0, &xfer); + process_enumeration(&xfer); } #if CFG_TUH_HUB @@ -1431,6 +1444,7 @@ static bool enum_request_set_addr(void) tuh_xfer_t xfer = { + .daddr = 0, // dev0 .ep_addr = 0, .setup = &request, .buffer = NULL, @@ -1438,8 +1452,7 @@ static bool enum_request_set_addr(void) .user_data = ENUM_GET_DEVICE_DESC }; - uint8_t const addr0 = 0; - TU_ASSERT( tuh_control_xfer(addr0, &xfer) ); + TU_ASSERT( tuh_control_xfer(&xfer) ); return true; } diff --git a/src/host/usbh.h b/src/host/usbh.h index 21ef86d5d..f79c5cdc8 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -42,7 +42,7 @@ struct tuh_xfer_s; typedef struct tuh_xfer_s tuh_xfer_t; -typedef void (*tuh_xfer_cb_t)(uint8_t daddr, tuh_xfer_t* xfer); +typedef void (*tuh_xfer_cb_t)(tuh_xfer_t* xfer); struct tuh_xfer_s { @@ -54,7 +54,7 @@ struct tuh_xfer_s union { - tusb_control_request_t const* setup; // setup packet if control transfer + tusb_control_request_t const* setup; // setup packet pointer if control transfer uint32_t buflen; // length if not control transfer }; @@ -62,7 +62,7 @@ struct tuh_xfer_s tuh_xfer_cb_t complete_cb; uintptr_t user_data; - uint32_t timeout_ms; + uint32_t timeout_ms; // place holder, not supported yet }; //--------------------------------------------------------------------+ @@ -118,19 +118,17 @@ static inline bool tuh_ready(uint8_t daddr) } //--------------------------------------------------------------------+ -// Endpoint Asynchronous (non-blocking) +// Transfer API //--------------------------------------------------------------------+ // Submit a control transfer -// true on success, false if there is on-going control transfer or incorrect parameters -// Note: blocking if complete callback is NULL. -// xfer contents will be updated to reflect the result -bool tuh_control_xfer(uint8_t daddr, tuh_xfer_t* xfer); +// Note: blocking if complete callback is NULL, in this case xfer contents will be updated to reflect the result +bool tuh_control_xfer(tuh_xfer_t* xfer); // Submit a bulk/interrupt transfer -// true on success, false if there is on-going control transfer or incorrect parameters +// xfer memory must exist until transfer is complete. // Note: blocking if complete callback is NULL. -bool tuh_edpt_xfer(uint8_t daddr, tuh_xfer_t* xfer); +bool tuh_edpt_xfer(tuh_xfer_t* xfer); // Set Configuration (control transfer) // config_num = 0 will un-configure device. Note: config_num = config_descriptor_index + 1 From 9ae0304b1ecd8d10f96a39c5c88a43d6b7c43681 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 18 Mar 2022 18:04:25 +0700 Subject: [PATCH 260/504] move code around --- src/host/usbh.c | 1109 +++++++++++++++++++++++------------------------ 1 file changed, 553 insertions(+), 556 deletions(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index 36774d3dc..8aa9c4a16 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -110,14 +110,7 @@ typedef struct { tu_edpt_state_t ep_status[CFG_TUH_ENDPOINT_MAX][2]; #if CFG_TUH_API_EDPT_XFER -// struct -// { -// uint8_t* buffer; -// tuh_xfer_cb_t complete_cb; -// uintptr_t user_data; -// uint16_t buflen; -// volatile uint16_t actual_len; -// }ep_xfer[[]]; + // ep_xfer[]; #endif } usbh_device_t; @@ -315,6 +308,558 @@ void osal_task_delay(uint32_t msec) } #endif +//--------------------------------------------------------------------+ +// CLASS-USBD API (don't require to verify parameters) +//--------------------------------------------------------------------+ + +static void clear_device(usbh_device_t* dev) +{ + tu_memclr(dev, sizeof(usbh_device_t)); + memset(dev->itf2drv, DRVID_INVALID, sizeof(dev->itf2drv)); // invalid mapping + memset(dev->ep2drv , DRVID_INVALID, sizeof(dev->ep2drv )); // invalid mapping +} + +bool tuh_inited(void) +{ + return _usbh_initialized; +} + +bool tuh_init(uint8_t rhport) +{ + // skip if already initialized + if (_usbh_initialized) return _usbh_initialized; + + TU_LOG2("USBH init\r\n"); + TU_LOG2_INT(sizeof(usbh_device_t)); + TU_LOG2_INT(sizeof(hcd_event_t)); + TU_LOG2_INT(sizeof(_ctrl_xfer)); + TU_LOG2_INT(sizeof(tuh_xfer_t)); + + // Event queue + _usbh_q = osal_queue_create( &_usbh_qdef ); + TU_ASSERT(_usbh_q != NULL); + +#if TUSB_OPT_MUTEX + // Mutex + _usbh_mutex = osal_mutex_create(&_usbh_mutexdef); + TU_ASSERT(_usbh_mutex); +#endif + + // Device + tu_memclr(&_dev0, sizeof(_dev0)); + tu_memclr(_usbh_devices, sizeof(_usbh_devices)); + tu_memclr(&_ctrl_xfer, sizeof(_ctrl_xfer)); + + for(uint8_t i=0; iep_status[epnum][ep_dir].busy = 0; + dev->ep_status[epnum][ep_dir].claimed = 0; + + if ( 0 == epnum ) + { + usbh_control_xfer_cb(event.dev_addr, ep_addr, event.xfer_complete.result, event.xfer_complete.len); + }else + { + uint8_t drv_id = dev->ep2drv[epnum][ep_dir]; + TU_ASSERT(drv_id < USBH_CLASS_DRIVER_COUNT, ); + + TU_LOG2("%s xfer callback\r\n", usbh_class_drivers[drv_id].name); + usbh_class_drivers[drv_id].xfer_cb(event.dev_addr, ep_addr, event.xfer_complete.result, event.xfer_complete.len); + } + } + } + break; + + case USBH_EVENT_FUNC_CALL: + if ( event.func_call.func ) event.func_call.func(event.func_call.param); + break; + + default: break; + } + } +} + +//--------------------------------------------------------------------+ +// Control transfer +//--------------------------------------------------------------------+ + +static void _control_blocking_complete_cb(tuh_xfer_t* xfer) +{ + // update result + *((xfer_result_t*) xfer->user_data) = xfer->result; +} + +// TODO timeout_ms is not supported yet +bool tuh_control_xfer (tuh_xfer_t* xfer) +{ + // EP0 with setup packet + TU_VERIFY(xfer->ep_addr == 0 && xfer->setup); + + // pre-check to help reducing mutex lock + TU_VERIFY(_ctrl_xfer.stage == CONTROL_STAGE_IDLE); + + uint8_t const daddr = xfer->daddr; + + // TODO probably better to use semaphore as resource management than mutex + usbh_lock(); + + bool const is_idle = (_ctrl_xfer.stage == CONTROL_STAGE_IDLE); + if (is_idle) + { + _ctrl_xfer.stage = CONTROL_STAGE_SETUP; + _ctrl_xfer.daddr = daddr; + _ctrl_xfer.actual_len = 0; + + _ctrl_xfer.request = (*xfer->setup); + _ctrl_xfer.buffer = xfer->buffer; + _ctrl_xfer.complete_cb = xfer->complete_cb; + _ctrl_xfer.user_data = xfer->user_data; + } + + usbh_unlock(); + + TU_VERIFY(is_idle); + const uint8_t rhport = usbh_get_rhport(daddr); + + TU_LOG2("[%u:%u] %s: ", rhport, daddr, xfer->setup->bRequest <= TUSB_REQ_SYNCH_FRAME ? tu_str_std_request[xfer->setup->bRequest] : "Unknown Request"); + TU_LOG2_VAR(&xfer->setup); + TU_LOG2("\r\n"); + + if (xfer->complete_cb) + { + TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t*) &_ctrl_xfer.request) ); + }else + { + // blocking if complete callback is not provided + // change callback to internal blocking, and result as user argument + volatile xfer_result_t result = XFER_RESULT_INVALID; + + // use user_data to point to xfer_result_t + _ctrl_xfer.user_data = (uintptr_t) &result; + _ctrl_xfer.complete_cb = _control_blocking_complete_cb; + + TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t*) &_ctrl_xfer.request) ); + + while (result == XFER_RESULT_INVALID) + { + // only need to call task if not preempted RTOS + #if CFG_TUSB_OS == OPT_OS_NONE || CFG_TUSB_OS == OPT_OS_PICO + tuh_task(); + #endif + + // TODO probably some timeout to prevent hanged + } + + // update transfer result + xfer->result = result; + xfer->actual_len = _ctrl_xfer.actual_len; + } + + return true; +} + +TU_ATTR_ALWAYS_INLINE static inline void _set_control_xfer_stage(uint8_t stage) +{ + usbh_lock(); + _ctrl_xfer.stage = stage; + usbh_unlock(); +} + +static void _xfer_complete(uint8_t daddr, xfer_result_t result) +{ + TU_LOG2("\r\n"); + + // duplicate xfer since user can execute control transfer within callback + tusb_control_request_t const request = _ctrl_xfer.request; + tuh_xfer_t xfer_temp = + { + .daddr = daddr, + .ep_addr = 0, + .result = result, + .setup = &request, + .actual_len = (uint32_t) _ctrl_xfer.actual_len, + .buffer = _ctrl_xfer.buffer, + .complete_cb = _ctrl_xfer.complete_cb, + .user_data = _ctrl_xfer.user_data + }; + + usbh_lock(); + _ctrl_xfer.stage = CONTROL_STAGE_IDLE; + usbh_unlock(); + + if (xfer_temp.complete_cb) + { + xfer_temp.complete_cb(&xfer_temp); + } +} + +static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) +{ + (void) ep_addr; + + const uint8_t rhport = usbh_get_rhport(dev_addr); + tusb_control_request_t const * request = &_ctrl_xfer.request; + + if (XFER_RESULT_SUCCESS != result) + { + TU_LOG2("[%u:%u] Control %s\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED"); + + // terminate transfer if any stage failed + _xfer_complete(dev_addr, result); + }else + { + switch(_ctrl_xfer.stage) + { + case CONTROL_STAGE_SETUP: + if (request->wLength) + { + // DATA stage: initial data toggle is always 1 + _set_control_xfer_stage(CONTROL_STAGE_DATA); + return hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.buffer, request->wLength); + } + __attribute__((fallthrough)); + + case CONTROL_STAGE_DATA: + if (xferred_bytes) + { + TU_LOG2("[%u:%u] Control data:\r\n", rhport, dev_addr); + TU_LOG2_MEM(_ctrl_xfer.buffer, xferred_bytes, 2); + } + + _ctrl_xfer.actual_len = xferred_bytes; + + // ACK stage: toggle is always 1 + _set_control_xfer_stage(CONTROL_STAGE_ACK); + hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, 1-request->bmRequestType_bit.direction), NULL, 0); + break; + + case CONTROL_STAGE_ACK: + _xfer_complete(dev_addr, result); + break; + + default: return false; + } + } + + return true; +} + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ + +bool tuh_edpt_xfer(tuh_xfer_t* xfer) +{ + TU_VERIFY(xfer->daddr && xfer->ep_addr); + + + + return true; +} + +//--------------------------------------------------------------------+ +// USBH API For Class Driver +//--------------------------------------------------------------------+ + +uint8_t usbh_get_rhport(uint8_t dev_addr) +{ + usbh_device_t* dev = get_device(dev_addr); + return dev ? dev->rhport : _dev0.rhport; +} + +uint8_t* usbh_get_enum_buf(void) +{ + return _usbh_ctrl_buf; +} + +void usbh_int_set(bool enabled) +{ + // TODO all host controller + if (enabled) + { + hcd_int_enable(TUH_OPT_RHPORT); + }else + { + hcd_int_disable(TUH_OPT_RHPORT); + } +} + +//--------------------------------------------------------------------+ +// Endpoint API +//--------------------------------------------------------------------+ + +// TODO has some duplication code with device, refactor later +bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr) +{ + usbh_device_t* dev = get_device(dev_addr); + + // addr0 only use tuh_control_xfer + TU_ASSERT(dev); + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + tu_edpt_state_t* ep_state = &dev->ep_status[epnum][dir]; + +#if TUSB_OPT_MUTEX + return tu_edpt_claim(ep_state, _usbh_mutex); +#else + return tu_edpt_claim(ep_state, NULL); +#endif +} + +// TODO has some duplication code with device, refactor later +bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr) +{ + // addr0 is always available + if (dev_addr == 0) return true; + + usbh_device_t* dev = get_device(dev_addr); + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + tu_edpt_state_t* ep_state = &dev->ep_status[epnum][dir]; + +#if TUSB_OPT_MUTEX + return tu_edpt_release(ep_state, _usbh_mutex); +#else + return tu_edpt_release(ep_state, NULL); +#endif +} + +// TODO has some duplication code with device, refactor later +bool usbh_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + usbh_device_t* dev = get_device(dev_addr); + TU_VERIFY(dev); + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + TU_LOG2(" Queue EP %02X with %u bytes ... ", ep_addr, total_bytes); + + // Attempt to transfer on a busy endpoint, sound like an race condition ! + TU_ASSERT(dev->ep_status[epnum][dir].busy == 0); + + // Set busy first since the actual transfer can be complete before hcd_edpt_xfer() + // could return and USBH task can preempt and clear the busy + dev->ep_status[epnum][dir].busy = true; + + if ( hcd_edpt_xfer(dev->rhport, dev_addr, ep_addr, buffer, total_bytes) ) + { + TU_LOG2("OK\r\n"); + return true; + }else + { + // HCD error, mark endpoint as ready to allow next transfer + dev->ep_status[epnum][dir].busy = false; + dev->ep_status[epnum][dir].claimed = 0; + TU_LOG1("failed\r\n"); + TU_BREAKPOINT(); + return false; + } +} + +static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size) +{ + TU_LOG2("Open EP0 with Size = %u (addr = %u)\r\n", max_packet_size, dev_addr); + + tusb_desc_endpoint_t ep0_desc = + { + .bLength = sizeof(tusb_desc_endpoint_t), + .bDescriptorType = TUSB_DESC_ENDPOINT, + .bEndpointAddress = 0, + .bmAttributes = { .xfer = TUSB_XFER_CONTROL }, + .wMaxPacketSize = max_packet_size, + .bInterval = 0 + }; + + return hcd_edpt_open(usbh_get_rhport(dev_addr), dev_addr, &ep0_desc); +} + +bool usbh_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep) +{ + TU_ASSERT( tu_edpt_validate(desc_ep, tuh_speed_get(dev_addr)) ); + return hcd_edpt_open(rhport, dev_addr, desc_ep); +} + +bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + usbh_device_t* dev = get_device(dev_addr); + TU_VERIFY(dev); + + return dev->ep_status[epnum][dir].busy; +} + +//--------------------------------------------------------------------+ +// HCD Event Handler +//--------------------------------------------------------------------+ + +void hcd_devtree_get_info(uint8_t dev_addr, hcd_devtree_info_t* devtree_info) +{ + usbh_device_t const* dev = get_device(dev_addr); + + if (dev) + { + devtree_info->rhport = dev->rhport; + devtree_info->hub_addr = dev->hub_addr; + devtree_info->hub_port = dev->hub_port; + devtree_info->speed = dev->speed; + }else + { + devtree_info->rhport = _dev0.rhport; + devtree_info->hub_addr = _dev0.hub_addr; + devtree_info->hub_port = _dev0.hub_port; + devtree_info->speed = _dev0.speed; + } +} + +void hcd_event_handler(hcd_event_t const* event, bool in_isr) +{ + switch (event->event_id) + { + default: + osal_queue_send(_usbh_q, event, in_isr); + break; + } +} + +void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, uint32_t xferred_bytes, xfer_result_t result, bool in_isr) +{ + hcd_event_t event = + { + .rhport = 0, // TODO correct rhport + .event_id = HCD_EVENT_XFER_COMPLETE, + .dev_addr = dev_addr, + .xfer_complete = + { + .ep_addr = ep_addr, + .result = result, + .len = xferred_bytes + } + }; + + hcd_event_handler(&event, in_isr); +} + +void hcd_event_device_attach(uint8_t rhport, bool in_isr) +{ + hcd_event_t event = + { + .rhport = rhport, + .event_id = HCD_EVENT_DEVICE_ATTACH + }; + + event.connection.hub_addr = 0; + event.connection.hub_port = 0; + + hcd_event_handler(&event, in_isr); +} + +void hcd_event_device_remove(uint8_t hostid, bool in_isr) +{ + hcd_event_t event = + { + .rhport = hostid, + .event_id = HCD_EVENT_DEVICE_REMOVE + }; + + event.connection.hub_addr = 0; + event.connection.hub_port = 0; + + hcd_event_handler(&event, in_isr); +} + //--------------------------------------------------------------------+ // Descriptors Async //--------------------------------------------------------------------+ @@ -535,554 +1080,6 @@ uint8_t tuh_descriptor_get_serial_string_sync(uint8_t daddr, uint16_t language_i _CONTROL_SYNC_API(tuh_descriptor_get_serial_string, daddr, language_id, buffer, len); } -//--------------------------------------------------------------------+ -// CLASS-USBD API (don't require to verify parameters) -//--------------------------------------------------------------------+ - -static void clear_device(usbh_device_t* dev) -{ - tu_memclr(dev, sizeof(usbh_device_t)); - memset(dev->itf2drv, DRVID_INVALID, sizeof(dev->itf2drv)); // invalid mapping - memset(dev->ep2drv , DRVID_INVALID, sizeof(dev->ep2drv )); // invalid mapping -} - -bool tuh_inited(void) -{ - return _usbh_initialized; -} - -bool tuh_init(uint8_t rhport) -{ - // skip if already initialized - if (_usbh_initialized) return _usbh_initialized; - - TU_LOG2("USBH init\r\n"); - TU_LOG2_INT(sizeof(usbh_device_t)); - TU_LOG2_INT(sizeof(hcd_event_t)); - TU_LOG2_INT(sizeof(_ctrl_xfer)); - TU_LOG2_INT(sizeof(tuh_xfer_t)); - - // Event queue - _usbh_q = osal_queue_create( &_usbh_qdef ); - TU_ASSERT(_usbh_q != NULL); - -#if TUSB_OPT_MUTEX - // Mutex - _usbh_mutex = osal_mutex_create(&_usbh_mutexdef); - TU_ASSERT(_usbh_mutex); -#endif - - // Device - tu_memclr(&_dev0, sizeof(_dev0)); - tu_memclr(_usbh_devices, sizeof(_usbh_devices)); - tu_memclr(&_ctrl_xfer, sizeof(_ctrl_xfer)); - - for(uint8_t i=0; iep_status[epnum][ep_dir].busy = 0; - dev->ep_status[epnum][ep_dir].claimed = 0; - - if ( 0 == epnum ) - { - usbh_control_xfer_cb(event.dev_addr, ep_addr, event.xfer_complete.result, event.xfer_complete.len); - }else - { - uint8_t drv_id = dev->ep2drv[epnum][ep_dir]; - TU_ASSERT(drv_id < USBH_CLASS_DRIVER_COUNT, ); - - TU_LOG2("%s xfer callback\r\n", usbh_class_drivers[drv_id].name); - usbh_class_drivers[drv_id].xfer_cb(event.dev_addr, ep_addr, event.xfer_complete.result, event.xfer_complete.len); - } - } - } - break; - - case USBH_EVENT_FUNC_CALL: - if ( event.func_call.func ) event.func_call.func(event.func_call.param); - break; - - default: break; - } - } -} - -//--------------------------------------------------------------------+ -// USBH API For Class Driver -//--------------------------------------------------------------------+ - -uint8_t usbh_get_rhport(uint8_t dev_addr) -{ - usbh_device_t* dev = get_device(dev_addr); - return dev ? dev->rhport : _dev0.rhport; -} - -uint8_t* usbh_get_enum_buf(void) -{ - return _usbh_ctrl_buf; -} - -void usbh_int_set(bool enabled) -{ - // TODO all host controller - if (enabled) - { - hcd_int_enable(TUH_OPT_RHPORT); - }else - { - hcd_int_disable(TUH_OPT_RHPORT); - } -} - -//--------------------------------------------------------------------+ -// HCD Event Handler -//--------------------------------------------------------------------+ - -void hcd_devtree_get_info(uint8_t dev_addr, hcd_devtree_info_t* devtree_info) -{ - usbh_device_t const* dev = get_device(dev_addr); - - if (dev) - { - devtree_info->rhport = dev->rhport; - devtree_info->hub_addr = dev->hub_addr; - devtree_info->hub_port = dev->hub_port; - devtree_info->speed = dev->speed; - }else - { - devtree_info->rhport = _dev0.rhport; - devtree_info->hub_addr = _dev0.hub_addr; - devtree_info->hub_port = _dev0.hub_port; - devtree_info->speed = _dev0.speed; - } -} - -void hcd_event_handler(hcd_event_t const* event, bool in_isr) -{ - switch (event->event_id) - { - default: - osal_queue_send(_usbh_q, event, in_isr); - break; - } -} - -void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, uint32_t xferred_bytes, xfer_result_t result, bool in_isr) -{ - hcd_event_t event = - { - .rhport = 0, // TODO correct rhport - .event_id = HCD_EVENT_XFER_COMPLETE, - .dev_addr = dev_addr, - .xfer_complete = - { - .ep_addr = ep_addr, - .result = result, - .len = xferred_bytes - } - }; - - hcd_event_handler(&event, in_isr); -} - -void hcd_event_device_attach(uint8_t rhport, bool in_isr) -{ - hcd_event_t event = - { - .rhport = rhport, - .event_id = HCD_EVENT_DEVICE_ATTACH - }; - - event.connection.hub_addr = 0; - event.connection.hub_port = 0; - - hcd_event_handler(&event, in_isr); -} - -void hcd_event_device_remove(uint8_t hostid, bool in_isr) -{ - hcd_event_t event = - { - .rhport = hostid, - .event_id = HCD_EVENT_DEVICE_REMOVE - }; - - event.connection.hub_addr = 0; - event.connection.hub_port = 0; - - hcd_event_handler(&event, in_isr); -} - -//--------------------------------------------------------------------+ -// Endpoint API -//--------------------------------------------------------------------+ - -// TODO has some duplication code with device, refactor later -bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr) -{ - usbh_device_t* dev = get_device(dev_addr); - - // addr0 only use tuh_control_xfer - TU_ASSERT(dev); - - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - tu_edpt_state_t* ep_state = &dev->ep_status[epnum][dir]; - -#if TUSB_OPT_MUTEX - return tu_edpt_claim(ep_state, _usbh_mutex); -#else - return tu_edpt_claim(ep_state, NULL); -#endif -} - -// TODO has some duplication code with device, refactor later -bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr) -{ - // addr0 is always available - if (dev_addr == 0) return true; - - usbh_device_t* dev = get_device(dev_addr); - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - tu_edpt_state_t* ep_state = &dev->ep_status[epnum][dir]; - -#if TUSB_OPT_MUTEX - return tu_edpt_release(ep_state, _usbh_mutex); -#else - return tu_edpt_release(ep_state, NULL); -#endif -} - -// TODO has some duplication code with device, refactor later -bool usbh_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) -{ - usbh_device_t* dev = get_device(dev_addr); - TU_VERIFY(dev); - - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - TU_LOG2(" Queue EP %02X with %u bytes ... ", ep_addr, total_bytes); - - // Attempt to transfer on a busy endpoint, sound like an race condition ! - TU_ASSERT(dev->ep_status[epnum][dir].busy == 0); - - // Set busy first since the actual transfer can be complete before hcd_edpt_xfer() - // could return and USBH task can preempt and clear the busy - dev->ep_status[epnum][dir].busy = true; - - if ( hcd_edpt_xfer(dev->rhport, dev_addr, ep_addr, buffer, total_bytes) ) - { - TU_LOG2("OK\r\n"); - return true; - }else - { - // HCD error, mark endpoint as ready to allow next transfer - dev->ep_status[epnum][dir].busy = false; - dev->ep_status[epnum][dir].claimed = 0; - TU_LOG1("failed\r\n"); - TU_BREAKPOINT(); - return false; - } -} - -static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size) -{ - TU_LOG2("Open EP0 with Size = %u (addr = %u)\r\n", max_packet_size, dev_addr); - - tusb_desc_endpoint_t ep0_desc = - { - .bLength = sizeof(tusb_desc_endpoint_t), - .bDescriptorType = TUSB_DESC_ENDPOINT, - .bEndpointAddress = 0, - .bmAttributes = { .xfer = TUSB_XFER_CONTROL }, - .wMaxPacketSize = max_packet_size, - .bInterval = 0 - }; - - return hcd_edpt_open(usbh_get_rhport(dev_addr), dev_addr, &ep0_desc); -} - -bool usbh_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep) -{ - TU_ASSERT( tu_edpt_validate(desc_ep, tuh_speed_get(dev_addr)) ); - return hcd_edpt_open(rhport, dev_addr, desc_ep); -} - -bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) -{ - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - usbh_device_t* dev = get_device(dev_addr); - TU_VERIFY(dev); - - return dev->ep_status[epnum][dir].busy; -} - -//--------------------------------------------------------------------+ -// Control transfer -//--------------------------------------------------------------------+ - -static void _control_blocking_complete_cb(tuh_xfer_t* xfer) -{ - // update result - *((xfer_result_t*) xfer->user_data) = xfer->result; -} - -// TODO timeout_ms is not supported yet -bool tuh_control_xfer (tuh_xfer_t* xfer) -{ - // EP0 with setup packet - TU_VERIFY(xfer->ep_addr == 0 && xfer->setup); - - // pre-check to help reducing mutex lock - TU_VERIFY(_ctrl_xfer.stage == CONTROL_STAGE_IDLE); - - uint8_t const daddr = xfer->daddr; - - // TODO probably better to use semaphore as resource management than mutex - usbh_lock(); - - bool const is_idle = (_ctrl_xfer.stage == CONTROL_STAGE_IDLE); - if (is_idle) - { - _ctrl_xfer.stage = CONTROL_STAGE_SETUP; - _ctrl_xfer.daddr = daddr; - _ctrl_xfer.actual_len = 0; - - _ctrl_xfer.request = (*xfer->setup); - _ctrl_xfer.buffer = xfer->buffer; - _ctrl_xfer.complete_cb = xfer->complete_cb; - _ctrl_xfer.user_data = xfer->user_data; - } - - usbh_unlock(); - - TU_VERIFY(is_idle); - const uint8_t rhport = usbh_get_rhport(daddr); - - TU_LOG2("[%u:%u] %s: ", rhport, daddr, xfer->setup->bRequest <= TUSB_REQ_SYNCH_FRAME ? tu_str_std_request[xfer->setup->bRequest] : "Unknown Request"); - TU_LOG2_VAR(&xfer->setup); - TU_LOG2("\r\n"); - - if (xfer->complete_cb) - { - TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t*) &_ctrl_xfer.request) ); - }else - { - // blocking if complete callback is not provided - // change callback to internal blocking, and result as user argument - volatile xfer_result_t result = XFER_RESULT_INVALID; - - // use user_data to point to xfer_result_t - _ctrl_xfer.user_data = (uintptr_t) &result; - _ctrl_xfer.complete_cb = _control_blocking_complete_cb; - - TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t*) &_ctrl_xfer.request) ); - - while (result == XFER_RESULT_INVALID) - { - // only need to call task if not preempted RTOS - #if CFG_TUSB_OS == OPT_OS_NONE || CFG_TUSB_OS == OPT_OS_PICO - tuh_task(); - #endif - - // TODO probably some timeout to prevent hanged - } - - // update transfer result - xfer->result = result; - xfer->actual_len = _ctrl_xfer.actual_len; - } - - return true; -} - -TU_ATTR_ALWAYS_INLINE static inline void _set_control_xfer_stage(uint8_t stage) -{ - usbh_lock(); - _ctrl_xfer.stage = stage; - usbh_unlock(); -} - -static void _xfer_complete(uint8_t daddr, xfer_result_t result) -{ - TU_LOG2("\r\n"); - - // duplicate xfer since user can execute control transfer within callback - tusb_control_request_t const request = _ctrl_xfer.request; - tuh_xfer_t xfer_temp = - { - .daddr = daddr, - .ep_addr = 0, - .result = result, - .setup = &request, - .actual_len = (uint32_t) _ctrl_xfer.actual_len, - .buffer = _ctrl_xfer.buffer, - .complete_cb = _ctrl_xfer.complete_cb, - .user_data = _ctrl_xfer.user_data - }; - - usbh_lock(); - _ctrl_xfer.stage = CONTROL_STAGE_IDLE; - usbh_unlock(); - - if (xfer_temp.complete_cb) - { - xfer_temp.complete_cb(&xfer_temp); - } -} - -static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) -{ - (void) ep_addr; - - const uint8_t rhport = usbh_get_rhport(dev_addr); - tusb_control_request_t const * request = &_ctrl_xfer.request; - - if (XFER_RESULT_SUCCESS != result) - { - TU_LOG2("[%u:%u] Control %s\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED"); - - // terminate transfer if any stage failed - _xfer_complete(dev_addr, result); - }else - { - switch(_ctrl_xfer.stage) - { - case CONTROL_STAGE_SETUP: - if (request->wLength) - { - // DATA stage: initial data toggle is always 1 - _set_control_xfer_stage(CONTROL_STAGE_DATA); - return hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.buffer, request->wLength); - } - __attribute__((fallthrough)); - - case CONTROL_STAGE_DATA: - if (xferred_bytes) - { - TU_LOG2("[%u:%u] Control data:\r\n", rhport, dev_addr); - TU_LOG2_MEM(_ctrl_xfer.buffer, xferred_bytes, 2); - } - - _ctrl_xfer.actual_len = xferred_bytes; - - // ACK stage: toggle is always 1 - _set_control_xfer_stage(CONTROL_STAGE_ACK); - hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, 1-request->bmRequestType_bit.direction), NULL, 0); - break; - - case CONTROL_STAGE_ACK: - _xfer_complete(dev_addr, result); - break; - - default: return false; - } - } - - return true; -} - -//--------------------------------------------------------------------+ -// -//--------------------------------------------------------------------+ - -bool tuh_edpt_xfer(tuh_xfer_t* xfer) -{ - (void) xfer; - return true; -} - //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ From ba1185bf28331da718cca38e6598361889fce54d Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 18 Mar 2022 22:22:21 +0700 Subject: [PATCH 261/504] implement tuh_edpt_xfer() for non-control --- examples/host/bare_api/src/main.c | 193 ++++++++++++++++-------------- src/class/hid/hid_host.c | 8 +- src/host/usbh.c | 104 +++++++++++----- src/host/usbh.h | 10 +- src/host/usbh_classdriver.h | 12 +- 5 files changed, 201 insertions(+), 126 deletions(-) diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index e2e0f4ff3..06ae03ecb 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -40,6 +40,8 @@ //--------------------------------------------------------------------+ void led_blinking_task(void); +static void print_utf16(uint16_t *temp_buf, size_t buf_len); + /*------------- MAIN -------------*/ int main(void) { @@ -65,10 +67,108 @@ int main(void) // English #define LANGUAGE_ID 0x0409 -//uint8_t usb_buf[256] TU_ATTR_ALIGNED(4); -TU_ATTR_ALIGNED(4) tusb_desc_device_t desc_device; +//void parse_config_descriptor(uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg) +//{ +// uint8_t const* desc_end = ((uint8_t const*) desc_cfg) + tu_le16toh(desc_cfg->wTotalLength); +// uint8_t const* p_desc = tu_desc_next(desc_cfg); +//} + +void print_device_descriptor(tuh_xfer_t* xfer) +{ + if ( XFER_RESULT_SUCCESS != xfer->result ) + { + printf("Failed to get device descriptor\r\n"); + return; + } + + uint8_t const daddr = xfer->daddr; + + printf("Device %u: ID %04x:%04x\r\n", daddr, desc_device.idVendor, desc_device.idProduct); + printf("Device Descriptor:\r\n"); + printf(" bLength %u\r\n" , desc_device.bLength); + printf(" bDescriptorType %u\r\n" , desc_device.bDescriptorType); + printf(" bcdUSB %04x\r\n" , desc_device.bcdUSB); + printf(" bDeviceClass %u\r\n" , desc_device.bDeviceClass); + printf(" bDeviceSubClass %u\r\n" , desc_device.bDeviceSubClass); + printf(" bDeviceProtocol %u\r\n" , desc_device.bDeviceProtocol); + printf(" bMaxPacketSize0 %u\r\n" , desc_device.bMaxPacketSize0); + printf(" idVendor 0x%04x\r\n" , desc_device.idVendor); + printf(" idProduct 0x%04x\r\n" , desc_device.idProduct); + printf(" bcdDevice %04x\r\n" , desc_device.bcdDevice); + + // Get String descriptor using Sync API + uint16_t temp_buf[128]; + + printf(" iManufacturer %u " , desc_device.iManufacturer); + if (XFER_RESULT_SUCCESS == tuh_descriptor_get_manufacturer_string_sync(daddr, LANGUAGE_ID, temp_buf, sizeof(temp_buf)) ) + { + print_utf16(temp_buf, TU_ARRAY_SIZE(temp_buf)); + } + printf("\r\n"); + + printf(" iProduct %u " , desc_device.iProduct); + if (XFER_RESULT_SUCCESS == tuh_descriptor_get_product_string_sync(daddr, LANGUAGE_ID, temp_buf, sizeof(temp_buf))) + { + print_utf16(temp_buf, TU_ARRAY_SIZE(temp_buf)); + } + printf("\r\n"); + + printf(" iSerialNumber %u " , desc_device.iSerialNumber); + if (XFER_RESULT_SUCCESS == tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, temp_buf, sizeof(temp_buf))) + { + print_utf16(temp_buf, TU_ARRAY_SIZE(temp_buf)); + } + printf("\r\n"); + + printf(" bNumConfigurations %u\r\n" , desc_device.bNumConfigurations); + + // Get configuration descriptor with sync API +// if (XFER_RESULT_SUCCESS == tuh_descriptor_get_configuration_sync(daddr, 0, temp_buf, sizeof(temp_buf)) ) +// { +// parse_config_descriptor(daddr, (tusb_desc_configuration_t*) temp_buf); +// } +} + +// Invoked when device is mounted (configured) +void tuh_mount_cb (uint8_t daddr) +{ + printf("Device attached, address = %d\r\n", daddr); + + // Get Device Descriptor sync API + // TODO: invoking control trannsfer now has issue with mounting hub with multiple devices attached, fix later + tuh_descriptor_get_device(daddr, &desc_device, 18, print_device_descriptor, 0); +} + +/// Invoked when device is unmounted (bus reset/unplugged) +void tuh_umount_cb(uint8_t daddr) +{ + printf("Device removed, address = %d\r\n", daddr); +} + +//--------------------------------------------------------------------+ +// Blinking Task +//--------------------------------------------------------------------+ +void led_blinking_task(void) +{ + const uint32_t interval_ms = 1000; + static uint32_t start_ms = 0; + + static bool led_state = false; + + // Blink every interval ms + if ( board_millis() - start_ms < interval_ms) return; // not enough time + start_ms += interval_ms; + + board_led_write(led_state); + led_state = 1 - led_state; // toggle +} + +//--------------------------------------------------------------------+ +// Helper +//--------------------------------------------------------------------+ + static void _convert_utf16le_to_utf8(const uint16_t *utf16, size_t utf16_len, uint8_t *utf8, size_t utf8_len) { // TODO: Check for runover. (void)utf8_len; @@ -108,94 +208,11 @@ static int _count_utf8_bytes(const uint16_t *buf, size_t len) { return total_bytes; } -static void utf16_to_utf8(uint16_t *temp_buf, size_t buf_len) { +static void print_utf16(uint16_t *temp_buf, size_t buf_len) { size_t utf16_len = ((temp_buf[0] & 0xff) - 2) / sizeof(uint16_t); size_t utf8_len = _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'; -} - -void print_device_descriptor(tuh_xfer_t* xfer) -{ - if ( XFER_RESULT_SUCCESS != xfer->result ) - { - printf("Failed to get device descriptor\r\n"); - return; - } - - uint8_t const daddr = xfer->daddr; - - printf("Device %u: ID %04x:%04x\r\n", daddr, desc_device.idVendor, desc_device.idProduct); - printf("Device Descriptor:\r\n"); - printf(" bLength %u\r\n" , desc_device.bLength); - printf(" bDescriptorType %u\r\n" , desc_device.bDescriptorType); - printf(" bcdUSB %04x\r\n" , desc_device.bcdUSB); - printf(" bDeviceClass %u\r\n" , desc_device.bDeviceClass); - printf(" bDeviceSubClass %u\r\n" , desc_device.bDeviceSubClass); - printf(" bDeviceProtocol %u\r\n" , desc_device.bDeviceProtocol); - printf(" bMaxPacketSize0 %u\r\n" , desc_device.bMaxPacketSize0); - printf(" idVendor 0x%04x\r\n" , desc_device.idVendor); - printf(" idProduct 0x%04x\r\n" , desc_device.idProduct); - printf(" bcdDevice %04x\r\n" , desc_device.bcdDevice); - - uint16_t temp_buf[128]; - - printf(" iManufacturer %u " , desc_device.iManufacturer); - if (XFER_RESULT_SUCCESS == tuh_descriptor_get_manufacturer_string_sync(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf)) ) - { - utf16_to_utf8(temp_buf, TU_ARRAY_SIZE(temp_buf)); - printf((const char*) temp_buf); - } - printf("\r\n"); - - printf(" iProduct %u " , desc_device.iProduct); - if (XFER_RESULT_SUCCESS == tuh_descriptor_get_product_string_sync(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf))) - { - utf16_to_utf8(temp_buf, TU_ARRAY_SIZE(temp_buf)); - printf((const char*) temp_buf); - } - printf("\r\n"); - - printf(" iSerialNumber %u " , desc_device.iSerialNumber); - if (XFER_RESULT_SUCCESS == tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf))) - { - utf16_to_utf8(temp_buf, TU_ARRAY_SIZE(temp_buf)); - printf((const char*) temp_buf); - } - printf("\r\n"); - - printf(" bNumConfigurations %u\r\n" , desc_device.bNumConfigurations); -} - -// Invoked when device is mounted (configured) -void tuh_mount_cb (uint8_t daddr) -{ - printf("Device attached, address = %d\r\n", daddr); - - // Get Device Descriptor using asynchronous API - tuh_descriptor_get_device(daddr, &desc_device, 18, print_device_descriptor, 0); -} - -/// Invoked when device is unmounted (bus reset/unplugged) -void tuh_umount_cb(uint8_t daddr) -{ - printf("Device removed, address = %d\r\n", daddr); -} - -//--------------------------------------------------------------------+ -// Blinking Task -//--------------------------------------------------------------------+ -void led_blinking_task(void) -{ - const uint32_t interval_ms = 1000; - static uint32_t start_ms = 0; - - static bool led_state = false; - - // Blink every interval ms - if ( board_millis() - start_ms < interval_ms) return; // not enough time - start_ms += interval_ms; - - board_led_write(led_state); - led_state = 1 - led_state; // toggle + + printf((char*)temp_buf); } diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index fa99b37fe..2bdd1db79 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -256,7 +256,13 @@ bool tuh_hid_receive_report(uint8_t dev_addr, uint8_t instance) // claim endpoint TU_VERIFY( usbh_edpt_claim(dev_addr, hid_itf->ep_in) ); - return usbh_edpt_xfer(dev_addr, hid_itf->ep_in, hid_itf->epin_buf, hid_itf->epin_size); + if ( !usbh_edpt_xfer(dev_addr, hid_itf->ep_in, hid_itf->epin_buf, hid_itf->epin_size) ) + { + usbh_edpt_claim(dev_addr, hid_itf->ep_in); + return false; + } + + return true; } //bool tuh_n_hid_n_ready(uint8_t dev_addr, uint8_t instance) diff --git a/src/host/usbh.c b/src/host/usbh.c index 8aa9c4a16..497badfde 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -82,8 +82,7 @@ typedef struct { uint8_t speed; // Device State - struct TU_ATTR_PACKED - { + struct TU_ATTR_PACKED { volatile uint8_t connected : 1; volatile uint8_t addressed : 1; volatile uint8_t configured : 1; @@ -110,7 +109,11 @@ typedef struct { tu_edpt_state_t ep_status[CFG_TUH_ENDPOINT_MAX][2]; #if CFG_TUH_API_EDPT_XFER - // ep_xfer[]; + // TODO array can be CFG_TUH_ENDPOINT_MAX-1 + struct { + tuh_xfer_cb_t complete_cb; + uintptr_t user_data; + }ep_callback[CFG_TUH_ENDPOINT_MAX][2]; #endif } usbh_device_t; @@ -227,6 +230,8 @@ TU_ATTR_ALWAYS_INLINE static inline void usbh_unlock(void) #else +#define _usbh_mutex NULL + #define usbh_lock() #define usbh_unlock() @@ -449,10 +454,38 @@ void tuh_task(void) }else { uint8_t drv_id = dev->ep2drv[epnum][ep_dir]; - TU_ASSERT(drv_id < USBH_CLASS_DRIVER_COUNT, ); + if(drv_id < USBH_CLASS_DRIVER_COUNT) + { + TU_LOG2("%s xfer callback\r\n", usbh_class_drivers[drv_id].name); + usbh_class_drivers[drv_id].xfer_cb(event.dev_addr, ep_addr, event.xfer_complete.result, event.xfer_complete.len); + } + else + { +#if CFG_TUH_API_EDPT_XFER + tuh_xfer_cb_t complete_cb = dev->ep_callback[epnum][ep_dir].complete_cb; + if ( complete_cb ) + { + tuh_xfer_t xfer = + { + .daddr = event.dev_addr, + .ep_addr = ep_addr, + .result = event.xfer_complete.result, + .actual_len = event.xfer_complete.len, + .buflen = 0, // not available + .buffer = NULL, // not available + .complete_cb = complete_cb, + .user_data = dev->ep_callback[epnum][ep_dir].user_data + }; - TU_LOG2("%s xfer callback\r\n", usbh_class_drivers[drv_id].name); - usbh_class_drivers[drv_id].xfer_cb(event.dev_addr, ep_addr, event.xfer_complete.result, event.xfer_complete.len); + complete_cb(&xfer); + }else +#endif + { + // no driver/callback responsible for this transfer + TU_ASSERT(false, ); + } + + } } } } @@ -638,9 +671,18 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result bool tuh_edpt_xfer(tuh_xfer_t* xfer) { - TU_VERIFY(xfer->daddr && xfer->ep_addr); + uint8_t const daddr = xfer->daddr; + uint8_t const ep_addr = xfer->ep_addr; + TU_VERIFY(daddr && ep_addr); + TU_VERIFY(usbh_edpt_claim(daddr, ep_addr)); + + if ( !usbh_edpt_xfer_with_callback(daddr, ep_addr, xfer->buffer, xfer->buflen, xfer->complete_cb, xfer->user_data) ) + { + usbh_edpt_release(daddr, ep_addr); + return false; + } return true; } @@ -687,50 +729,50 @@ bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr) uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); - tu_edpt_state_t* ep_state = &dev->ep_status[epnum][dir]; - -#if TUSB_OPT_MUTEX - return tu_edpt_claim(ep_state, _usbh_mutex); -#else - return tu_edpt_claim(ep_state, NULL); -#endif + return tu_edpt_claim(&dev->ep_status[epnum][dir], _usbh_mutex); } // TODO has some duplication code with device, refactor later bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr) { - // addr0 is always available - if (dev_addr == 0) return true; + usbh_device_t* dev = get_device(dev_addr); - usbh_device_t* dev = get_device(dev_addr); - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - tu_edpt_state_t* ep_state = &dev->ep_status[epnum][dir]; + // addr0 only use tuh_control_xfer + TU_ASSERT(dev); -#if TUSB_OPT_MUTEX - return tu_edpt_release(ep_state, _usbh_mutex); -#else - return tu_edpt_release(ep_state, NULL); -#endif + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + return tu_edpt_release(&dev->ep_status[epnum][dir], _usbh_mutex); } // TODO has some duplication code with device, refactor later -bool usbh_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + (void) complete_cb; + (void) user_data; + usbh_device_t* dev = get_device(dev_addr); TU_VERIFY(dev); uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); + tu_edpt_state_t* ep_state = &dev->ep_status[epnum][dir]; TU_LOG2(" Queue EP %02X with %u bytes ... ", ep_addr, total_bytes); // Attempt to transfer on a busy endpoint, sound like an race condition ! - TU_ASSERT(dev->ep_status[epnum][dir].busy == 0); + TU_ASSERT(ep_state->busy == 0); // Set busy first since the actual transfer can be complete before hcd_edpt_xfer() // could return and USBH task can preempt and clear the busy - dev->ep_status[epnum][dir].busy = true; + ep_state->busy = 1; + +#if CFG_TUH_API_EDPT_XFER + dev->ep_callback[epnum][dir].complete_cb = complete_cb; + dev->ep_callback[epnum][dir].user_data = user_data; +#endif if ( hcd_edpt_xfer(dev->rhport, dev_addr, ep_addr, buffer, total_bytes) ) { @@ -739,9 +781,9 @@ bool usbh_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_ }else { // HCD error, mark endpoint as ready to allow next transfer - dev->ep_status[epnum][dir].busy = false; - dev->ep_status[epnum][dir].claimed = 0; - TU_LOG1("failed\r\n"); + ep_state->busy = 0; + ep_state->claimed = 0; + TU_LOG1("Failed\r\n"); TU_BREAKPOINT(); return false; } diff --git a/src/host/usbh.h b/src/host/usbh.h index f79c5cdc8..772c4cfd6 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -44,25 +44,27 @@ typedef struct tuh_xfer_s tuh_xfer_t; typedef void (*tuh_xfer_cb_t)(tuh_xfer_t* xfer); +// Note: layout and order of this will be changed in near future +// it is advised to initialize it using member name struct tuh_xfer_s { uint8_t daddr; uint8_t ep_addr; xfer_result_t result; - uint32_t actual_len; // excluding setup packet + uint32_t actual_len; // excluding setup packet union { tusb_control_request_t const* setup; // setup packet pointer if control transfer - uint32_t buflen; // length if not control transfer + uint32_t buflen; // expected length if not control transfer (not available in callback) }; - uint8_t* buffer; + uint8_t* buffer; // not available in callback if not control transfer tuh_xfer_cb_t complete_cb; uintptr_t user_data; - uint32_t timeout_ms; // place holder, not supported yet + // uint32_t timeout_ms; // place holder, not supported yet }; //--------------------------------------------------------------------+ diff --git a/src/host/usbh_classdriver.h b/src/host/usbh_classdriver.h index 0435eae70..30e97535d 100644 --- a/src/host/usbh_classdriver.h +++ b/src/host/usbh_classdriver.h @@ -66,8 +66,16 @@ void usbh_int_set(bool enabled); // Open an endpoint bool usbh_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep); -// Submit a usb transfer -bool usbh_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes); +// Submit a usb transfer with callback support, require CFG_TUH_API_EDPT_XFER +bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, + tuh_xfer_cb_t complete_cb, uintptr_t user_data); + +TU_ATTR_ALWAYS_INLINE +static inline bool usbh_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + return usbh_edpt_xfer_with_callback(dev_addr, ep_addr, buffer, total_bytes, NULL, 0); +} + // Claim an endpoint before submitting a transfer. // If caller does not make any transfer, it must release endpoint for others. From 4795cca04ac60d58fbc78d554cd7af7039cd310a Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 19 Mar 2022 00:43:31 +0700 Subject: [PATCH 262/504] add parse config descriptor to example move usbh_edpt_open() to public API, remove rhport from its signature --- examples/host/bare_api/src/main.c | 154 +++++++++++++++++++++++++----- src/class/cdc/cdc_host.c | 5 +- src/class/hid/hid.h | 2 +- src/class/hid/hid_host.c | 3 +- src/class/msc/msc_host.c | 3 +- src/host/hub.c | 4 +- src/host/usbh.c | 11 ++- src/host/usbh.h | 14 ++- src/host/usbh_classdriver.h | 3 - src/portable/ehci/ehci.c | 25 ++++- src/tusb.h | 2 + 11 files changed, 180 insertions(+), 46 deletions(-) diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index 06ae03ecb..3b23dd43b 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -35,12 +35,19 @@ #include "bsp/board.h" #include "tusb.h" +// English +#define LANGUAGE_ID 0x0409 + //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ void led_blinking_task(void); static void print_utf16(uint16_t *temp_buf, size_t buf_len); +void print_device_descriptor(tuh_xfer_t* xfer); +void parse_config_descriptor(uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg); + +tusb_desc_device_t desc_device; /*------------- MAIN -------------*/ int main(void) @@ -60,21 +67,28 @@ int main(void) return 0; } +/*------------- TinyUSB Callbacks -------------*/ + +// Invoked when device is mounted (configured) +void tuh_mount_cb (uint8_t daddr) +{ + printf("Device attached, address = %d\r\n", daddr); + + // Get Device Descriptor sync API + // TODO: invoking control trannsfer now has issue with mounting hub with multiple devices attached, fix later + tuh_descriptor_get_device(daddr, &desc_device, 18, print_device_descriptor, 0); +} + +/// Invoked when device is unmounted (bus reset/unplugged) +void tuh_umount_cb(uint8_t daddr) +{ + printf("Device removed, address = %d\r\n", daddr); +} + //--------------------------------------------------------------------+ -// TinyUSB Callbacks +// Device Descriptor //--------------------------------------------------------------------+ -// English -#define LANGUAGE_ID 0x0409 - -tusb_desc_device_t desc_device; - -//void parse_config_descriptor(uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg) -//{ -// uint8_t const* desc_end = ((uint8_t const*) desc_cfg) + tu_le16toh(desc_cfg->wTotalLength); -// uint8_t const* p_desc = tu_desc_next(desc_cfg); -//} - void print_device_descriptor(tuh_xfer_t* xfer) { if ( XFER_RESULT_SUCCESS != xfer->result ) @@ -125,28 +139,118 @@ void print_device_descriptor(tuh_xfer_t* xfer) printf(" bNumConfigurations %u\r\n" , desc_device.bNumConfigurations); // Get configuration descriptor with sync API -// if (XFER_RESULT_SUCCESS == tuh_descriptor_get_configuration_sync(daddr, 0, temp_buf, sizeof(temp_buf)) ) -// { -// parse_config_descriptor(daddr, (tusb_desc_configuration_t*) temp_buf); -// } + if (XFER_RESULT_SUCCESS == tuh_descriptor_get_configuration_sync(daddr, 0, temp_buf, sizeof(temp_buf)) ) + { + parse_config_descriptor(daddr, (tusb_desc_configuration_t*) temp_buf); + } } -// Invoked when device is mounted (configured) -void tuh_mount_cb (uint8_t daddr) + +//--------------------------------------------------------------------+ +// Configuration Descriptor +//--------------------------------------------------------------------+ + +// count total length of an interface +uint16_t count_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_t itf_count, uint16_t max_len); + +void open_hid_interface(uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len) { - printf("Device attached, address = %d\r\n", daddr); + // len = interface + hid + n*endpoints + uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); - // Get Device Descriptor sync API - // TODO: invoking control trannsfer now has issue with mounting hub with multiple devices attached, fix later - tuh_descriptor_get_device(daddr, &desc_device, 18, print_device_descriptor, 0); + // corrupted descriptor + if (max_len < drv_len) return; + + uint8_t const *p_desc = (uint8_t const *) desc_itf; + + // HID descriptor + p_desc = tu_desc_next(p_desc); + + // Endpoint descriptor + tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc; + + for(int i = 0; i < desc_itf->bNumEndpoints; i++) + { + if (TUSB_DESC_ENDPOINT != desc_ep->bDescriptorType) return; + + if(tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) + { + //usbh_edpt_open(rhport, dev_addr, desc_ep); + } + } } -/// Invoked when device is unmounted (bus reset/unplugged) -void tuh_umount_cb(uint8_t daddr) +// simple configuration parser to open and listen to HID Endpoint IN +void parse_config_descriptor(uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg) { - printf("Device removed, address = %d\r\n", daddr); + uint8_t const* desc_end = ((uint8_t const*) desc_cfg) + tu_le16toh(desc_cfg->wTotalLength); + uint8_t const* p_desc = tu_desc_next(desc_cfg); + + // parse each interfaces + while( p_desc < desc_end ) + { + uint8_t assoc_itf_count = 1; + + // Class will always starts with Interface Association (if any) and then Interface descriptor + if ( TUSB_DESC_INTERFACE_ASSOCIATION == tu_desc_type(p_desc) ) + { + tusb_desc_interface_assoc_t const * desc_iad = (tusb_desc_interface_assoc_t const *) p_desc; + assoc_itf_count = desc_iad->bInterfaceCount; + + p_desc = tu_desc_next(p_desc); // next to Interface + } + + // must be interface from now + if( TUSB_DESC_INTERFACE != tu_desc_type(p_desc) ) return; + tusb_desc_interface_t const* desc_itf = (tusb_desc_interface_t const*) p_desc; + + uint16_t const drv_len = count_interface_total_len(desc_itf, assoc_itf_count, desc_end-p_desc); + + // probably corrupted descriptor + if(drv_len < sizeof(tusb_desc_interface_t)) return; + + // only open and listen to HID endpoint IN + if (desc_itf->bInterfaceClass == TUSB_CLASS_HID) + { + open_hid_interface(dev_addr, desc_itf, drv_len); + } + + // next Interface or IAD descriptor + p_desc += drv_len; + } } +uint16_t count_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_t itf_count, uint16_t max_len) +{ + uint8_t const* p_desc = (uint8_t const*) desc_itf; + uint16_t len = 0; + + while (itf_count--) + { + // Next on interface desc + len += tu_desc_len(desc_itf); + p_desc = tu_desc_next(p_desc); + + while (len < max_len) + { + // return on IAD regardless of itf count + if ( tu_desc_type(p_desc) == TUSB_DESC_INTERFACE_ASSOCIATION ) return len; + + if ( (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) && + ((tusb_desc_interface_t const*) p_desc)->bAlternateSetting == 0 ) + { + break; + } + + len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } + } + + return len; +} + + //--------------------------------------------------------------------+ // Blinking Task //--------------------------------------------------------------------+ diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index f946974e8..82cf911cf 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -161,6 +161,7 @@ void cdch_init(void) bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { + (void) rhport; (void) max_len; // Only support ACM subclass @@ -196,7 +197,7 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it // notification endpoint tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc; - TU_ASSERT( usbh_edpt_open(rhport, dev_addr, desc_ep) ); + TU_ASSERT( usbh_edpt_open(dev_addr, desc_ep) ); p_cdc->ep_notif = desc_ep->bEndpointAddress; drv_len += tu_desc_len(p_desc); @@ -217,7 +218,7 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) p_desc; TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && TUSB_XFER_BULK == desc_ep->bmAttributes.xfer); - TU_ASSERT(usbh_edpt_open(rhport, dev_addr, desc_ep)); + TU_ASSERT(usbh_edpt_open(dev_addr, desc_ep)); if ( tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN ) { diff --git a/src/class/hid/hid.h b/src/class/hid/hid.h index 940454bd9..44a464be1 100644 --- a/src/class/hid/hid.h +++ b/src/class/hid/hid.h @@ -43,7 +43,7 @@ /** \defgroup ClassDriver_HID_Common Common Definitions * @{ */ - /// USB HID Descriptor +/// USB HID Descriptor typedef struct TU_ATTR_PACKED { uint8_t bLength; /**< Numeric expression that is the total size of the HID descriptor */ diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 2bdd1db79..2280e87b4 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -324,6 +324,7 @@ void hidh_close(uint8_t dev_addr) bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len) { + (void) rhport; (void) max_len; TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass); @@ -355,7 +356,7 @@ bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *de for(int i = 0; i < desc_itf->bNumEndpoints; i++) { TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType); - TU_ASSERT( usbh_edpt_open(rhport, dev_addr, desc_ep) ); + TU_ASSERT( usbh_edpt_open(dev_addr, desc_ep) ); if(tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index 06af781f5..4033cc429 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -365,6 +365,7 @@ static bool config_read_capacity_complete(uint8_t dev_addr, msc_cbw_t const* cbw bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len) { + (void) rhport; TU_VERIFY (MSC_SUBCLASS_SCSI == desc_itf->bInterfaceSubClass && MSC_PROTOCOL_BOT == desc_itf->bInterfaceProtocol); @@ -378,7 +379,7 @@ bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *de for(uint32_t i=0; i<2; i++) { TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType && TUSB_XFER_BULK == ep_desc->bmAttributes.xfer); - TU_ASSERT(usbh_edpt_open(rhport, dev_addr, ep_desc)); + TU_ASSERT(usbh_edpt_open(dev_addr, ep_desc)); if ( tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN ) { diff --git a/src/host/hub.c b/src/host/hub.c index da4f6fe3a..b4d369aca 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -183,6 +183,8 @@ void hub_init(void) bool hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { + (void) rhport; + TU_VERIFY(TUSB_CLASS_HUB == itf_desc->bInterfaceClass && 0 == itf_desc->bInterfaceSubClass); @@ -199,7 +201,7 @@ bool hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && TUSB_XFER_INTERRUPT == desc_ep->bmAttributes.xfer, 0); - TU_ASSERT(usbh_edpt_open(rhport, dev_addr, desc_ep)); + TU_ASSERT(usbh_edpt_open(dev_addr, desc_ep)); hub_interface_t* p_hub = get_itf(dev_addr); diff --git a/src/host/usbh.c b/src/host/usbh.c index 497badfde..466e5decd 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -806,10 +806,11 @@ static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size) return hcd_edpt_open(usbh_get_rhport(dev_addr), dev_addr, &ep0_desc); } -bool usbh_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep) +bool usbh_edpt_open(uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep) { TU_ASSERT( tu_edpt_validate(desc_ep, tuh_speed_get(dev_addr)) ); - return hcd_edpt_open(rhport, dev_addr, desc_ep); + + return hcd_edpt_open(usbh_get_rhport(dev_addr), dev_addr, desc_ep); } bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) @@ -1189,7 +1190,7 @@ enum { }; static bool enum_request_set_addr(void); -static bool parse_configuration_descriptor (uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg); +static bool _parse_configuration_descriptor (uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg); static void enum_full_complete(void); // process device enumeration @@ -1350,7 +1351,7 @@ static void process_enumeration(tuh_xfer_t* xfer) case ENUM_SET_CONFIG: // Parse configuration & set up drivers // Driver open aren't allowed to make any usb transfer yet - TU_ASSERT( parse_configuration_descriptor(daddr, (tusb_desc_configuration_t*) _usbh_ctrl_buf), ); + TU_ASSERT( _parse_configuration_descriptor(daddr, (tusb_desc_configuration_t*) _usbh_ctrl_buf), ); TU_ASSERT( tuh_configuration_set(daddr, CONFIG_NUM, process_enumeration, ENUM_CONFIG_DRIVER), ); break; @@ -1496,7 +1497,7 @@ static bool enum_request_set_addr(void) return true; } -static bool parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg) +static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg) { usbh_device_t* dev = get_device(dev_addr); diff --git a/src/host/usbh.h b/src/host/usbh.h index 772c4cfd6..a2df0153e 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -44,8 +44,10 @@ typedef struct tuh_xfer_s tuh_xfer_t; typedef void (*tuh_xfer_cb_t)(tuh_xfer_t* xfer); -// Note: layout and order of this will be changed in near future +// Note1: layout and order of this will be changed in near future // it is advised to initialize it using member name +// Note2: not all field is available/meaningful in callback, some info is not saved by +// usbh to save SRAM struct tuh_xfer_s { uint8_t daddr; @@ -124,14 +126,18 @@ static inline bool tuh_ready(uint8_t daddr) //--------------------------------------------------------------------+ // Submit a control transfer -// Note: blocking if complete callback is NULL, in this case xfer contents will be updated to reflect the result +// - async: complete callback invoked when finished. +// - sync : blocking if complete callback is NULL. bool tuh_control_xfer(tuh_xfer_t* xfer); // Submit a bulk/interrupt transfer -// xfer memory must exist until transfer is complete. -// Note: blocking if complete callback is NULL. +// - async: complete callback invoked when finished. +// - sync : blocking if complete callback is NULL. bool tuh_edpt_xfer(tuh_xfer_t* xfer); +// Open an endpoint +bool usbh_edpt_open(uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep); + // Set Configuration (control transfer) // config_num = 0 will un-configure device. Note: config_num = config_descriptor_index + 1 // true on success, false if there is on-going control transfer or incorrect parameters diff --git a/src/host/usbh_classdriver.h b/src/host/usbh_classdriver.h index 30e97535d..c156afea0 100644 --- a/src/host/usbh_classdriver.h +++ b/src/host/usbh_classdriver.h @@ -63,9 +63,6 @@ void usbh_int_set(bool enabled); // USBH Endpoint API //--------------------------------------------------------------------+ -// Open an endpoint -bool usbh_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep); - // Submit a usb transfer with callback support, require CFG_TUH_API_EDPT_XFER bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, tuh_xfer_cb_t complete_cb, uintptr_t user_data); diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index 8d420f26a..665f2380b 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -656,6 +656,26 @@ static void xfer_error_isr(uint8_t hostid) } } +#if CFG_TUSB_DEBUG >= EHCI_DBG + +static inline void print_portsc(ehci_registers_t* regs) +{ + TU_LOG_HEX(EHCI_DBG, regs->portsc); + TU_LOG(EHCI_DBG, " Current Connect Status: %u\r\n", regs->portsc_bm.current_connect_status); + TU_LOG(EHCI_DBG, " Connect Status Change : %u\r\n", regs->portsc_bm.connect_status_change); + TU_LOG(EHCI_DBG, " Port Enabled : %u\r\n", regs->portsc_bm.port_enabled); + TU_LOG(EHCI_DBG, " Port Enabled Change : %u\r\n", regs->portsc_bm.port_enable_change); + + TU_LOG(EHCI_DBG, " Port Reset : %u\r\n", regs->portsc_bm.port_reset); + TU_LOG(EHCI_DBG, " Port Power : %u\r\n", regs->portsc_bm.port_power); +} + +#else + +#define print_portsc(_reg) + +#endif + //------------- Host Controller Driver's Interrupt Handler -------------// void hcd_int_handler(uint8_t rhport) { @@ -675,9 +695,8 @@ void hcd_int_handler(uint8_t rhport) if (int_status & EHCI_INT_MASK_PORT_CHANGE) { - uint32_t port_status = regs->portsc & EHCI_PORTSC_MASK_ALL; - - TU_LOG_HEX(EHCI_DBG, regs->portsc); + uint32_t const port_status = regs->portsc & EHCI_PORTSC_MASK_ALL; + print_portsc(regs); if (regs->portsc_bm.connect_status_change) { diff --git a/src/tusb.h b/src/tusb.h index 222855fcb..b776d7d01 100644 --- a/src/tusb.h +++ b/src/tusb.h @@ -38,6 +38,8 @@ #include "osal/osal.h" #include "common/tusb_fifo.h" +#include "class/hid/hid.h" + //------------- HOST -------------// #if CFG_TUH_ENABLED #include "host/usbh.h" From a4b976f095ae36ab90cfc5394211598626ff895e Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 19 Mar 2022 14:57:43 +0700 Subject: [PATCH 263/504] get bare example working with hid device --- examples/host/bare_api/src/main.c | 86 +++++++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 3 deletions(-) diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index 3b23dd43b..3f3d1d488 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -49,6 +49,11 @@ void parse_config_descriptor(uint8_t dev_addr, tusb_desc_configuration_t const* tusb_desc_device_t desc_device; +#define BUF_COUNT 4 + +uint8_t buf_pool[BUF_COUNT][64]; +uint8_t buf_owner[BUF_COUNT] = { 0 }; // device address that owns buffer + /*------------- MAIN -------------*/ int main(void) { @@ -139,7 +144,7 @@ void print_device_descriptor(tuh_xfer_t* xfer) printf(" bNumConfigurations %u\r\n" , desc_device.bNumConfigurations); // Get configuration descriptor with sync API - if (XFER_RESULT_SUCCESS == tuh_descriptor_get_configuration_sync(daddr, 0, temp_buf, sizeof(temp_buf)) ) + if (XFER_RESULT_SUCCESS == tuh_descriptor_get_configuration_sync(daddr, 0, temp_buf, sizeof(temp_buf))) { parse_config_descriptor(daddr, (tusb_desc_configuration_t*) temp_buf); } @@ -150,10 +155,60 @@ void print_device_descriptor(tuh_xfer_t* xfer) // Configuration Descriptor //--------------------------------------------------------------------+ +// get an buffer from pool +uint8_t* get_hid_buf(uint8_t daddr) +{ + for(size_t i=0; ibuffer is NULL. We have used user_data to store buffer when submitted callback + uint8_t* buf = (uint8_t*) xfer->user_data; + + if (xfer->result == XFER_RESULT_SUCCESS) + { + printf("[dev %u: ep %02x] HID Report:", xfer->daddr, xfer->ep_addr); + for(uint32_t i=0; iactual_len; i++) + { + if (i%16 == 0) printf("\r\n "); + printf("%02X ", buf[i]); + } + printf("\r\n"); + } + + // continue to submit transfer, with updated buffer + // other field remain the same + xfer->buflen = 64; + xfer->buffer = buf; + + tuh_edpt_xfer(xfer); +} + // count total length of an interface uint16_t count_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_t itf_count, uint16_t max_len); -void open_hid_interface(uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len) +void open_hid_interface(uint8_t daddr, tusb_desc_interface_t const *desc_itf, uint16_t max_len) { // len = interface + hid + n*endpoints uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); @@ -165,8 +220,11 @@ void open_hid_interface(uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, // HID descriptor p_desc = tu_desc_next(p_desc); + tusb_hid_descriptor_hid_t const *desc_hid = (tusb_hid_descriptor_hid_t const *) p_desc; + if(HID_DESC_TYPE_HID != desc_hid->bDescriptorType) return; // Endpoint descriptor + p_desc = tu_desc_next(p_desc); tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc; for(int i = 0; i < desc_itf->bNumEndpoints; i++) @@ -175,8 +233,30 @@ void open_hid_interface(uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, if(tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { - //usbh_edpt_open(rhport, dev_addr, desc_ep); + // skip if failed to open endpoint + if ( ! usbh_edpt_open(daddr, desc_ep) ) return; + + uint8_t* buf = get_hid_buf(daddr); + if (!buf) return; // out of memory + + tuh_xfer_t xfer = + { + .daddr = daddr, + .ep_addr = desc_ep->bEndpointAddress, + .buflen = 64, + .buffer = buf, + .complete_cb = hid_report_received, + .user_data = (uintptr_t) buf, // since buffer is not available in callback, use user data to store the buffer + }; + + // submit transfer for this EP + tuh_edpt_xfer(&xfer); + + printf("Listen to [dev %u: ep %02x]\r\n", daddr, desc_ep->bEndpointAddress); } + + p_desc = tu_desc_next(p_desc); + desc_ep = (tusb_desc_endpoint_t const *) p_desc; } } From 821be65b034bd69210834ae7400527149cb66e43 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 19 Mar 2022 14:59:31 +0700 Subject: [PATCH 264/504] rename usbh_edpt_open() to tuh_edpt_open() --- examples/host/bare_api/src/main.c | 2 +- src/class/cdc/cdc_host.c | 4 ++-- src/class/hid/hid_host.c | 2 +- src/class/msc/msc_host.c | 2 +- src/host/hub.c | 2 +- src/host/usbh.c | 2 +- src/host/usbh.h | 4 ++-- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index 3f3d1d488..fa50c7af3 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -234,7 +234,7 @@ void open_hid_interface(uint8_t daddr, tusb_desc_interface_t const *desc_itf, ui if(tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { // skip if failed to open endpoint - if ( ! usbh_edpt_open(daddr, desc_ep) ) return; + if ( ! tuh_edpt_open(daddr, desc_ep) ) return; uint8_t* buf = get_hid_buf(daddr); if (!buf) return; // out of memory diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 82cf911cf..044085e81 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -197,7 +197,7 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it // notification endpoint tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc; - TU_ASSERT( usbh_edpt_open(dev_addr, desc_ep) ); + TU_ASSERT( tuh_edpt_open(dev_addr, desc_ep) ); p_cdc->ep_notif = desc_ep->bEndpointAddress; drv_len += tu_desc_len(p_desc); @@ -218,7 +218,7 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) p_desc; TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && TUSB_XFER_BULK == desc_ep->bmAttributes.xfer); - TU_ASSERT(usbh_edpt_open(dev_addr, desc_ep)); + TU_ASSERT(tuh_edpt_open(dev_addr, desc_ep)); if ( tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN ) { diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 2280e87b4..ce3d1598c 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -356,7 +356,7 @@ bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *de for(int i = 0; i < desc_itf->bNumEndpoints; i++) { TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType); - TU_ASSERT( usbh_edpt_open(dev_addr, desc_ep) ); + TU_ASSERT( tuh_edpt_open(dev_addr, desc_ep) ); if(tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index 4033cc429..c54a63f37 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -379,7 +379,7 @@ bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *de for(uint32_t i=0; i<2; i++) { TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType && TUSB_XFER_BULK == ep_desc->bmAttributes.xfer); - TU_ASSERT(usbh_edpt_open(dev_addr, ep_desc)); + TU_ASSERT(tuh_edpt_open(dev_addr, ep_desc)); if ( tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN ) { diff --git a/src/host/hub.c b/src/host/hub.c index b4d369aca..9e546f6f7 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -201,7 +201,7 @@ bool hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && TUSB_XFER_INTERRUPT == desc_ep->bmAttributes.xfer, 0); - TU_ASSERT(usbh_edpt_open(dev_addr, desc_ep)); + TU_ASSERT(tuh_edpt_open(dev_addr, desc_ep)); hub_interface_t* p_hub = get_itf(dev_addr); diff --git a/src/host/usbh.c b/src/host/usbh.c index 466e5decd..f534070de 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -806,7 +806,7 @@ static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size) return hcd_edpt_open(usbh_get_rhport(dev_addr), dev_addr, &ep0_desc); } -bool usbh_edpt_open(uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep) +bool tuh_edpt_open(uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep) { TU_ASSERT( tu_edpt_validate(desc_ep, tuh_speed_get(dev_addr)) ); diff --git a/src/host/usbh.h b/src/host/usbh.h index a2df0153e..e883ac90b 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -135,8 +135,8 @@ bool tuh_control_xfer(tuh_xfer_t* xfer); // - sync : blocking if complete callback is NULL. bool tuh_edpt_xfer(tuh_xfer_t* xfer); -// Open an endpoint -bool usbh_edpt_open(uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep); +// Open an non-control endpoint +bool tuh_edpt_open(uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep); // Set Configuration (control transfer) // config_num = 0 will un-configure device. Note: config_num = config_descriptor_index + 1 From a270d8d6236124244f5a1447d57b35f4cfa4909c Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 19 Mar 2022 15:06:12 +0700 Subject: [PATCH 265/504] move code around --- examples/host/bare_api/src/main.c | 232 ++++++++++++++++-------------- 1 file changed, 123 insertions(+), 109 deletions(-) diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index fa50c7af3..eb3f7d8d7 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -37,6 +37,13 @@ // English #define LANGUAGE_ID 0x0409 +#define BUF_COUNT 4 + + +tusb_desc_device_t desc_device; + +uint8_t buf_pool[BUF_COUNT][64]; +uint8_t buf_owner[BUF_COUNT] = { 0 }; // device address that owns buffer //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES @@ -47,12 +54,8 @@ static void print_utf16(uint16_t *temp_buf, size_t buf_len); void print_device_descriptor(tuh_xfer_t* xfer); void parse_config_descriptor(uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg); -tusb_desc_device_t desc_device; - -#define BUF_COUNT 4 - -uint8_t buf_pool[BUF_COUNT][64]; -uint8_t buf_owner[BUF_COUNT] = { 0 }; // device address that owns buffer +uint8_t* get_hid_buf(uint8_t daddr); +void free_hid_buf(uint8_t daddr); /*------------- MAIN -------------*/ int main(void) @@ -88,6 +91,7 @@ void tuh_mount_cb (uint8_t daddr) void tuh_umount_cb(uint8_t daddr) { printf("Device removed, address = %d\r\n", daddr); + free_hid_buf(daddr); } //--------------------------------------------------------------------+ @@ -150,115 +154,14 @@ void print_device_descriptor(tuh_xfer_t* xfer) } } - //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ -// get an buffer from pool -uint8_t* get_hid_buf(uint8_t daddr) -{ - for(size_t i=0; ibuffer is NULL. We have used user_data to store buffer when submitted callback - uint8_t* buf = (uint8_t*) xfer->user_data; - - if (xfer->result == XFER_RESULT_SUCCESS) - { - printf("[dev %u: ep %02x] HID Report:", xfer->daddr, xfer->ep_addr); - for(uint32_t i=0; iactual_len; i++) - { - if (i%16 == 0) printf("\r\n "); - printf("%02X ", buf[i]); - } - printf("\r\n"); - } - - // continue to submit transfer, with updated buffer - // other field remain the same - xfer->buflen = 64; - xfer->buffer = buf; - - tuh_edpt_xfer(xfer); -} - // count total length of an interface uint16_t count_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_t itf_count, uint16_t max_len); -void open_hid_interface(uint8_t daddr, tusb_desc_interface_t const *desc_itf, uint16_t max_len) -{ - // len = interface + hid + n*endpoints - uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); - - // corrupted descriptor - if (max_len < drv_len) return; - - uint8_t const *p_desc = (uint8_t const *) desc_itf; - - // HID descriptor - p_desc = tu_desc_next(p_desc); - tusb_hid_descriptor_hid_t const *desc_hid = (tusb_hid_descriptor_hid_t const *) p_desc; - if(HID_DESC_TYPE_HID != desc_hid->bDescriptorType) return; - - // Endpoint descriptor - p_desc = tu_desc_next(p_desc); - tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc; - - for(int i = 0; i < desc_itf->bNumEndpoints; i++) - { - if (TUSB_DESC_ENDPOINT != desc_ep->bDescriptorType) return; - - if(tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) - { - // skip if failed to open endpoint - if ( ! tuh_edpt_open(daddr, desc_ep) ) return; - - uint8_t* buf = get_hid_buf(daddr); - if (!buf) return; // out of memory - - tuh_xfer_t xfer = - { - .daddr = daddr, - .ep_addr = desc_ep->bEndpointAddress, - .buflen = 64, - .buffer = buf, - .complete_cb = hid_report_received, - .user_data = (uintptr_t) buf, // since buffer is not available in callback, use user data to store the buffer - }; - - // submit transfer for this EP - tuh_edpt_xfer(&xfer); - - printf("Listen to [dev %u: ep %02x]\r\n", daddr, desc_ep->bEndpointAddress); - } - - p_desc = tu_desc_next(p_desc); - desc_ep = (tusb_desc_endpoint_t const *) p_desc; - } -} +void open_hid_interface(uint8_t daddr, tusb_desc_interface_t const *desc_itf, uint16_t max_len); // simple configuration parser to open and listen to HID Endpoint IN void parse_config_descriptor(uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg) @@ -330,6 +233,117 @@ uint16_t count_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_ return len; } +//--------------------------------------------------------------------+ +// HID Interface +//--------------------------------------------------------------------+ + +void hid_report_received(tuh_xfer_t* xfer); + +void open_hid_interface(uint8_t daddr, tusb_desc_interface_t const *desc_itf, uint16_t max_len) +{ + // len = interface + hid + n*endpoints + uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); + + // corrupted descriptor + if (max_len < drv_len) return; + + uint8_t const *p_desc = (uint8_t const *) desc_itf; + + // HID descriptor + p_desc = tu_desc_next(p_desc); + tusb_hid_descriptor_hid_t const *desc_hid = (tusb_hid_descriptor_hid_t const *) p_desc; + if(HID_DESC_TYPE_HID != desc_hid->bDescriptorType) return; + + // Endpoint descriptor + p_desc = tu_desc_next(p_desc); + tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc; + + for(int i = 0; i < desc_itf->bNumEndpoints; i++) + { + if (TUSB_DESC_ENDPOINT != desc_ep->bDescriptorType) return; + + if(tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) + { + // skip if failed to open endpoint + if ( ! tuh_edpt_open(daddr, desc_ep) ) return; + + uint8_t* buf = get_hid_buf(daddr); + if (!buf) return; // out of memory + + tuh_xfer_t xfer = + { + .daddr = daddr, + .ep_addr = desc_ep->bEndpointAddress, + .buflen = 64, + .buffer = buf, + .complete_cb = hid_report_received, + .user_data = (uintptr_t) buf, // since buffer is not available in callback, use user data to store the buffer + }; + + // submit transfer for this EP + tuh_edpt_xfer(&xfer); + + printf("Listen to [dev %u: ep %02x]\r\n", daddr, desc_ep->bEndpointAddress); + } + + p_desc = tu_desc_next(p_desc); + desc_ep = (tusb_desc_endpoint_t const *) p_desc; + } +} + +void hid_report_received(tuh_xfer_t* xfer) +{ + // Note: not all field in xfer is available for use (i.e filled by tinyusb stack) in callback to save sram + // For instance, xfer->buffer is NULL. We have used user_data to store buffer when submitted callback + uint8_t* buf = (uint8_t*) xfer->user_data; + + if (xfer->result == XFER_RESULT_SUCCESS) + { + printf("[dev %u: ep %02x] HID Report:", xfer->daddr, xfer->ep_addr); + for(uint32_t i=0; iactual_len; i++) + { + if (i%16 == 0) printf("\r\n "); + printf("%02X ", buf[i]); + } + printf("\r\n"); + } + + // continue to submit transfer, with updated buffer + // other field remain the same + xfer->buflen = 64; + xfer->buffer = buf; + + tuh_edpt_xfer(xfer); +} + +//--------------------------------------------------------------------+ +// Buffer helper +//--------------------------------------------------------------------+ + +// get an buffer from pool +uint8_t* get_hid_buf(uint8_t daddr) +{ + for(size_t i=0; i Date: Sat, 19 Mar 2022 13:37:54 +0100 Subject: [PATCH 266/504] Implement power of two, shift, and float calculation --- src/class/audio/audio_device.c | 68 ++++++++++++++++++++++++++++------ src/class/audio/audio_device.h | 4 +- src/common/tusb_common.h | 10 +++++ 3 files changed, 69 insertions(+), 13 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index f0cab4d93..a815f7557 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -308,11 +308,15 @@ typedef struct uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR - uint8_t n_frames; // Number of (micro)frames used to estimate feedback value - uint8_t n_frames_current; // Current (micro)frame number - uint32_t n_cycles_old; // Old cycle count - uint32_t feeback_param_factor_N; // Numerator of feedback parameter coefficient - uint32_t feeback_param_factor_D; // Denominator of feedback parameter coefficient + uint8_t n_frames; // Number of (micro)frames used to estimate feedback value + uint8_t n_frames_current; // Current (micro)frame number + uint32_t n_cycles_old; // Old cycle count + union { + uint32_t i; + float f; + } feedback_param_factor_N; // Numerator of feedback parameter coefficient + uint32_t feedback_param_factor_D; // Denominator of feedback parameter coefficient + uint32_t * feedback_param_p_cycle_count; // Pointer to cycle counter #endif #endif @@ -2010,14 +2014,39 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 // f_s max is 2^19-1 = 524287 Hz // n_frames_min is ceil(2^10 * f_s / f_m) for full speed and ceil(2^13 * f_s / f_m) for high speed // f_m max is 2^29/(1 ms * n_frames) for full speed and 2^29/(125 us * n_frames) for high speed -bool tud_audio_set_feedback_params_fm_fs(uint8_t func_id, uint32_t f_m, uint32_t f_s) +bool tud_audio_set_feedback_params_fm_fs(uint8_t func_id, uint32_t f_m, uint32_t f_s, uint32_t * p_cycle_count, bool use_float) { audiod_function_t* audio = &_audiod_fct[func_id]; + audio->feedback_param_p_cycle_count = p_cycle_count; uint8_t n_frame = 1; // TODO: finalize that audio->n_frames = n_frame; - audio->feeback_param_factor_N = f_s << 13; - audio->feeback_param_factor_D = f_m * n_frame; + + + + // Check if parameters reduce to a power of two shift i.e. is n_f * f_m / f_s a power of two? + if ((f_m % f_s) == 0 && tu_is_power_of_two(n_frame * f_m / f_s)) + { + audio->feedback_param_factor_N.i = 0; // zero marks power of two option + audio->feedback_param_factor_D = 16 - tu_log2(n_frame * f_m / f_s); + } + else + { + // Next best option is to use float if a FPU is available - this has to be enabled by the user + if (use_float) + { + audio->feedback_param_factor_N.f = (float)f_s / n_frame / f_m * (1 << 16); + audio->feedback_param_factor_D = 0; // non zero marks float option + } + else + { + // Neither a power of two or floats - use fixed point number + audio->feedback_param_factor_N.i = f_s << 13; + audio->feedback_param_factor_D = f_m * n_frame; + } + } + return true; + } #endif @@ -2044,10 +2073,27 @@ void audiod_sof (uint8_t rhport, uint32_t frame_count) audio->n_frames_current++; if (audio->n_frames_current == audio->n_frames) { - uint32_t n_cylces = tud_audio_n_get_fm_n_cycles_cb(rhport, audio->ep_fb); - uint32_t feedback = ((n_cylces - audio->n_cycles_old) << 3) * audio->feeback_param_factor_N / audio->feeback_param_factor_D; // feeback_param_factor_N has scaling factor of 13 bits, n_cycles 3 and feeback_param_factor_D 1, hence 16.16 precision + uint32_t n_cylces = *audio->feedback_param_p_cycle_count; + uint32_t feedback; - // TODO: Implement fast computation in case n_frames * f_s / f_m is a power of two + if (audio->feedback_param_factor_N.i == 0) + { + // Power of two shift + feedback = n_cylces << audio->feedback_param_factor_D; + } + else + { + if (audio->feedback_param_factor_D == 0) + { + // Float computation + feedback = (uint32_t)(n_cylces * audio->feedback_param_factor_N.f); + } + else + { + // Fixed point computation + feedback = ((n_cylces - audio->n_cycles_old) << 3) * audio->feedback_param_factor_N.i / audio->feedback_param_factor_D; // feeback_param_factor_N has scaling factor of 13 bits, n_cycles 3 and feeback_param_factor_D 1, hence 16.16 precision + } + } tud_audio_n_fb_set(i, feedback); audio->n_frames_current = 0; diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index eba8a6488..3645bda46 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -193,7 +193,7 @@ // Determine feedback value within SOF ISR within audio driver - if disabled the user has to call tud_audio_n_fb_set() with a suitable feedback value on its own. If done within audio driver SOF ISR, tud_audio_n_fb_set() is disabled for user #ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR -#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR 0 // 0 or 1 +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR 1 // 0 or 1 #endif // Audio interrupt control EP size - disabled if 0 @@ -487,7 +487,7 @@ TU_ATTR_WEAK uint32_t tud_audio_n_get_fm_n_cycles_cb(uint8_t rhport, uint8_t ep_ // f_m : Main clock frequency in Hz i.e. master clock to which sample clock is locked // f_s : Current sample rate in Hz -bool tud_audio_set_feedback_params_fm_fs(uint8_t func_id, uint32_t f_m, uint32_t f_s); +bool tud_audio_set_feedback_params_fm_fs(uint8_t func_id, uint32_t f_m, uint32_t f_s, uint32_t * p_cycle_count, bool use_float); #endif #endif diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 58591f0be..bcdf8933a 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -149,6 +149,16 @@ static inline uint8_t tu_log2(uint32_t value) return result; } +//static inline uint8_t tu_log2(uint32_t value) +//{ +// return sizeof(uint32_t) * CHAR_BIT - __builtin_clz(x) - 1; +//} + +static inline bool tu_is_power_of_two(uint32_t value) +{ + return (value != 0) && ((value & (value - 1)) == 0); +} + //------------- Unaligned Access -------------// #if TUP_ARCH_STRICT_ALIGN From ff2dc0a5471c3166a1995cc2abb5f42a8a9ab035 Mon Sep 17 00:00:00 2001 From: Reinhard Panhuber Date: Sun, 20 Mar 2022 11:21:33 +0100 Subject: [PATCH 267/504] Streamline feedback calc, find fb interval from descriptors, inc. checks --- src/class/audio/audio_device.c | 195 ++++++++++++++++++--------------- src/class/audio/audio_device.h | 28 ++++- 2 files changed, 135 insertions(+), 88 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index a815f7557..b97155823 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -305,18 +305,29 @@ typedef struct #endif #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP - uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). +#if !CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR + uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). +#endif #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR - uint8_t n_frames; // Number of (micro)frames used to estimate feedback value - uint8_t n_frames_current; // Current (micro)frame number - uint32_t n_cycles_old; // Old cycle count - union { - uint32_t i; - float f; - } feedback_param_factor_N; // Numerator of feedback parameter coefficient - uint32_t feedback_param_factor_D; // Denominator of feedback parameter coefficient - uint32_t * feedback_param_p_cycle_count; // Pointer to cycle counter + volatile uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). + uint8_t fb_n_frames; // Number of (micro)frames used to estimate feedback value + volatile uint8_t fb_n_frames_current; // Current (micro)frame number + volatile uint32_t fb_n_cycles_old; // Old cycle count + uint32_t * fb_param_p_cycle_count; // Pointer to cycle counter + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT + uint8_t fb_power_of_two_val; +#endif + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT + float fb_float_val; +#endif + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT + uint64_t fb_param_factor_N; // Numerator of feedback parameter coefficient + uint64_t fb_param_factor_D; // Denominator of feedback parameter coefficient +#endif #endif #endif @@ -1527,7 +1538,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * tu_fifo_clear(&audio->tx_supp_ff[cnt]); } #endif - + // Invoke callback - can be used to stop data sampling if (tud_audio_set_itf_close_EP_cb) TU_VERIFY(tud_audio_set_itf_close_EP_cb(rhport, p_request)); @@ -1560,7 +1571,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * // Close corresponding feedback EP #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP usbd_edpt_close(rhport, audio->ep_fb); - audio->ep_fb = 0; // Necessary? + audio->ep_fb = 0; #endif } #endif @@ -1677,8 +1688,9 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR usbd_sof_enable(rhport, true); // Enable SOF interrupt - audio->n_frames_current = 0; - audio->n_cycles_old = 0; + audio->fb_n_frames = desc_ep->bInterval; + audio->fb_n_frames_current = 0; + audio->fb_n_cycles_old = 0; #endif // Invoke callback after ep_out is set @@ -1711,12 +1723,12 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * bool disable = true; for(uint8_t i=0; i < CFG_TUD_AUDIO; i++) + { + if (_audiod_fct[i].ep_fb != 0) { - if (_audiod_fct[i].ep_fb != 0) - { - disable = false; - } + disable = false; } + } if (disable) usbd_sof_enable(rhport, false); @@ -2011,40 +2023,56 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 } #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR -// f_s max is 2^19-1 = 524287 Hz -// n_frames_min is ceil(2^10 * f_s / f_m) for full speed and ceil(2^13 * f_s / f_m) for high speed -// f_m max is 2^29/(1 ms * n_frames) for full speed and 2^29/(125 us * n_frames) for high speed -bool tud_audio_set_feedback_params_fm_fs(uint8_t func_id, uint32_t f_m, uint32_t f_s, uint32_t * p_cycle_count, bool use_float) + +// This function must be called from the user within the tud_audio_set_itf_cb(rhport, p_request) callback function, where p_request needs to be checked as +// uint8_t const itf = tu_u16_low(p_request->wIndex); +// uint8_t const alt = tu_u16_low(p_request->wValue); +// such that tud_audio_set_fb_params() gets called with the parameters corresponding to the defined interface and alternate setting +// Also, start the main clock cycle counter (or reset its value) within tud_audio_set_itf_cb() +TU_ATTR_WEAK bool tud_audio_set_fb_params(uint8_t func_id, uint32_t f_m, uint32_t f_s, uint32_t * p_cycle_count) { audiod_function_t* audio = &_audiod_fct[func_id]; - audio->feedback_param_p_cycle_count = p_cycle_count; - uint8_t n_frame = 1; // TODO: finalize that - audio->n_frames = n_frame; + audio->fb_param_p_cycle_count = p_cycle_count; + // Check if frame interval is within sane limits + // The interval value audio->fb_n_frames was taken from the descriptors within audiod_set_interface() - - // Check if parameters reduce to a power of two shift i.e. is n_f * f_m / f_s a power of two? - if ((f_m % f_s) == 0 && tu_is_power_of_two(n_frame * f_m / f_s)) + // n_frames_min is ceil(2^10 * f_s / f_m) for full speed and ceil(2^13 * f_s / f_m) for high speed - this lower limit ensures the measures feedback value has sufficient precision + if ((TUSB_SPEED_FULL == tud_speed_get() && ((2^10 * f_s / f_m) + 1) > audio->fb_n_frames) || (TUSB_SPEED_HIGH == tud_speed_get() && ((2^13 * f_s / f_m) + 1) > audio->fb_n_frames)) { - audio->feedback_param_factor_N.i = 0; // zero marks power of two option - audio->feedback_param_factor_D = 16 - tu_log2(n_frame * f_m / f_s); + TU_LOG2(" UAC2 feedback interval too small\r\n"); TU_BREAKPOINT(); return false; } - else + + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT + // Check if parameters really allow for a power of two division + if ((f_m % f_s) != 0 || !tu_is_power_of_two(audio->fb_n_frames * f_m / f_s)) { - // Next best option is to use float if a FPU is available - this has to be enabled by the user - if (use_float) - { - audio->feedback_param_factor_N.f = (float)f_s / n_frame / f_m * (1 << 16); - audio->feedback_param_factor_D = 0; // non zero marks float option - } - else - { - // Neither a power of two or floats - use fixed point number - audio->feedback_param_factor_N.i = f_s << 13; - audio->feedback_param_factor_D = f_m * n_frame; - } + TU_LOG2(" FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT not possible!\r\n"); TU_BREAKPOINT(); return false; } + audio->fb_power_of_two_val = 16 - tu_log2(audio->fb_n_frames * f_m / f_s); +#endif + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT + audio->fb_float_val = (float)f_s / audio->fb_n_frames / f_m * (1 << 16); +#endif + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT + + // f_s max is 2^19-1 = 524287 Hz + // f_m max is 2^29/(1 ms * n_frames) for full speed and 2^29/(125 us * n_frames) for high speed, this means for f_m fitting in an uint32, n_frames must be < 125 for full speed and < 1000 for high speed (1000 does not fit into uint8 so the maximum possible value cannot even be reached by UAC2 - we don't need to check for it) + + if ((f_s > (2^19)-1) || (TUSB_SPEED_FULL == tud_speed_get() && (audio->fb_n_frames > 125))) + { + // If this check fails, not every thing is lost - you need to re-evaluate the scaling factors of the parameters such that the numbers fit into uint64 again. feedback = n_cycles * S_c / (n_frames * S_n) * f_s * S_s / (f_m * S_m). In the end S_c*S_s / (S_n * S_m) = 2^16 for a 16.16 fixed point precision. If you find something, define your own function of tud_audio_set_feedback_params_fm_fs() and audiod_sof() and use your values + TU_LOG2(" FEEDBACK_DETERMINATION_MODE_FIXED_POINT not possible!\r\n"); TU_BREAKPOINT(); return false; + } + + audio->fb_param_factor_N = (uint64_t)f_s << 13; + audio->fb_param_factor_D = (uint64_t)f_m * audio->fb_n_frames; +#endif + return true; } @@ -2053,54 +2081,47 @@ bool tud_audio_set_feedback_params_fm_fs(uint8_t func_id, uint32_t f_m, uint32_t void audiod_sof (uint8_t rhport, uint32_t frame_count) { (void) rhport; - (void) frame_count; + (void) frame_count; // frame_count is not used since some devices may not provide the frame count value #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR // Determine feedback value - The feedback method is described in 5.12.4.2 of the USB 2.0 spec // Boiled down, the feedback value Ff = n_samples / (micro)frame. - // Since an accuracy of less than 1 Sample / second is desired, at least n_frames = ceil(2^K * f_s / f_m) frames need to be measured, where K = 10 for full speed and K = 13 for high speed, f_s is the sampling frequency e.g. 48 kHz and f_cpu is the cpu clock frequency e.g. 100 MHz (or any other master clock whose clock count is available and locked to f_s) - // The update interval in the (4.10.2.1) Feedback Endpoint Descriptor must be less or equal to 2^(K - P), where P = min( ceil(log2(f_cpu / f_s)), K) - // Ff = n_cycles / n_frames * f_s / f_cpu in 16.16 format, where n_cycles are the number of CPU cycles within n_frames + // Since an accuracy of less than 1 Sample / second is desired, at least n_frames = ceil(2^K * f_s / f_m) frames need to be measured, where K = 10 for full speed and K = 13 for high speed, f_s is the sampling frequency e.g. 48 kHz and f_m is the cpu clock frequency e.g. 100 MHz (or any other master clock whose clock count is available and locked to f_s) + // The update interval in the (4.10.2.1) Feedback Endpoint Descriptor must be less or equal to 2^(K - P), where P = min( ceil(log2(f_m / f_s)), K) + // feedback = n_cycles / n_frames * f_s / f_m in 16.16 format, where n_cycles are the number of main clock cycles within fb_n_frames // Iterate over audio functions and set feedback value for(uint8_t i=0; i < CFG_TUD_AUDIO; i++) + { + audiod_function_t* audio = &_audiod_fct[i]; + + if (audio->ep_fb != 0) { - audiod_function_t* audio = &_audiod_fct[i]; - - if (audio->ep_fb != 0) + audio->fb_n_frames_current++; + if (audio->fb_n_frames_current == audio->fb_n_frames) { - audio->n_frames_current++; - if (audio->n_frames_current == audio->n_frames) - { - uint32_t n_cylces = *audio->feedback_param_p_cycle_count; - uint32_t feedback; + uint32_t n_cylces = *audio->fb_param_p_cycle_count; + uint32_t feedback; - if (audio->feedback_param_factor_N.i == 0) - { - // Power of two shift - feedback = n_cylces << audio->feedback_param_factor_D; - } - else - { - if (audio->feedback_param_factor_D == 0) - { - // Float computation - feedback = (uint32_t)(n_cylces * audio->feedback_param_factor_N.f); - } - else - { - // Fixed point computation - feedback = ((n_cylces - audio->n_cycles_old) << 3) * audio->feedback_param_factor_N.i / audio->feedback_param_factor_D; // feeback_param_factor_N has scaling factor of 13 bits, n_cycles 3 and feeback_param_factor_D 1, hence 16.16 precision - } - } +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT + feedback = (n_cylces - audio->fb_n_cycles_old) << audio->fb_power_of_two_val; +#endif - tud_audio_n_fb_set(i, feedback); - audio->n_frames_current = 0; - audio->n_cycles_old = n_cylces; - } +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT + feedback = (uint32_t)((float)(n_cylces - audio->fb_n_cycles_old) * audio->fb_float_val); +#endif + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT + feedback = ((n_cylces - audio->fb_n_cycles_old) << 3) * audio->fb_param_factor_N / audio->fb_param_factor_D; // feeback_param_factor_N has scaling factor of 13 bits, n_cycles 3 and feeback_param_factor_D 1, hence 16.16 precision +#endif + + tud_audio_n_fb_set(i, feedback); + audio->fb_n_frames_current = 0; + audio->fb_n_cycles_old = n_cylces; } } + } #endif } @@ -2299,6 +2320,16 @@ static bool audiod_verify_ep_exists(uint8_t ep, uint8_t *func_id) // Currently, only AS interfaces with an EP (in or out) are supposed to be parsed for! static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * p_desc, uint8_t const * p_desc_end, uint8_t const as_itf) { +#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_EP_OUT + if (as_itf != audio->ep_in_as_intf_num && as_itf != audio->ep_out_as_intf_num) return; // Abort, this interface has no EP, this driver does not support this currently +#endif +#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_EP_OUT + if (as_itf != audio->ep_in_as_intf_num) return; +#endif +#if !CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_EP_OUT + if (as_itf != audio->ep_out_as_intf_num) return; +#endif + p_desc = tu_desc_next(p_desc); // Exclude standard AS interface descriptor of current alternate interface descriptor while (p_desc < p_desc_end) @@ -2309,16 +2340,6 @@ static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * // Look for a Class-Specific AS Interface Descriptor(4.9.2) to verify format type and format and also to get number of physical channels if (tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE && tu_desc_subtype(p_desc) == AUDIO_CS_AS_INTERFACE_AS_GENERAL) { -#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_EP_OUT - if (as_itf != audio->ep_in_as_intf_num && as_itf != audio->ep_out_as_intf_num) break; // Abort loop, this interface has no EP, this driver does not support this currently -#endif -#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_EP_OUT - if (as_itf != audio->ep_in_as_intf_num) break; -#endif -#if !CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_EP_OUT - if (as_itf != audio->ep_out_as_intf_num) break; -#endif - #if CFG_TUD_AUDIO_ENABLE_EP_IN if (as_itf == audio->ep_in_as_intf_num) { diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index 3645bda46..f1bb084d6 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -196,6 +196,25 @@ #define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR 1 // 0 or 1 #endif +// Feeback calculation mode +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR + +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT 1 +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT 2 +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT 3 + +#ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE +#error You must tell the driver the feedback determination mode! Possible choices are: CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT, CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT, or CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT! +#endif + +#ifdef CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE +#if (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE != CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE != CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE != CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT) +#error Unknown CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE. Possible choices are: CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT, CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT, or CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT! +#endif +#endif + +#endif + // Audio interrupt control EP size - disabled if 0 #ifndef CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN #define CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN 0 // Audio interrupt control - if required - 6 Bytes according to UAC 2 specification (p. 74) @@ -487,7 +506,14 @@ TU_ATTR_WEAK uint32_t tud_audio_n_get_fm_n_cycles_cb(uint8_t rhport, uint8_t ep_ // f_m : Main clock frequency in Hz i.e. master clock to which sample clock is locked // f_s : Current sample rate in Hz -bool tud_audio_set_feedback_params_fm_fs(uint8_t func_id, uint32_t f_m, uint32_t f_s, uint32_t * p_cycle_count, bool use_float); +// p_cycle_count : Pointer to main clock cycle counter register where the current count can be read from (e.g. a timer register) + +// This function must be called from the user within the tud_audio_set_itf_cb(rhport, p_request) callback function, where p_request needs to be checked as +// uint8_t const itf = tu_u16_low(p_request->wIndex); +// uint8_t const alt = tu_u16_low(p_request->wValue); +// such that tud_audio_set_fb_params() gets called with the parameters corresponding to the defined interface and alternate setting +// Also, start the main clock cycle counter (or reset its value) within tud_audio_set_itf_cb() +TU_ATTR_WEAK bool tud_audio_set_fb_params(uint8_t func_id, uint32_t f_m, uint32_t f_s, uint32_t * p_cycle_count); #endif #endif From 5aba4642707e8885b9d10837ac60fb0724d3503f Mon Sep 17 00:00:00 2001 From: Reinhard Panhuber Date: Sun, 20 Mar 2022 12:04:10 +0100 Subject: [PATCH 268/504] Add magic checks --- src/class/audio/audio_device.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index b97155823..386e0ba21 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -2116,6 +2116,16 @@ void audiod_sof (uint8_t rhport, uint32_t frame_count) feedback = ((n_cylces - audio->fb_n_cycles_old) << 3) * audio->fb_param_factor_N / audio->fb_param_factor_D; // feeback_param_factor_N has scaling factor of 13 bits, n_cycles 3 and feeback_param_factor_D 1, hence 16.16 precision #endif + // Buffer count checks ? + + // Magic checks + if (feedback > 2949166){ // 45.0007 in 16.16 format + feedback = 2949166; + } + if ( feedback < 2883630) { // 44.0007 in 16.16 format + feedback = 2883630; + } + tud_audio_n_fb_set(i, feedback); audio->fb_n_frames_current = 0; audio->fb_n_cycles_old = n_cylces; From 8ffdbfebce56c709b1c2c2396498e9fc32555a77 Mon Sep 17 00:00:00 2001 From: Reinhard Panhuber Date: Sun, 20 Mar 2022 12:08:27 +0100 Subject: [PATCH 269/504] Streamline call of tud_audio_set_itf_cb() within audiod_set_interface() --- src/class/audio/audio_device.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 386e0ba21..434bfdcc6 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -1631,7 +1631,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * #endif // Invoke callback - can be used to trigger data sampling if not already running - if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); +// if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); // Schedule first transmit if alternate interface is not zero i.e. streaming is disabled - in case no sample data is available a ZLP is loaded // It is necessary to trigger this here since the refill is done with an RX FIFO empty interrupt which can only trigger if something was in there @@ -1665,10 +1665,10 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // In case of asynchronous EP, call Cb after ep_fb is set - if ( !(desc_ep->bmAttributes.sync == 0x01 && audio->ep_fb == 0) ) - { - if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); - } +// if ( !(desc_ep->bmAttributes.sync == 0x01 && audio->ep_fb == 0) ) +// { +// if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); +// } #else // Invoke callback if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); @@ -1693,11 +1693,11 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * audio->fb_n_cycles_old = 0; #endif - // Invoke callback after ep_out is set - if (audio->ep_out != 0) - { - if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); - } +// // Invoke callback after ep_out is set +// if (audio->ep_out != 0) +// { +// if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); +// } } #endif #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT @@ -1709,6 +1709,9 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * TU_VERIFY(foundEPs == nEps); + // Invoke one callback for a final set interface + if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); + // We are done - abort loop break; } @@ -2118,7 +2121,7 @@ void audiod_sof (uint8_t rhport, uint32_t frame_count) // Buffer count checks ? - // Magic checks + // Magic checks - where are they from? if (feedback > 2949166){ // 45.0007 in 16.16 format feedback = 2949166; } From 5cd67baf15aa24c5f5eae18b9f9615e3af807704 Mon Sep 17 00:00:00 2001 From: Reinhard Panhuber Date: Sun, 20 Mar 2022 12:57:53 +0100 Subject: [PATCH 270/504] Disable SOF ISR feedback calcuation by default s.t. examples still work --- src/class/audio/audio_device.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index f1bb084d6..e5eaed9c7 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -193,7 +193,7 @@ // Determine feedback value within SOF ISR within audio driver - if disabled the user has to call tud_audio_n_fb_set() with a suitable feedback value on its own. If done within audio driver SOF ISR, tud_audio_n_fb_set() is disabled for user #ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR -#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR 1 // 0 or 1 +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR 0 // 0 or 1 #endif // Feeback calculation mode From 735300b53cf519b58576b3746ec48ae163df327f Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 28 Mar 2022 12:47:32 +0700 Subject: [PATCH 271/504] remove cxd56 __pycache-_ folder --- .../tools/__pycache__/xmodem.cpython-36.pyc | Bin 15257 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 hw/mcu/sony/cxd56/tools/__pycache__/xmodem.cpython-36.pyc diff --git a/hw/mcu/sony/cxd56/tools/__pycache__/xmodem.cpython-36.pyc b/hw/mcu/sony/cxd56/tools/__pycache__/xmodem.cpython-36.pyc deleted file mode 100644 index cfa917f71d3dbe945ac710d5b292db2daa36426e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15257 zcmeHO2Y4LSwVtxOT8&o4w%iR2V6Ya{ZNMl-*p_85*s>#uwv_c~&q!Kni!?K9Nt;zd zA`?s!6Q_rS^g>AQJ*0>9O4_6Y2~m1NDoODB&z;#K*~agSpWpYr?|UoHKX+zsJ@>!& zo^$T?#@bq~Wgxi!b9*J}A*tdQKzJ)I+XavmlSq!qq>wtI#1sm|R0_rd6r!qBFcuW| zP%I?wRk14E!>Mq(I#w-9;++=L%-~oJRnN(>h*?Y8h>TDjLNy{(k5EK}8W5@#p(O~_ ziO^Dn>P2W7LJcC+h|m%dT7HE@OKI6biI$lw=G53qv)WuqjkNr*5?e(pXyrjEw%S}n ztHu@UJ7(3`T66WBG$*5GRRdCVwJ~2ON!n#k{L}R7_w3!#yGI{RrcB+jjEp^OTKa^Q zb+UZHlF)>eJ}E?Tc?gQH1X$3H_)B^}c;QhG8ykuuX}#xa~^Hlt^U{jypIuOEyz z`wtygi$~qakj7Qn)6?JMN3e4f6IsjAhqIP`gI7z$(qmo_MNOC)N@hk{i(l>0Y%WFG zkf{$FNh>v@n}$83JK1tgbOUvCylRdbiE$nEakG zZRO{R&z?joBY1C0QHmleM=8G1v>hl-A5LYbbaUEZ`RmC{B9&t?>852tl9rjs9x$z$ zlXYzcZ#3;n(?U+%xwe<9FEDPLD6Sb&5}ko48(W4_S;!W`u#FM3RoexLi&{WBEM{ja ztEaQJqbIWIGG%!w_U-8H=g`T2{k=WCyRPl+_fnobz87OlON-vO?P{;Iy;th(9s15*ojdnNRQ6__ z+qXEcmX>Z2fARYhJ#!flX}OF}edmtTUB*UzXV2*_W0Ssf`{^#@B7NsJzl`>F^vAwE zy?b}wxS(rJr9XQ24xXsn7QFvY%kY`s(lPFHzFEiU!Js7b1nlP_@xMI+dOU6pUcZ3< z?VXz-aMYHsir;@K3(jJI%c$W0X)B|G|Lv8;sc6!vwBxk%W>0b&Gjj*z!z;F4nmM=g zjDMn;vpAjpKYvc8ZwGiCsNj#7Y>piU`YD%DF@IK4l$V`iai>zoY3Hb~D{eQO#Hc>V zDs4Jx+pK~PKqKLMQ-@I4qE9f_6**hHpCWfF=Bbkgd13C+n^-x*80)fzqUANZUEjGA zif6Vpq4!<08_K}OieB+@K9#;XY2Ew?qKf5OE!IwoG^xn$RB9!dkJ)*F=5RX7!00M! z4*%DfU(^;)_votV(vt=ku|#m!V{PSJQkl(v$`Vb>pL<<$EW>Nko-C1RVd&^v(nj9g zIx*vnwr5(i)<}1LeNT2`#!8NiIv8J3y|cZeT|XvW{_KUZIxgMZq4$jDVAAZ&TK14> zjl|SFy9V>Y_STK9o%8S`NPSV+t(q__CuyYI&@?Mj>3JC+<`o8ZI?RU{8W@%{tYYW^ zByg2~NVFACb^!@Z39bnVZV4G~3AiXIK*A+KVX7vLYA8Z*B~U#z&=PhPuycSN1GI`( z(;8Y!>*x$Rlg=WY&ZcwdTv|`((fPE2nkY&a(1p}YE!0YF)J`4LNgHVsT|^htCA66? zr7n6BZK2Dkn=YrVw2ih?5AC2{+DTW?m9&elqN`~)?V&!}OZ(`_)K3F6NY~J{bRAt! zH&Bdjq?_nwx`pDjp9~tJ1fgeWm_}%nk~Bu+l%h0cC`%JGNfz1UP>v4J6iw3%<>@I@ zpjmn`{?8J3Hl^`iat%Bq0iFi=zjVYA>3Evs>M}@=PKOS;97!fDV{mrT3pL;HR8D%_jS0I<641d4fn`^)N}@z z=!QHK*|-I46!X1rGVk*pMEWR(T*|bX;cu8Q6ENX1?y^H;2(shFG7Zv)t!!FoiXeiMTiGeoM(aV?rxpTVK(j)O?EPGHtS9@ZDw=MWgXEj5v3Jw6#iMJle03yxxyBI zUp8YFzc0vYB8RNlOL5YyxV#f)CC0OUneQNK;tDqFoOe|7s@{dMZ=^-dyY!v8OhUN4 zgajPROdcpYk33oEHeMQOQPVDGX2SFnCX7_d7)p6f@w4Po7G^2DbZNM;Jbx4lfm>#A zhF-GcWyo#m@>^1J^m(QqOV+E87YVt-$>LShYv6=IUHU$QghMGYibf~k?BlLZ8{_Co zcv&XkS2IC`w9voGZ*-P$MUzEVoP{Sri)YK^*_a=b+jT&q9dHm+Ve$?80H50rcw_<) zemWrfJit}20gS&3@SINq-u4Z^SAPch{T~4xO92hwZPM-p^q&KGUq9f5+W~*G0N)t` zT>1jQsyV<@-UEoe4)C#W0q*`Z;OL`(A3p>bS`X;i1kf>^C*?-KF9>kI19<%oz-@zo zu{Qv&ejlLeHbC`@0KfY=;A?*Yy!Eqy!`}uBTnw zoq!uZ0Lb41Sp5>f=Gy^3`5WNzM*y$*F5sj013q&l;OEx^o;eD*XBx0I3^1_LB$Xz> zxtjrB{sQ2)-v``@r7QW4e*mt$1CYE6pxq0&@I!#V!~hRm1^7T7@ZvGRK4HM z2w>Yfz}tTdc<#RezxfK_D?b8U@HRlr#{i>;0lQuSc*#=%@6Q0feGA~veSl@%fX-IH zlg|W9zyqFq)ltBGzX$y2CxCx_4Y2m(fUb7{Zg>@7`niBZOsRXBTwi2L{hG-YVM?_y zx%!w=Sti%5py)h4O36<#MIU0a2AHDfF+{j zrqnG=u6HSbBTUvu&jEas$$HUtKqHfNY6x&Gll50jsV_0P-o%u;gUOX)O6_HGH8Z7Z znOqMtML)eB@M@;$(*uBErsx#}SkDv8NvuDfmre2~c%e+2MUCf6DF1GX@^ zzQq*%6O;9MOwo5TS+8S?9$>OAXNqoOvhHR|rI}oHOsO^|*XNm1^GvR1F{R$ZnE6^KVz~!gDLttChIIy>Lw=FoRWZ>brNHU zw~|U*Io{4r&$hneUI54CpICA@RHg&sBJSX(3=g%L!AJQ$40p_%NhfsJ5O@)dSe} zoUP6@IyGYv(wy3YHYX3uE5x>A0o$XONV8Ris)8~ew6>$R#*?8f`$&I-;;#98jFs9h!T)@$({ z=ZM%`+I#&p^;CEHf;i5qLOs=PExpS$6k}H8gdQlUs5$z;SuJYzc%eqLtj1YW2s&%W z*3EH!|5XSUB88el)to9?FM8{UVht8$TM=8aE~t#{Nga7yjPgrzhb+&adTs^xz!7=! z;>@7vy9UuRzsDBjdh35P*Cmy?E-EuZON(C%wG>*3E$kK2Z0+R3*GbdY3i+HV$`{;R zAQ{E_J9yb#Y_H!c#d=^-31?7av4kVa zoLSxn>=z~s?{jL`;F`2^iG*nn=ThEge9?0$b~SezDVrlEGkU_XVXX|8T8a(t zRL;U)Yw3+|K6v%$(g&fL`^_qwXIxXyhGM&iHh!~ck=TtFTe6sxd6zzAQmNFUJiWVTM(9H(78y4cwL&XB0hlmQcp&lVW4CT++b67@ z=?sH(aYahS9j7XjxuofI>AQyY_GUhPAh?2a2$^AsB#T~wyUK!DiwGSe0%akuOxBNy z)oVsXUR!;y8ymynvDn(8l|q50^~TQNw`|FE-{+*lvg^g);@* zb~`zeF<^U}sBrPfN6t2xu#n}6b0}`u+c*u9v%z&3rB3TFg%s!9zm)!XwU9Fu}yut35^m zpQZ2~Dh7iXHpLveL|!Fxo(q`26>EEvHJYd*^gTE1HN0ayziwLwy?nq(B}vR9`V=~a zkHDmoCJC*?Vm%@s!2u3-D3H!diR=b=SnkZ9E5>qffB)Wo-xY%xa0<6!&!$-)0h!LT zqq4P@v#8;?+?j9|&qINg=2eg*@;FlQ6Ic6{S zf~#F?q;g(Z=(nzlnn7pl@3B^+U2aeeI9Ii2Y&YbMHdjq$N8F&OsjFr!vRJ!z1MIJI z13WU_U}`LfnU6JOH;g__#1mG+t@T3wK@wj(#QubZ9S4Wp z8XToc!6k;hC)*A8_+Fk^)s$gn&=0N(8AKaA{Sq}~-w^aqo>N7Kxj`}1MK#2@c56Id z#@VIf)>M!YajZmK=>4Gtmz{D0>|=@5E+BBMb^*QJa8WUaoZ&2URphc*p@jjFp>IMQ z_I&{9EJfzOkQ|Zg-6X!OG zab@ukNK|pl@Z(-*YorI4{QyiblA%+}(5YqU)E|XbqC&%kr8p)P0;C8HR~>+1#+n** z-oRRETtZk_Cv&pxIO$#LuY@JAFf9DK4|M7B-Ds)0K_Pzgr4NJM1%J2Y2j!QYvHgIygdKR zUy#?sct*a^C~+9F^hOhJ&J-=H5$(~??y!SW5p#0^d0CyMk{>R>8*TSH5emar2+zq* z-B>+UABJ{YtdlRxhgp_$m=QQF>xq6ntC3E~fwl5k9I&i>UM0a6s4YZLwqo5~s4In# z0{V4uC3*xGOR&DcaaJKUc1u>nUZI+9Njxp#ru`Cx`wSkYQP-4d#YB~e?b8&>_AGZzH|Cm)1#A?4_D z1IJj)+H$|QuwXUzHNO8Lg?Z{^3Nu!;1IJaEJ2!6XENiqyg_&K-WsS~rf|nM>k_v5m zCjoh9;3O(Dugv@ti>$v!_6cW%H#3}tNkA;xc_@mB1Nx#x7PEgF=5MjcBK6sbZJon# zE+D^@&rCF(*S=|5-_ot~J(@2cL~JS^NkoiJKSt+t)LPF;{dHVuUBx4)=V5sii#fHO zNAr&#J$iH=*HP;#F7WCiL|2IQ%yaZa@zxEng6anClxa>_O&m{nf-d3^TzisODJ}NB zSa85e7QAMX)y8lk13X`n)dFyXWDeyh382uX4W=-4WAg0lrfS25}f~v%7G4ZG7FOj$DE-nI@yx;?J4Iv%mrW1sW2;fps9>s;W$R}6Q!BTS}B5g&2h>ab+NQjbGqr+FB{sYHzqceCkQcY;JQakLAC|qpPA_566^M<|6{#L0b-{>m{3z}ByChj8k*@Jd<0c)zUU;R+)qc58u?S+>rsJ_QW08Gm}Uq6ENZkHV?G9 z85~2v5$2QhYpEX>^{;PqpL>X$BkX;Mhjb`+<&1OBVWH#SHaV?oi=dtr~Xlv%)O+;MpQ$jn7)i;ed4phvAl&e1~wbtR;#l-Xrpd-@UkSh^HEMdGr4S zh{s(m&Z>AW#oP@rdhKUe+mo0V@ zAHrp0<4Fpy48Xg5Dt~L#hEPLQ!_y?aVY;DKE!DlU6F+6&*b zl#*t>yL<=pULp2Y%d_y(k5!ylIUImKBaa2YZF>)hzT`ys1InE1(fpJJrxV!vzH%?v;mC_RWsf6sq~`%wc5~p|J?-qnVgr z0&AJF)h+T~^8|UXJwe{J$L1}zZO-Tu{K>bS2lIGDzi~@;LKuqOH|ty2JSp%3(Jfq& zOrBBzwtq0k|G^@!w50Q)mKL6ig;yberZ;(ceuO5^#n9~gSUSd|7*SR5br`vn;|4HU zPt0?F=9d)R4~8|8HasEn_K3Y3;F01EpA@r-14>;#@)-1SSP{WYfTY40o#?c?+e8eFPI$G=%*$*xsIQBTu=q0ZhpPqs$k{m}+=xgibf63Wh6v7?A9kf?pXbx&zl7 zm>1la#s6<}1N(OE>$S#_kCg)O(De@nW0N;IVWRn>RVA^y!8pIal&db5KGrtn#Z~4g zF~!d3!!0e|{2*38SD6~}=X_zlAj~R!OtJDVc#V!MO$O0AH;kDI$AWBAR3R4GD<-ae z;!RA$A)&Z8mARUT700|{d(^@9x8y3xtQ+7)dh3nYkmjWiTdb)pGUcM85zFCMA+H>_ z%AXwFfXHkN->gZ70}R5ZVK#Xt2+wLPSoSyz-W7!!XgRFXg_oW;)GcO}g;NYttQu3oZbXIC zj}0>G5{8QyxE*B^E~f6--Rqfp>;<)=05_BsNArZhV_|QV=olBxu&(0>0dqR(ROrTK rT7|cGs!TW2P{=F*%ZD9+u#SXV&vWdtowVRjg<8RXazqX92+RKk`88&w From 65b6b79e9954c4b8edceea040aba1a8fd80e975c Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 29 Mar 2022 16:53:45 +0700 Subject: [PATCH 272/504] clean up and comment out tud_sof_isr_set --- src/device/usbd.c | 61 +++++++++++++++++++------------------------ src/device/usbd.h | 2 +- src/device/usbd_pvt.h | 2 +- src/tusb_option.h | 2 +- 4 files changed, 30 insertions(+), 37 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 96ac19c8d..8ab67c8de 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -98,7 +98,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = cdcd_open, .control_xfer_cb = cdcd_control_xfer_cb, .xfer_cb = cdcd_xfer_cb, - .sof = NULL + .sof_isr = NULL }, #endif @@ -110,7 +110,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = mscd_open, .control_xfer_cb = mscd_control_xfer_cb, .xfer_cb = mscd_xfer_cb, - .sof = NULL + .sof_isr = NULL }, #endif @@ -122,7 +122,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = hidd_open, .control_xfer_cb = hidd_control_xfer_cb, .xfer_cb = hidd_xfer_cb, - .sof = NULL + .sof_isr = NULL }, #endif @@ -134,7 +134,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = audiod_open, .control_xfer_cb = audiod_control_xfer_cb, .xfer_cb = audiod_xfer_cb, - .sof = audiod_sof + .sof_isr = audiod_sof }, #endif @@ -146,7 +146,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = videod_open, .control_xfer_cb = videod_control_xfer_cb, .xfer_cb = videod_xfer_cb, - .sof = NULL + .sof_isr = NULL }, #endif @@ -158,7 +158,7 @@ static usbd_class_driver_t const _usbd_driver[] = .reset = midid_reset, .control_xfer_cb = midid_control_xfer_cb, .xfer_cb = midid_xfer_cb, - .sof = NULL + .sof_isr = NULL }, #endif @@ -170,7 +170,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = vendord_open, .control_xfer_cb = tud_vendor_control_xfer_cb, .xfer_cb = vendord_xfer_cb, - .sof = NULL + .sof_isr = NULL }, #endif @@ -182,7 +182,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = usbtmcd_open_cb, .control_xfer_cb = usbtmcd_control_xfer_cb, .xfer_cb = usbtmcd_xfer_cb, - .sof = NULL + .sof_isr = NULL }, #endif @@ -194,7 +194,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = dfu_rtd_open, .control_xfer_cb = dfu_rtd_control_xfer_cb, .xfer_cb = NULL, - .sof = NULL + .sof_isr = NULL }, #endif @@ -206,7 +206,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = dfu_moded_open, .control_xfer_cb = dfu_moded_control_xfer_cb, .xfer_cb = NULL, - .sof = NULL + .sof_isr = NULL }, #endif @@ -218,7 +218,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = netd_open, .control_xfer_cb = netd_control_xfer_cb, .xfer_cb = netd_xfer_cb, - .sof = NULL, + .sof_isr = NULL, }, #endif @@ -230,7 +230,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = btd_open, .control_xfer_cb = btd_control_xfer_cb, .xfer_cb = btd_xfer_cb, - .sof = NULL + .sof_isr = NULL }, #endif }; @@ -264,7 +264,7 @@ static inline usbd_class_driver_t const * get_driver(uint8_t drvid) // DCD Event //--------------------------------------------------------------------+ -static tud_sof_isr_t _sof_isr = NULL; +//static tud_sof_isr_t _sof_isr = NULL; enum { RHPORT_INVALID = 0xFFu }; static uint8_t _usbd_rhport = RHPORT_INVALID; @@ -373,11 +373,11 @@ bool tud_connect(void) return true; } -void tud_sof_isr_set(tud_sof_isr_t sof_isr) -{ - _sof_isr = sof_isr; - dcd_sof_enable(_usbd_rhport, _sof_isr != NULL); -} +//void tud_sof_isr_set(tud_sof_isr_t sof_isr) +//{ +// _sof_isr = sof_isr; +// dcd_sof_enable(_usbd_rhport, _sof_isr != NULL); +//} //--------------------------------------------------------------------+ // USBD Task @@ -422,7 +422,7 @@ bool tud_init (uint8_t rhport) } _usbd_rhport = rhport; - _sof_isr = NULL; + //_sof_isr = NULL; // Init device controller driver dcd_init(rhport); @@ -585,21 +585,12 @@ void tud_task (void) } break; - case DCD_EVENT_SOF: - TU_LOG2("\r\n"); - // TODO: Should this really be done here in the queue? How to distinguish the calls here from those SOF events which should be handled directly in the ISR routine? If we do it like this, the SOF routines get called two time right now, once in the ISR context and once again here -// for ( uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++ ) -// { -// usbd_class_driver_t const * driver = get_driver(i); -// if ( driver->sof ) driver->sof(event.rhport, event.sof.frame_count); -// } - break; - case USBD_EVENT_FUNC_CALL: TU_LOG2("\r\n"); if ( event.func_call.func ) event.func_call.func(event.func_call.param); break; + case DCD_EVENT_SOF: default: TU_BREAKPOINT(); break; @@ -1114,15 +1105,14 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr) for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { usbd_class_driver_t const * driver = get_driver(i); - if (driver->sof) + if (driver->sof_isr) { - driver->sof(event->rhport, event->sof.frame_count); - // TU_LOG2("%s sof\r\n", driver->name); // too demanding + driver->sof_isr(event->rhport, event->sof.frame_count); } } // SOF user handler in ISR context - if (_sof_isr) _sof_isr(event->sof.frame_count); + // if (_sof_isr) _sof_isr(event->sof.frame_count); // Some MCUs after running dcd_remote_wakeup() does not have way to detect the end of remote wakeup // which last 1-15 ms. DCD can use SOF as a clear indicator that bus is back to operational @@ -1133,6 +1123,8 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr) dcd_event_t const event_resume = { .rhport = event->rhport, .event_id = DCD_EVENT_RESUME }; osal_queue_send(_usbd_q, &event_resume, in_isr); } + + // skip osal queue for SOF in usbd task break; default: @@ -1411,7 +1403,8 @@ void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr) void usbd_sof_enable(uint8_t rhport, bool en) { - // TODO: Check needed if all drivers including the user sof_cb does not need an active SOF ISR any more. Only if all drivers switched off SOF calls the SOF interrupt may be disabled + // TODO: Check needed if all drivers including the user sof_cb does not need an active SOF ISR any more. + // Only if all drivers switched off SOF calls the SOF interrupt may be disabled dcd_sof_enable(rhport, en); } diff --git a/src/device/usbd.h b/src/device/usbd.h index 72401a7e9..d485d8711 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -88,7 +88,7 @@ bool tud_connect(void); // Set Start-of-frame (1ms interval) IRQ handler // NULL means disabled, frame_count may not be supported on mcus -void tud_sof_isr_set(tud_sof_isr_t sof_isr); +// void tud_sof_isr_set(tud_sof_isr_t sof_isr); // Carry out Data and Status stage of control transfer // - If len = 0, it is equivalent to sending status only diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index 144736a46..603ffc936 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -48,7 +48,7 @@ typedef struct uint16_t (* open ) (uint8_t rhport, tusb_desc_interface_t const * desc_intf, uint16_t max_len); bool (* control_xfer_cb ) (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); bool (* xfer_cb ) (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); - void (* sof ) (uint8_t rhport, uint32_t frame_count); /* optional */ + void (* sof_isr ) (uint8_t rhport, uint32_t frame_count); // optional } usbd_class_driver_t; // Invoked when initializing device stack to get additional class drivers. diff --git a/src/tusb_option.h b/src/tusb_option.h index b3c3f4c5e..e1e418f89 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -297,7 +297,7 @@ #endif #ifndef CFG_TUD_INTERFACE_MAX - #define CFG_TUD_INTERFACE_MAX 8 + #define CFG_TUD_INTERFACE_MAX 16 #endif #ifndef CFG_TUD_CDC From e2f0aef93b246368e1f6bdf101604e73d252801a Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 30 Mar 2022 16:41:55 +0700 Subject: [PATCH 273/504] make use pio_usb_port_reset_start/end --- hw/bsp/rp2040/family.cmake | 1 + src/portable/raspberrypi/pio/hcd_pio.c | 10 ++-------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index 23ea893b7..b56ee6a6d 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -91,6 +91,7 @@ if (NOT TARGET _rp2040_family_inclusion_marker) ${TOP}/src/portable/raspberrypi/pio/hcd_pio.c ${TOP}/lib/Pico-PIO-USB/pio_usb.c + ${TOP}/lib/Pico-PIO-USB/pio_usb_port.c ${TOP}/lib/Pico-PIO-USB/usb_crc.c ) diff --git a/src/portable/raspberrypi/pio/hcd_pio.c b/src/portable/raspberrypi/pio/hcd_pio.c index 8d1903f85..e4a4e2450 100644 --- a/src/portable/raspberrypi/pio/hcd_pio.c +++ b/src/portable/raspberrypi/pio/hcd_pio.c @@ -53,8 +53,6 @@ extern pio_port_t pio_port[1]; extern root_port_t root_port[PIO_USB_ROOT_PORT_CNT]; extern endpoint_t ep_pool[PIO_USB_EP_POOL_CNT]; - -extern port_pin_status_t get_port_pin_status( root_port_t *port); extern void configure_fullspeed_host( pio_port_t *pp, const pio_usb_configuration_t *c, root_port_t *port); extern void configure_lowspeed_host( pio_port_t *pp, const pio_usb_configuration_t *c, root_port_t *port); @@ -83,10 +81,7 @@ void hcd_port_reset(uint8_t rhport) pio_port_t *pp = &pio_port[0]; root_port_t *root = &root_port[rhport]; - pio_sm_set_pins_with_mask(pp->pio_usb_tx, pp->sm_tx, (0b00 << root->pin_dp), - (0b11u << root->pin_dp)); - pio_sm_set_pindirs_with_mask(pp->pio_usb_tx, pp->sm_tx, (0b11u << root->pin_dp), - (0b11u << root->pin_dp)); + pio_usb_port_reset_start(root, pp); } void hcd_port_reset_end(uint8_t rhport) @@ -96,8 +91,7 @@ void hcd_port_reset_end(uint8_t rhport) pio_port_t *pp = &pio_port[0]; root_port_t *root = &root_port[rhport]; - pio_sm_set_pindirs_with_mask(pp->pio_usb_tx, pp->sm_tx, (0b00u << root->pin_dp), - (0b11u << root->pin_dp)); + pio_usb_port_reset_end(root, pp); busy_wait_us(100); From 95801bf5cc4afa27f9b54c33e74aa74689074a97 Mon Sep 17 00:00:00 2001 From: Rafael Silva Date: Wed, 30 Mar 2022 14:15:34 +0100 Subject: [PATCH 274/504] Update requirements.txt --- docs/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/requirements.txt b/docs/requirements.txt index 8ae9ae73b..15022e147 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,3 +1,4 @@ sphinx~=3.0 furo>=2020.12.30.b24 sphinx-autodoc-typehints>=1.10 +jinja2==3.0.3 From e94d11a5b39cae08f39722eaa5f6ac4d527a329b Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 31 Mar 2022 12:56:53 +0700 Subject: [PATCH 275/504] implement pio_usb_irq_handler --- lib/Pico-PIO-USB | 2 +- src/portable/raspberrypi/pio/hcd_pio.c | 26 +++++++++++++++++++++++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB index 92268187f..4220c05dc 160000 --- a/lib/Pico-PIO-USB +++ b/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit 92268187f3b0490a43d139ed2cb598b06258011f +Subproject commit 4220c05dc6b7ab7b4db33e5e05bb66be7b6c7156 diff --git a/src/portable/raspberrypi/pio/hcd_pio.c b/src/portable/raspberrypi/pio/hcd_pio.c index e4a4e2450..254acf1d2 100644 --- a/src/portable/raspberrypi/pio/hcd_pio.c +++ b/src/portable/raspberrypi/pio/hcd_pio.c @@ -101,7 +101,7 @@ void hcd_port_reset_end(uint8_t rhport) if (fullspeed_flag && get_port_pin_status(root) == PORT_PIN_FS_IDLE) { root->root_device = &usb_device[0]; if (!root->root_device->connected) { - configure_fullspeed_host(pp, &pio_host_config, root); +// configure_fullspeed_host(pp, &pio_host_config, root); root->root_device->is_fullspeed = true; root->root_device->is_root = true; root->root_device->connected = true; @@ -111,7 +111,7 @@ void hcd_port_reset_end(uint8_t rhport) } else if (!fullspeed_flag && get_port_pin_status(root) == PORT_PIN_LS_IDLE) { root->root_device = &usb_device[0]; if (!root->root_device->connected) { - configure_lowspeed_host(pp, &pio_host_config, root); +// configure_lowspeed_host(pp, &pio_host_config, root); root->root_device->is_fullspeed = false; root->root_device->is_root = true; root->root_device->connected = true; @@ -217,6 +217,7 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet return false; } + bool hcd_edpt_control_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8], uint8_t* data) { int ret; @@ -242,7 +243,6 @@ bool hcd_edpt_control_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t const setup return ret == 0; } - //bool hcd_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) //{ // // EPX is shared, so multiple device addresses and endpoint addresses share that @@ -265,4 +265,24 @@ bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) return true; } +// IRQ Handler +void pio_usb_irq_handler(uint8_t root_id) +{ + root_port_t* port = PIO_USB(root_id); + + if ( port->ints & PIO_USB_INTS_CONNECT_BITS ) + { + hcd_event_device_attach(root_id+1, true); + + port->ints &= ~PIO_USB_INTS_CONNECT_BITS; + } + + if ( port->ints & PIO_USB_INTS_DISCONNECT_BITS ) + { + hcd_event_device_remove(root_id+1, true); + + port->ints &= ~PIO_USB_INTS_DISCONNECT_BITS; + } +} + #endif From 75bca96bc630b98723c9f4bbb4958dac22ac594d Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 1 Apr 2022 16:01:24 +0700 Subject: [PATCH 276/504] pio usb control work well including stall response --- src/host/hcd.h | 4 - src/host/usbh.c | 16 ++-- src/portable/raspberrypi/pio/hcd_pio.c | 118 +++++++++++++++---------- 3 files changed, 78 insertions(+), 60 deletions(-) diff --git a/src/host/hcd.h b/src/host/hcd.h index 0e18351fc..9b41f2447 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -153,10 +153,6 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * // Submit a special transfer to send 8-byte Setup Packet, when complete hcd_event_xfer_complete() must be invoked bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]); -// Optional: some controllers are capable of carry out the whole Control Transfer (setup, data, status) -// without help of USBH. -bool hcd_edpt_control_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8], uint8_t* data) TU_ATTR_WEAK; - // clear stall, data toggle is also reset to DATA0 bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr); diff --git a/src/host/usbh.c b/src/host/usbh.c index b388a4c08..520ef4c7d 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -543,19 +543,12 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) const uint8_t rhport = usbh_get_rhport(daddr); TU_LOG2("[%u:%u] %s: ", rhport, daddr, xfer->setup->bRequest <= TUSB_REQ_SYNCH_FRAME ? tu_str_std_request[xfer->setup->bRequest] : "Unknown Request"); - TU_LOG2_VAR(&xfer->setup); + TU_LOG2_VAR(xfer->setup); TU_LOG2("\r\n"); if (xfer->complete_cb) { - if ( hcd_edpt_control_xfer ) - { - _ctrl_xfer.stage = CONTROL_STAGE_ACK; - TU_ASSERT( hcd_edpt_control_xfer(rhport, daddr, (uint8_t const*) &_ctrl_xfer.request, _ctrl_xfer.buffer) ); - }else - { - TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t const*) &_ctrl_xfer.request) ); - } + TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t const*) &_ctrl_xfer.request) ); }else { // blocking if complete callback is not provided @@ -643,7 +636,8 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result { // DATA stage: initial data toggle is always 1 _set_control_xfer_stage(CONTROL_STAGE_DATA); - return hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.buffer, request->wLength); + TU_ASSERT( hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.buffer, request->wLength) ); + return true; } __attribute__((fallthrough)); @@ -658,7 +652,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result // ACK stage: toggle is always 1 _set_control_xfer_stage(CONTROL_STAGE_ACK); - hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, 1-request->bmRequestType_bit.direction), NULL, 0); + TU_ASSERT( hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, 1-request->bmRequestType_bit.direction), NULL, 0) ); break; case CONTROL_STAGE_ACK: diff --git a/src/portable/raspberrypi/pio/hcd_pio.c b/src/portable/raspberrypi/pio/hcd_pio.c index 254acf1d2..4eff490c8 100644 --- a/src/portable/raspberrypi/pio/hcd_pio.c +++ b/src/portable/raspberrypi/pio/hcd_pio.c @@ -53,15 +53,6 @@ extern pio_port_t pio_port[1]; extern root_port_t root_port[PIO_USB_ROOT_PORT_CNT]; extern endpoint_t ep_pool[PIO_USB_EP_POOL_CNT]; -extern void configure_fullspeed_host( pio_port_t *pp, const pio_usb_configuration_t *c, root_port_t *port); -extern void configure_lowspeed_host( pio_port_t *pp, const pio_usb_configuration_t *c, root_port_t *port); - -extern void control_setup_transfer( const pio_port_t *pp, uint8_t device_address, uint8_t *tx_data_address, uint8_t tx_data_len); -extern int control_in_protocol( usb_device_t *device, uint8_t *tx_data, uint16_t tx_length, uint8_t *rx_buffer, uint16_t request_length); -extern int control_out_protocol( usb_device_t *device, uint8_t *setup_data, uint16_t setup_length, uint8_t *out_data, uint16_t out_length); - -extern void update_packet_crc16(usb_setup_packet_t * packet); - //--------------------------------------------------------------------+ // HCD API //--------------------------------------------------------------------+ @@ -157,12 +148,15 @@ void hcd_int_disable(uint8_t rhport) // Endpoint API //--------------------------------------------------------------------+ -bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) +bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep) { rhport = RHPORT_PIO(rhport); usb_device_t *device = &usb_device[0]; + return pio_usb_endpoint_open(rhport, dev_addr, (uint8_t const*) desc_ep); + +#if 0 static uint8_t ep_id_idx; // TODO remove later if (ep_desc->bEndpointAddress == 0) @@ -202,45 +196,19 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const } return true; +#endif } bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) { - (void) rhport; - - return true; + rhport = RHPORT_PIO(rhport); + return pio_usb_endpoint_transfer(rhport, dev_addr, ep_addr, buffer, buflen); } bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) { - (void) rhport; - return false; -} - - -bool hcd_edpt_control_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8], uint8_t* data) -{ - int ret; rhport = RHPORT_PIO(rhport); - - uint16_t const len = ((tusb_control_request_t const*) setup_packet)->wLength; - - usb_setup_packet_t pio_setup = { USB_SYNC, USB_PID_DATA0 }; - memcpy(&pio_setup.request_type, setup_packet, 8); - update_packet_crc16(&pio_setup); - - if (setup_packet[0] & TUSB_DIR_IN_MASK) - { - ret = control_in_protocol(&usb_device[0], (uint8_t*) &pio_setup, sizeof(pio_setup), data, len); - }else - { - ret = control_out_protocol(&usb_device[0], (uint8_t*) &pio_setup, sizeof(pio_setup), data, len); - } - - // TODO current pio is blocking - hcd_event_xfer_complete(dev_addr, 0, 0, ret ? XFER_RESULT_FAILED : XFER_RESULT_SUCCESS, false); - - return ret == 0; + return pio_usb_endpoint_send_setup(rhport, dev_addr, setup_packet); } //bool hcd_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) @@ -265,23 +233,83 @@ bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) return true; } +void __no_inline_not_in_flash_func(handle_endpoint_irq)(root_port_t* port, uint32_t flag) +{ + volatile uint32_t* ep_reg; + xfer_result_t result; + + if ( flag == PIO_USB_INTS_ENDPOINT_COMPLETE_BITS ) + { + ep_reg = &port->ep_complete; + result = XFER_RESULT_SUCCESS; + } + else if ( flag == PIO_USB_INTS_ENDPOINT_ERROR_BITS ) + { + ep_reg = &port->ep_error; + result = XFER_RESULT_FAILED; + } + else if ( flag == PIO_USB_INTS_ENDPOINT_STALLED_BITS ) + { + ep_reg = &port->ep_stalled; + result = XFER_RESULT_STALLED; + } + else + { + // something wrong + return; + } + + const uint32_t ep_all = *ep_reg; + + for(uint8_t ep_idx = 0; ep_idx < PIO_USB_EP_POOL_CNT; ep_idx++) + { + uint32_t const mask = (1u << ep_idx); + + if (ep_all & mask) + { + endpoint_t* ep = PIO_USB_EP(ep_idx); + hcd_event_xfer_complete(ep->dev_addr, ep->ep_num, ep->actual_len, result, true); + } + } + + // clear all + (*ep_reg) &= ~ep_all; +} + // IRQ Handler -void pio_usb_irq_handler(uint8_t root_id) +void __no_inline_not_in_flash_func(pio_usb_host_irq_handler)(uint8_t root_id) { root_port_t* port = PIO_USB(root_id); if ( port->ints & PIO_USB_INTS_CONNECT_BITS ) { - hcd_event_device_attach(root_id+1, true); - port->ints &= ~PIO_USB_INTS_CONNECT_BITS; + + hcd_event_device_attach(root_id+1, true); } if ( port->ints & PIO_USB_INTS_DISCONNECT_BITS ) { - hcd_event_device_remove(root_id+1, true); - port->ints &= ~PIO_USB_INTS_DISCONNECT_BITS; + hcd_event_device_remove(root_id+1, true); + } + + if ( port->ints & PIO_USB_INTS_ENDPOINT_COMPLETE_BITS ) + { + port->ints &= ~PIO_USB_INTS_ENDPOINT_COMPLETE_BITS; + handle_endpoint_irq(port, PIO_USB_INTS_ENDPOINT_COMPLETE_BITS); + } + + if ( port->ints & PIO_USB_INTS_ENDPOINT_ERROR_BITS ) + { + port->ints &= ~PIO_USB_INTS_ENDPOINT_ERROR_BITS; + handle_endpoint_irq(port, PIO_USB_INTS_ENDPOINT_ERROR_BITS); + } + + if ( port->ints & PIO_USB_INTS_ENDPOINT_STALLED_BITS ) + { + port->ints &= ~PIO_USB_INTS_ENDPOINT_STALLED_BITS; + handle_endpoint_irq(port, PIO_USB_INTS_ENDPOINT_STALLED_BITS); } } From e6e3dfedc815007d07ea455df04569604d87a856 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 1 Apr 2022 16:34:36 +0700 Subject: [PATCH 277/504] hid example work well --- lib/Pico-PIO-USB | 2 +- src/class/hid/hid_host.c | 2 +- src/host/usbh.c | 2 +- src/portable/raspberrypi/pio/hcd_pio.c | 42 -------------------------- 4 files changed, 3 insertions(+), 45 deletions(-) diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB index 4220c05dc..650130ab3 160000 --- a/lib/Pico-PIO-USB +++ b/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit 4220c05dc6b7ab7b4db33e5e05bb66be7b6c7156 +Subproject commit 650130ab312e0dc9337dc52cccf34d35875abdf7 diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index ce3d1598c..2573f5a6b 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -329,7 +329,7 @@ bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *de TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass); - TU_LOG2("HID opening Interface %u (addr = %u)\r\n", desc_itf->bInterfaceNumber, dev_addr); + TU_LOG2("[%u] HID opening Interface %u\r\n", dev_addr, desc_itf->bInterfaceNumber); // len = interface + hid + n*endpoints uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); diff --git a/src/host/usbh.c b/src/host/usbh.c index 520ef4c7d..c127ef310 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -792,7 +792,7 @@ bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * b static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size) { - TU_LOG2("Open EP0 with Size = %u (addr = %u)\r\n", max_packet_size, dev_addr); + TU_LOG2("[%u] Open EP0 with Size = %u\r\n", dev_addr, max_packet_size); tusb_desc_endpoint_t ep0_desc = { diff --git a/src/portable/raspberrypi/pio/hcd_pio.c b/src/portable/raspberrypi/pio/hcd_pio.c index 4eff490c8..037ebc132 100644 --- a/src/portable/raspberrypi/pio/hcd_pio.c +++ b/src/portable/raspberrypi/pio/hcd_pio.c @@ -155,48 +155,6 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const usb_device_t *device = &usb_device[0]; return pio_usb_endpoint_open(rhport, dev_addr, (uint8_t const*) desc_ep); - -#if 0 - static uint8_t ep_id_idx; // TODO remove later - - if (ep_desc->bEndpointAddress == 0) - { - device->event = EVENT_NONE; - device->address = dev_addr; - - ep_id_idx = 0; - }else if (ep_desc->bmAttributes.xfer == TUSB_XFER_INTERRUPT) // only support interrupt endpoint - { - endpoint_t *ep = NULL; - for ( int ep_pool_idx = 0; ep_pool_idx < PIO_USB_EP_POOL_CNT; ep_pool_idx++ ) - { - if ( ep_pool[ep_pool_idx].ep_num == 0 ) - { - ep = &ep_pool[ep_pool_idx]; - device->endpoint_id[ep_id_idx] = ep_pool_idx + 1; - ep_id_idx++; - - ep->data_id = 0; - ep->ep_num = ep_desc->bEndpointAddress; - ep->interval = ep_desc->bInterval; - ep->interval_counter = 0; - ep->size = (uint8_t) tu_edpt_packet_size(ep_desc); - ep->attr = EP_ATTR_INTERRUPT; - - break; - } - } - -// TU_LOG1_INT(device->connected); -// TU_LOG1_INT(device->root); -// TU_LOG1_INT(device->is_root); -// TU_LOG1_INT(device->is_fullspeed); -// -// TU_LOG1_INT(ep_id_idx); - } - - return true; -#endif } bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) From db6cba6a7bdf82f8c131fa2c521b86b10b4d053e Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 1 Apr 2022 16:38:41 +0700 Subject: [PATCH 278/504] rename pio to pio_usb --- hw/bsp/rp2040/family.cmake | 2 +- .../raspberrypi/{pio/hcd_pio.c => pio_usb/hcd_pio_usb.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/portable/raspberrypi/{pio/hcd_pio.c => pio_usb/hcd_pio_usb.c} (100%) diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index b56ee6a6d..4cec645a2 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -89,7 +89,7 @@ if (NOT TARGET _rp2040_family_inclusion_marker) ${TOP}/src/class/msc/msc_host.c ${TOP}/src/class/vendor/vendor_host.c - ${TOP}/src/portable/raspberrypi/pio/hcd_pio.c + ${TOP}/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c ${TOP}/lib/Pico-PIO-USB/pio_usb.c ${TOP}/lib/Pico-PIO-USB/pio_usb_port.c ${TOP}/lib/Pico-PIO-USB/usb_crc.c diff --git a/src/portable/raspberrypi/pio/hcd_pio.c b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c similarity index 100% rename from src/portable/raspberrypi/pio/hcd_pio.c rename to src/portable/raspberrypi/pio_usb/hcd_pio_usb.c From c25f835aea838f935893fdef6352fab938e11d4b Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 1 Apr 2022 23:31:43 +0700 Subject: [PATCH 279/504] update to use pio hw endpoint --- hw/bsp/rp2040/family.cmake | 3 ++- lib/Pico-PIO-USB | 2 +- src/portable/raspberrypi/pio_usb/hcd_pio_usb.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index 4cec645a2..275ec9e6b 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -91,7 +91,8 @@ if (NOT TARGET _rp2040_family_inclusion_marker) ${TOP}/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c ${TOP}/lib/Pico-PIO-USB/pio_usb.c - ${TOP}/lib/Pico-PIO-USB/pio_usb_port.c + ${TOP}/lib/Pico-PIO-USB/pio_usb_host.c + ${TOP}/lib/Pico-PIO-USB/pio_usb_hw.c ${TOP}/lib/Pico-PIO-USB/usb_crc.c ) diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB index 650130ab3..72f91ac9c 160000 --- a/lib/Pico-PIO-USB +++ b/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit 650130ab312e0dc9337dc52cccf34d35875abdf7 +Subproject commit 72f91ac9cdaf532eacfbe9534420341b13480441 diff --git a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c index 037ebc132..09407851d 100644 --- a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c @@ -225,7 +225,7 @@ void __no_inline_not_in_flash_func(handle_endpoint_irq)(root_port_t* port, uint3 if (ep_all & mask) { - endpoint_t* ep = PIO_USB_EP(ep_idx); + pio_hw_endpoint_t* ep = PIO_USB_HW_EP(ep_idx); hcd_event_xfer_complete(ep->dev_addr, ep->ep_num, ep->actual_len, result, true); } } From f881e77e66ea92506fefb69a24324f6c2274aab9 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 2 Apr 2022 19:19:00 +0700 Subject: [PATCH 280/504] extracting hw root port --- lib/Pico-PIO-USB | 2 +- src/portable/raspberrypi/pio_usb/hcd_pio_usb.c | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB index 72f91ac9c..ea48fc073 160000 --- a/lib/Pico-PIO-USB +++ b/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit 72f91ac9cdaf532eacfbe9534420341b13480441 +Subproject commit ea48fc073ce28e3870a71e8019b08a02bde8ebf9 diff --git a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c index 09407851d..1fe7a0d6e 100644 --- a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c @@ -50,8 +50,6 @@ static pio_usb_configuration_t pio_host_config = PIO_USB_DEFAULT_CONFIG; extern root_port_t root_port[PIO_USB_ROOT_PORT_CNT]; extern usb_device_t usb_device[PIO_USB_DEVICE_CNT]; extern pio_port_t pio_port[1]; -extern root_port_t root_port[PIO_USB_ROOT_PORT_CNT]; -extern endpoint_t ep_pool[PIO_USB_EP_POOL_CNT]; //--------------------------------------------------------------------+ // HCD API @@ -191,7 +189,7 @@ bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) return true; } -void __no_inline_not_in_flash_func(handle_endpoint_irq)(root_port_t* port, uint32_t flag) +void __no_inline_not_in_flash_func(handle_endpoint_irq)(pio_hw_root_port_t* port, uint32_t flag) { volatile uint32_t* ep_reg; xfer_result_t result; @@ -237,7 +235,7 @@ void __no_inline_not_in_flash_func(handle_endpoint_irq)(root_port_t* port, uint3 // IRQ Handler void __no_inline_not_in_flash_func(pio_usb_host_irq_handler)(uint8_t root_id) { - root_port_t* port = PIO_USB(root_id); + pio_hw_root_port_t* port = PIO_USB_HW_RPORT(root_id); if ( port->ints & PIO_USB_INTS_CONNECT_BITS ) { From f6851cf18764a615f83bb782973bb3ea25e9089c Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 3 Apr 2022 00:17:58 +0700 Subject: [PATCH 281/504] clean up hcd pio --- lib/Pico-PIO-USB | 2 +- .../raspberrypi/pio_usb/hcd_pio_usb.c | 60 +++---------------- 2 files changed, 10 insertions(+), 52 deletions(-) diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB index ea48fc073..7d8df447c 160000 --- a/lib/Pico-PIO-USB +++ b/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit ea48fc073ce28e3870a71e8019b08a02bde8ebf9 +Subproject commit 7d8df447c4c5d0515f2ab9f10b28ac92d7cc78df diff --git a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c index 1fe7a0d6e..dc52870e9 100644 --- a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c @@ -43,14 +43,8 @@ #define RHPORT_OFFSET 1 #define RHPORT_PIO(_x) ((_x)-RHPORT_OFFSET) - -static usb_device_t *_test_usb_device = NULL; static pio_usb_configuration_t pio_host_config = PIO_USB_DEFAULT_CONFIG; -extern root_port_t root_port[PIO_USB_ROOT_PORT_CNT]; -extern usb_device_t usb_device[PIO_USB_DEVICE_CNT]; -extern pio_port_t pio_port[1]; - //--------------------------------------------------------------------+ // HCD API //--------------------------------------------------------------------+ @@ -58,7 +52,7 @@ bool hcd_init(uint8_t rhport) { // To run USB SOF interrupt in core1, create alarm pool in core1. pio_host_config.alarm_pool = (void*)alarm_pool_create(2, 1); - _test_usb_device = pio_usb_host_init(&pio_host_config); + (void) pio_usb_host_init(&pio_host_config); return true; } @@ -66,56 +60,23 @@ bool hcd_init(uint8_t rhport) void hcd_port_reset(uint8_t rhport) { rhport = RHPORT_PIO(rhport); - - pio_port_t *pp = &pio_port[0]; - root_port_t *root = &root_port[rhport]; - - pio_usb_port_reset_start(root, pp); + pio_usb_hw_port_reset_start(rhport); } void hcd_port_reset_end(uint8_t rhport) { rhport = RHPORT_PIO(rhport); - - pio_port_t *pp = &pio_port[0]; - root_port_t *root = &root_port[rhport]; - - pio_usb_port_reset_end(root, pp); - - busy_wait_us(100); - - // TODO slow speed - bool fullspeed_flag = true; - - if (fullspeed_flag && get_port_pin_status(root) == PORT_PIN_FS_IDLE) { - root->root_device = &usb_device[0]; - if (!root->root_device->connected) { -// configure_fullspeed_host(pp, &pio_host_config, root); - root->root_device->is_fullspeed = true; - root->root_device->is_root = true; - root->root_device->connected = true; - root->root_device->root = root; - root->root_device->event = EVENT_CONNECT; - } - } else if (!fullspeed_flag && get_port_pin_status(root) == PORT_PIN_LS_IDLE) { - root->root_device = &usb_device[0]; - if (!root->root_device->connected) { -// configure_lowspeed_host(pp, &pio_host_config, root); - root->root_device->is_fullspeed = false; - root->root_device->is_root = true; - root->root_device->connected = true; - root->root_device->root = root; - root->root_device->event = EVENT_CONNECT; - } - } + pio_usb_hw_port_reset_end(rhport); } bool hcd_port_connect_status(uint8_t rhport) { - root_port_t* port = &root_port[0]; - bool dp = gpio_get(port->pin_dp); - bool dm = gpio_get(port->pin_dm); - return dp || dm; + rhport = RHPORT_PIO(rhport); + + pio_hw_root_port_t *root = PIO_USB_HW_RPORT(rhport); + port_pin_status_t line_state = pio_hw_get_line_state(root); + + return line_state != PORT_PIN_SE0; } tusb_speed_t hcd_port_speed_get(uint8_t rhport) @@ -149,9 +110,6 @@ void hcd_int_disable(uint8_t rhport) bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep) { rhport = RHPORT_PIO(rhport); - - usb_device_t *device = &usb_device[0]; - return pio_usb_endpoint_open(rhport, dev_addr, (uint8_t const*) desc_ep); } From 7ea75d3c09d1afd4db5374c89f715d8ff6c1d414 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 3 Apr 2022 20:44:16 +0700 Subject: [PATCH 282/504] use pio usb host init --- lib/Pico-PIO-USB | 2 +- src/portable/raspberrypi/pio_usb/hcd_pio_usb.c | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB index 7d8df447c..b507f95de 160000 --- a/lib/Pico-PIO-USB +++ b/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit 7d8df447c4c5d0515f2ab9f10b28ac92d7cc78df +Subproject commit b507f95de457d5dc14fb15fd6481ef748c6e3342 diff --git a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c index dc52870e9..c2ac2c706 100644 --- a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c @@ -50,9 +50,8 @@ static pio_usb_configuration_t pio_host_config = PIO_USB_DEFAULT_CONFIG; //--------------------------------------------------------------------+ bool hcd_init(uint8_t rhport) { - // To run USB SOF interrupt in core1, create alarm pool in core1. - pio_host_config.alarm_pool = (void*)alarm_pool_create(2, 1); - (void) pio_usb_host_init(&pio_host_config); + // To run USB SOF interrupt in core1, call this init in core1 + pio_usb_host_controller_init(&pio_host_config); return true; } From d7d7e61f3437076a38ec031f2dc4cef38c8c831b Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 3 Apr 2022 22:48:08 +0700 Subject: [PATCH 283/504] correct pio usb speed, and close device --- lib/Pico-PIO-USB | 2 +- src/portable/raspberrypi/pio_usb/hcd_pio_usb.c | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB index b507f95de..650ef75f0 160000 --- a/lib/Pico-PIO-USB +++ b/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit b507f95de457d5dc14fb15fd6481ef748c6e3342 +Subproject commit 650ef75f0d8a4020a7ddc2ccee1ee0f3237ab760 diff --git a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c index c2ac2c706..839087957 100644 --- a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c @@ -81,12 +81,15 @@ bool hcd_port_connect_status(uint8_t rhport) tusb_speed_t hcd_port_speed_get(uint8_t rhport) { // TODO determine link speed - return TUSB_SPEED_FULL; + rhport = RHPORT_PIO(rhport); + return PIO_USB_HW_RPORT(rhport)->is_fullspeed ? TUSB_SPEED_FULL : TUSB_SPEED_LOW; } // Close all opened endpoint belong to this device void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { + rhport = RHPORT_PIO(rhport); + pio_usb_host_close_device(rhport, dev_addr); } uint32_t hcd_frame_number(uint8_t rhport) From d97c1546957059cfb3063b95d5287e2729f7f79a Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 5 Apr 2022 00:04:47 +0700 Subject: [PATCH 284/504] add need_pre for pio usb, but not work out well --- lib/Pico-PIO-USB | 2 +- src/host/usbh.c | 4 ++-- src/portable/raspberrypi/pio_usb/hcd_pio_usb.c | 6 +++++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB index 650ef75f0..4993f4a1d 160000 --- a/lib/Pico-PIO-USB +++ b/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit 650ef75f0d8a4020a7ddc2ccee1ee0f3237ab760 +Subproject commit 4993f4a1df03c8af13c8091052a6274e8c333bc0 diff --git a/src/host/usbh.c b/src/host/usbh.c index c127ef310..47c462012 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -642,7 +642,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result __attribute__((fallthrough)); case CONTROL_STAGE_DATA: - if (xferred_bytes) + if (request->wLength) { TU_LOG2("[%u:%u] Control data:\r\n", rhport, dev_addr); TU_LOG2_MEM(_ctrl_xfer.buffer, xferred_bytes, 2); @@ -1301,7 +1301,7 @@ static void process_enumeration(tuh_xfer_t* xfer) TU_ASSERT(new_dev, ); new_dev->addressed = 1; - // TODO close device 0, may not be needed + // Close device 0 hcd_device_close(_dev0.rhport, 0); // open control pipe for new address diff --git a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c index 839087957..c2ef54b9e 100644 --- a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c @@ -111,8 +111,12 @@ void hcd_int_disable(uint8_t rhport) bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep) { + hcd_devtree_info_t dev_tree; + hcd_devtree_get_info(dev_addr, &dev_tree); + bool const need_pre = (dev_tree.hub_addr && dev_tree.speed == TUSB_SPEED_LOW); + rhport = RHPORT_PIO(rhport); - return pio_usb_endpoint_open(rhport, dev_addr, (uint8_t const*) desc_ep); + return pio_usb_endpoint_open(rhport, dev_addr, (uint8_t const*) desc_ep, need_pre); } bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) From d5d4909c20f581ef2046932191f487c001d59ca3 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 8 Apr 2022 13:36:05 +0700 Subject: [PATCH 285/504] proof of concpet that device pio-usb work with host pio-usb --- examples/device/hid_boot_interface/src/main.c | 4 +++ .../hid_boot_interface/src/tusb_config.h | 3 ++ examples/host/cdc_msc_hid/src/tusb_config.h | 1 + hw/bsp/rp2040/family.cmake | 32 ++++++++----------- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 2 +- src/tusb_option.h | 6 +++- 6 files changed, 27 insertions(+), 21 deletions(-) diff --git a/examples/device/hid_boot_interface/src/main.c b/examples/device/hid_boot_interface/src/main.c index e5e2f6856..ed7f235b7 100644 --- a/examples/device/hid_boot_interface/src/main.c +++ b/examples/device/hid_boot_interface/src/main.c @@ -31,6 +31,8 @@ #include "tusb.h" #include "usb_descriptors.h" +#include "pio_usb.h" + //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ @@ -59,6 +61,8 @@ int main(void) while (1) { + pio_usb_device_task(); + tud_task(); // tinyusb device task led_blinking_task(); diff --git a/examples/device/hid_boot_interface/src/tusb_config.h b/examples/device/hid_boot_interface/src/tusb_config.h index 1c8fa40b2..d4f67e7ba 100644 --- a/examples/device/hid_boot_interface/src/tusb_config.h +++ b/examples/device/hid_boot_interface/src/tusb_config.h @@ -39,6 +39,9 @@ #error CFG_TUSB_MCU must be defined #endif +// Use raspberry pio-usb for device +#define CFG_TUD_RPI_PIO_USB 1 + // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_DEVICE_RHPORT_NUM #define BOARD_DEVICE_RHPORT_NUM 0 diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index 80ee8cb01..9d083c771 100644 --- a/examples/host/cdc_msc_hid/src/tusb_config.h +++ b/examples/host/cdc_msc_hid/src/tusb_config.h @@ -39,6 +39,7 @@ #error CFG_TUSB_MCU must be defined #endif +// Use raspberry pio-usb for host #define CFG_TUH_RPI_PIO_USB 1 //#define CFG_TUSB_RPI_PIO_INC_PATH 1 diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index 275ec9e6b..b186fc78e 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -29,12 +29,17 @@ if (NOT TARGET _rp2040_family_inclusion_marker) target_sources(tinyusb_common_base INTERFACE ${TOP}/src/tusb.c ${TOP}/src/common/tusb_fifo.c + ${TOP}/lib/Pico-PIO-USB/pio_usb.c + ${TOP}/lib/Pico-PIO-USB/pio_usb_host.c + ${TOP}/lib/Pico-PIO-USB/pio_usb_hw.c + ${TOP}/lib/Pico-PIO-USB/usb_crc.c ) target_include_directories(tinyusb_common_base INTERFACE ${TOP}/src ${TOP}/src/common ${TOP}/hw + ${TOP}/lib/Pico-PIO-USB ) target_link_libraries(tinyusb_common_base INTERFACE @@ -42,6 +47,10 @@ if (NOT TARGET _rp2040_family_inclusion_marker) hardware_irq hardware_resets pico_sync + # for usb-pio + hardware_dma + hardware_pio + pico_multicore ) set(TINYUSB_DEBUG_LEVEL 0) @@ -60,6 +69,7 @@ if (NOT TARGET _rp2040_family_inclusion_marker) add_library(tinyusb_device_base INTERFACE) target_sources(tinyusb_device_base INTERFACE ${TOP}/src/portable/raspberrypi/rp2040/dcd_rp2040.c + ${TOP}/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c ${TOP}/src/portable/raspberrypi/rp2040/rp2040_usb.c ${TOP}/src/device/usbd.c ${TOP}/src/device/usbd_control.c @@ -88,12 +98,7 @@ if (NOT TARGET _rp2040_family_inclusion_marker) ${TOP}/src/class/hid/hid_host.c ${TOP}/src/class/msc/msc_host.c ${TOP}/src/class/vendor/vendor_host.c - - ${TOP}/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c - ${TOP}/lib/Pico-PIO-USB/pio_usb.c - ${TOP}/lib/Pico-PIO-USB/pio_usb_host.c - ${TOP}/lib/Pico-PIO-USB/pio_usb_hw.c - ${TOP}/lib/Pico-PIO-USB/usb_crc.c + ${TOP}/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c ) # Sometimes have to do host specific actions in mostly common functions @@ -101,17 +106,6 @@ if (NOT TARGET _rp2040_family_inclusion_marker) RP2040_USB_HOST_MODE=1 ) - # config for host pio - target_link_libraries(tinyusb_host_base INTERFACE - hardware_dma - hardware_pio - pico_multicore - ) - - target_include_directories(tinyusb_host_base INTERFACE - ${TOP}/lib/Pico-PIO-USB - ) - add_library(tinyusb_bsp INTERFACE) target_sources(tinyusb_bsp INTERFACE ${TOP}/hw/bsp/rp2040/family.c @@ -166,8 +160,8 @@ if (NOT TARGET _rp2040_family_inclusion_marker) _family_initialize_project(${PROJECT} ${DIR}) enable_language(C CXX ASM) pico_sdk_init() - pico_generate_pio_header(tinyusb_host_base ${TOP}/lib/Pico-PIO-USB/usb_tx.pio) - pico_generate_pio_header(tinyusb_host_base ${TOP}/lib/Pico-PIO-USB/usb_rx.pio) + pico_generate_pio_header(tinyusb_common_base ${TOP}/lib/Pico-PIO-USB/usb_tx.pio) + pico_generate_pio_header(tinyusb_common_base ${TOP}/lib/Pico-PIO-USB/usb_rx.pio) endfunction() # This method must be called from the project scope to suppress known warnings in TinyUSB source files diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index 915822798..2d77ad4f9 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_RP2040 +#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_RP2040) && !CFG_TUD_RPI_PIO_USB #include "pico.h" #include "rp2040_usb.h" diff --git a/src/tusb_option.h b/src/tusb_option.h index 61cc283c4..5636b34fe 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -239,7 +239,7 @@ #define TUH_OPT_RHPORT -1 #endif -#define CFG_TUH_ENABLED ( TUH_RHPORT_MODE & OPT_MODE_HOST ) +#define CFG_TUH_ENABLED (TUH_RHPORT_MODE & OPT_MODE_HOST) // For backward compatible #define TUSB_OPT_DEVICE_ENABLED CFG_TUD_ENABLED @@ -398,6 +398,10 @@ #define CFG_TUH_RPI_PIO_USB 0 #endif +#ifndef CFG_TUD_RPI_PIO_USB +#define CFG_TUD_RPI_PIO_USB 0 +#endif + //------------------------------------------------------------------ // Configuration Validation From 7094ff7125b6961d52eaca0e3b8d42f3b57a1ee9 Mon Sep 17 00:00:00 2001 From: Reinhard Panhuber Date: Sat, 9 Apr 2022 16:36:26 +0200 Subject: [PATCH 286/504] Introduce 3 fb calc options: NO_SOF_BY_USER, SOF_BY_AUDIO_D, SOF_BY_USER --- src/class/audio/audio_device.c | 84 ++++++++++++++++++++++++---------- src/class/audio/audio_device.h | 70 ++++++++++++++++++++++------ 2 files changed, 117 insertions(+), 37 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 434bfdcc6..2e2653e48 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -305,11 +305,12 @@ typedef struct #endif #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -#if !CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). + uint8_t fb_n_frames; // Number of (micro)frames used to estimate feedback value #endif -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER volatile uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). uint8_t fb_n_frames; // Number of (micro)frames used to estimate feedback value volatile uint8_t fb_n_frames_current; // Current (micro)frame number @@ -328,10 +329,15 @@ typedef struct uint64_t fb_param_factor_N; // Numerator of feedback parameter coefficient uint64_t fb_param_factor_D; // Denominator of feedback parameter coefficient #endif +#endif // CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER + volatile uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). + uint8_t fb_n_frames; // Number of (micro)frames used to estimate feedback value #endif -#endif -#endif +#endif // CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP +#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT #if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING tu_fifo_t ep_in_ff; @@ -445,7 +451,7 @@ static inline uint8_t tu_desc_subtype(void const* desc) } #endif -#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER) static bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); #endif @@ -1572,6 +1578,8 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP usbd_edpt_close(rhport, audio->ep_fb); audio->ep_fb = 0; + audio->fb_n_frames = 0; + #endif } #endif @@ -1631,7 +1639,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * #endif // Invoke callback - can be used to trigger data sampling if not already running -// if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); + // if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); // Schedule first transmit if alternate interface is not zero i.e. streaming is disabled - in case no sample data is available a ZLP is loaded // It is necessary to trigger this here since the refill is done with an RX FIFO empty interrupt which can only trigger if something was in there @@ -1665,10 +1673,10 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // In case of asynchronous EP, call Cb after ep_fb is set -// if ( !(desc_ep->bmAttributes.sync == 0x01 && audio->ep_fb == 0) ) -// { -// if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); -// } + // if ( !(desc_ep->bmAttributes.sync == 0x01 && audio->ep_fb == 0) ) + // { + // if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); + // } #else // Invoke callback if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); @@ -1685,19 +1693,22 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && desc_ep->bmAttributes.usage == 1) // Check if usage is explicit data feedback { audio->ep_fb = ep_addr; - -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR - usbd_sof_enable(rhport, true); // Enable SOF interrupt audio->fb_n_frames = desc_ep->bInterval; + +#if ((CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER) || (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER)) + usbd_sof_enable(rhport, true); // Enable SOF interrupt +#endif + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER audio->fb_n_frames_current = 0; audio->fb_n_cycles_old = 0; #endif -// // Invoke callback after ep_out is set -// if (audio->ep_out != 0) -// { -// if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); -// } + // // Invoke callback after ep_out is set + // if (audio->ep_out != 0) + // { + // if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); + // } } #endif #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT @@ -1721,7 +1732,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * } // Disable SOF interrupt if no driver has any enabled feedback EP -#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && ((CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER) || (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER)) bool disable = true; @@ -2025,7 +2036,14 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 return false; } -#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && ((CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER) || (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER)) +uint8_t tud_audio_n_get_fb_n_frames(uint8_t func_id) +{ + return _audiod_fct[func_id].fb_n_frames; +} +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER) // This function must be called from the user within the tud_audio_set_itf_cb(rhport, p_request) callback function, where p_request needs to be checked as // uint8_t const itf = tu_u16_low(p_request->wIndex); @@ -2081,12 +2099,14 @@ TU_ATTR_WEAK bool tud_audio_set_fb_params(uint8_t func_id, uint32_t f_m, uint32_ } #endif -void audiod_sof (uint8_t rhport, uint32_t frame_count) +TU_ATTR_WEAK void audiod_sof (uint8_t rhport, uint32_t frame_count) { (void) rhport; (void) frame_count; // frame_count is not used since some devices may not provide the frame count value -#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP + +#if (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER) // Determine feedback value - The feedback method is described in 5.12.4.2 of the USB 2.0 spec // Boiled down, the feedback value Ff = n_samples / (micro)frame. @@ -2136,7 +2156,23 @@ void audiod_sof (uint8_t rhport, uint32_t frame_count) } } -#endif +#endif // (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER) + +#if (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER) + // Iterate over audio functions and call callback function + for(uint8_t i=0; i < CFG_TUD_AUDIO; i++) + { + audiod_function_t* audio = &_audiod_fct[i]; + + if (audio->ep_fb != 0) + { + tud_audio_sof_isr_cb(i, frame_count); + } + } + +#endif // (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER) + +#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP } bool tud_audio_buffer_and_schedule_control_xfer(uint8_t rhport, tusb_control_request_t const * p_request, void* data, uint16_t len) @@ -2416,7 +2452,7 @@ static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER static bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) #else bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index e5eaed9c7..e8721cf27 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -191,13 +191,24 @@ #define CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION 0 // 0 or 1 #endif +// Possible options for determination of feedback value +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER 1 // Feedback value must be determined by the user itself and set by use of tud_audio_n_fb_set(). The feedback value may be determined e.g. from some fill status of some FIFO buffer. Advantage: No ISR interrupt is enabled, hence the CPU need not to handle an ISR every 1ms or 125us and thus less CPU load, disadvantage: typically a larger FIFO is needed to compensate for jitter (e.g. 8 frames), i.e. a larger delay is introduced. +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER 2 // Feedback value is calculated within the audio driver by use of SOF interrupt. The driver needs information about the master clock f_m from which the audio sample frequency f_s is derived, f_s itself, and the cycle count of f_m at time of the SOF interrupt (e.g. by use of a hardware counter) - see tud_audio_set_fb_params(). Advantage: Reduced jitter in the feedback value computation, hence, the receive FIFO can be smaller (e.g. 2 frames) and thus a smaller delay is possible, disadvantage: higher CPU load due to SOF ISR handling every frame i.e. 1ms or 125us. This option is a great starting point to try the SOF ISR option but depending on your hardware setup (performance of the CPU) it might not work. If so, figure out why and use the next option. (The most critical point is the reading of the cycle counter value of f_m. It is read from within the SOF ISR - see: audiod_sof() -, hence, the ISR must has a high priority such that no software dependent "random" delay i.e. jitter is introduced). +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER 3 // Feedback value is determined by the user by use of SOF interrupt. The user may use tud_audio_sof_isr_cb() which is called every SOF (of course only invoked when an alternate interface other than zero was set). The number of frames used to determine the feedback value for the currently active alternate setting can be get by tud_audio_get_fb_n_frames(). The feedback value must be set by use of tud_audio_n_fb_set(). + // Determine feedback value within SOF ISR within audio driver - if disabled the user has to call tud_audio_n_fb_set() with a suitable feedback value on its own. If done within audio driver SOF ISR, tud_audio_n_fb_set() is disabled for user -#ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR -#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR 0 // 0 or 1 +#ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER +#endif + +#ifdef CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION +#if (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION != CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION != CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION != CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER) +#error Unknown CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION. Possible choices are: CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER, CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER, or CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER! +#endif #endif // Feeback calculation mode -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER #define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT 1 #define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT 2 @@ -484,6 +495,8 @@ TU_ATTR_WEAK bool tud_audio_rx_done_post_read_cb(uint8_t rhport, uint16_t n_byte #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP TU_ATTR_WEAK bool tud_audio_fb_done_cb(uint8_t rhport); +#if (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER) + // This function is used to provide data rate feedback from an asynchronous sink. Feedback value will be sent at FB endpoint interval till it's changed. // // The feedback format is specified to be 16.16 for HS and 10.14 for FS devices (see Universal Serial Bus Specification Revision 2.0 5.12.4.2). By default, @@ -494,15 +507,16 @@ TU_ATTR_WEAK bool tud_audio_fb_done_cb(uint8_t rhport); // driver can work with either format. So a good compromise is to keep format correction disabled and stick to 16.16 format. // Feedback value can be determined from within the SOF ISR of the audio driver. This should reduce jitter. If the feature is used, the user can not set the feedback value. -# if !CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR + bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); static inline bool tud_audio_fb_set(uint32_t feedback); -# else -// This callback function is called once the feedback value needs to be updated within the SOF ISR in the audio class. To determine the feedback value, some -// parameters need to be given. The user must implement this callback function and provide the current cycle count of the master clock. -// The feedback endpoint number can be used to identify the correct audio function in case multiple audio functions were defined. -TU_ATTR_WEAK uint32_t tud_audio_n_get_fm_n_cycles_cb(uint8_t rhport, uint8_t ep_fb); +uint8_t tud_audio_n_get_fb_n_frames(uint8_t func_id); +static inline uint8_t tud_audio_get_fb_n_frames(); + +#endif // (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER) + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER // f_m : Main clock frequency in Hz i.e. master clock to which sample clock is locked // f_s : Current sample rate in Hz @@ -513,10 +527,34 @@ TU_ATTR_WEAK uint32_t tud_audio_n_get_fm_n_cycles_cb(uint8_t rhport, uint8_t ep_ // uint8_t const alt = tu_u16_low(p_request->wValue); // such that tud_audio_set_fb_params() gets called with the parameters corresponding to the defined interface and alternate setting // Also, start the main clock cycle counter (or reset its value) within tud_audio_set_itf_cb() -TU_ATTR_WEAK bool tud_audio_set_fb_params(uint8_t func_id, uint32_t f_m, uint32_t f_s, uint32_t * p_cycle_count); -#endif +bool tud_audio_set_fb_params(uint8_t func_id, uint32_t f_m, uint32_t f_s, uint32_t * p_cycle_count); -#endif +#endif // CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER + +#if (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER) + +// This function is used to provide data rate feedback from an asynchronous sink. Feedback value will be sent at FB endpoint interval till it's changed. +// +// The feedback format is specified to be 16.16 for HS and 10.14 for FS devices (see Universal Serial Bus Specification Revision 2.0 5.12.4.2). By default, +// the choice of format is left to the caller and feedback argument is sent as-is. If CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION is set, then tinyusb +// expects 16.16 format and handles the conversion to 10.14 on FS. +// +// Note that due to a bug in its USB Audio 2.0 driver, Windows currently requires 16.16 format for _all_ USB 2.0 devices. On Linux and macOS it seems the +// driver can work with either format. So a good compromise is to keep format correction disabled and stick to 16.16 format. + +// Feedback value can be determined from within the SOF ISR of the audio driver. This should reduce jitter. If the feature is used, the user can not set the feedback value. + +bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); +static inline bool tud_audio_fb_set(uint32_t feedback); + +uint8_t tud_audio_n_get_fb_n_frames(uint8_t func_id); +static inline uint8_t tud_audio_get_fb_n_frames(); + +TU_ATTR_WEAK void tud_audio_sof_isr_cb(uint8_t func_id, uint32_t frame); + +#endif // (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER) + +#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN TU_ATTR_WEAK bool tud_audio_int_ctr_done_cb(uint8_t rhport, uint16_t n_bytes_copied); @@ -657,11 +695,17 @@ static inline uint16_t tud_audio_int_ctr_write(uint8_t const* buffer, uint16_t l } #endif -#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && !CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_WITHIN_SOF_ISR +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && ((CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER) || (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER)) static inline bool tud_audio_fb_set(uint32_t feedback) { return tud_audio_n_fb_set(0, feedback); } + +static inline uint8_t tud_audio_get_fb_n_frames() +{ + return tud_audio_n_get_fb_n_frames(0); +} + #endif //--------------------------------------------------------------------+ From cc5a4720e5c1295eacf02c7b81fc4454f29cfaa4 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 14 Apr 2022 21:51:49 +0700 Subject: [PATCH 287/504] catch up with pio lib --- .../hid_boot_interface/src/tusb_config.h | 3 + hw/bsp/rp2040/family.cmake | 5 +- lib/Pico-PIO-USB | 2 +- .../raspberrypi/pio_usb/dcd_pio_usb.c | 234 ++++++++++++++++++ .../raspberrypi/pio_usb/hcd_pio_usb.c | 28 +-- 5 files changed, 254 insertions(+), 18 deletions(-) create mode 100644 src/portable/raspberrypi/pio_usb/dcd_pio_usb.c diff --git a/examples/device/hid_boot_interface/src/tusb_config.h b/examples/device/hid_boot_interface/src/tusb_config.h index d4f67e7ba..c8bb8a807 100644 --- a/examples/device/hid_boot_interface/src/tusb_config.h +++ b/examples/device/hid_boot_interface/src/tusb_config.h @@ -41,6 +41,9 @@ // Use raspberry pio-usb for device #define CFG_TUD_RPI_PIO_USB 1 +#if CFG_TUD_RPI_PIO_USB +#define BOARD_DEVICE_RHPORT_NUM 1 +#endif // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_DEVICE_RHPORT_NUM diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index b186fc78e..d872c35ea 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -31,6 +31,7 @@ if (NOT TARGET _rp2040_family_inclusion_marker) ${TOP}/src/common/tusb_fifo.c ${TOP}/lib/Pico-PIO-USB/pio_usb.c ${TOP}/lib/Pico-PIO-USB/pio_usb_host.c + ${TOP}/lib/Pico-PIO-USB/pio_usb_device.c ${TOP}/lib/Pico-PIO-USB/pio_usb_hw.c ${TOP}/lib/Pico-PIO-USB/usb_crc.c ) @@ -69,8 +70,8 @@ if (NOT TARGET _rp2040_family_inclusion_marker) add_library(tinyusb_device_base INTERFACE) target_sources(tinyusb_device_base INTERFACE ${TOP}/src/portable/raspberrypi/rp2040/dcd_rp2040.c - ${TOP}/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c ${TOP}/src/portable/raspberrypi/rp2040/rp2040_usb.c + ${TOP}/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c ${TOP}/src/device/usbd.c ${TOP}/src/device/usbd_control.c ${TOP}/src/class/audio/audio_device.c @@ -92,13 +93,13 @@ if (NOT TARGET _rp2040_family_inclusion_marker) target_sources(tinyusb_host_base INTERFACE ${TOP}/src/portable/raspberrypi/rp2040/hcd_rp2040.c ${TOP}/src/portable/raspberrypi/rp2040/rp2040_usb.c + ${TOP}/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c ${TOP}/src/host/usbh.c ${TOP}/src/host/hub.c ${TOP}/src/class/cdc/cdc_host.c ${TOP}/src/class/hid/hid_host.c ${TOP}/src/class/msc/msc_host.c ${TOP}/src/class/vendor/vendor_host.c - ${TOP}/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c ) # Sometimes have to do host specific actions in mostly common functions diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB index 4993f4a1d..84a00b976 160000 --- a/lib/Pico-PIO-USB +++ b/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit 4993f4a1df03c8af13c8091052a6274e8c333bc0 +Subproject commit 84a00b976041d8c34cf660fda6fa88198c9721dc diff --git a/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c new file mode 100644 index 000000000..08d8b6086 --- /dev/null +++ b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c @@ -0,0 +1,234 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2018, hathach (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_TUSB_MCU == OPT_MCU_RP2040) && CFG_TUD_RPI_PIO_USB + +#include "pico.h" +#include "hardware/pio.h" +#include "pio_usb.h" + +#include "device/dcd.h" + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ + +#define RHPORT_OFFSET 1 +#define RHPORT_PIO(_x) ((_x)-RHPORT_OFFSET) + +static uint8_t new_addr = 0; + +//------------- -------------// +static usb_device_t *usb_device = NULL; +static usb_descriptor_buffers_t desc; + +/*------------------------------------------------------------------*/ +/* Device API + *------------------------------------------------------------------*/ + +// Initialize controller to device mode +void dcd_init (uint8_t rhport) +{ + (void) rhport; + + static pio_usb_configuration_t config = PIO_USB_DEFAULT_CONFIG; + usb_device = pio_usb_device_init(&config, &desc); +} + +// Enable device interrupt +void dcd_int_enable (uint8_t rhport) +{ + (void) rhport; +} + +// Disable device interrupt +void dcd_int_disable (uint8_t rhport) +{ + (void) rhport; +} + +// Receive Set Address request, mcu port must also include status IN response +void dcd_set_address (uint8_t rhport, uint8_t dev_addr) +{ + // store addr, will update crc5 lut when status is complete + new_addr = dev_addr; + + dcd_edpt_xfer(rhport, 0x80, NULL, 0); +} + +// Wake up host +void dcd_remote_wakeup (uint8_t rhport) +{ + (void) rhport; +} + +// Connect by enabling internal pull-up resistor on D+/D- +void dcd_connect(uint8_t rhport) +{ + (void) rhport; +} + +// Disconnect by disabling internal pull-up resistor on D+/D- +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; +} + +//--------------------------------------------------------------------+ +// Endpoint API +//--------------------------------------------------------------------+ + +// Configure endpoint's registers according to descriptor +bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) +{ + (void) rhport; + (void) ep_desc; + return false; +} + +void dcd_edpt_close_all (uint8_t rhport) +{ + (void) rhport; +} + +// 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) +{ + uint8_t pio_rhport = RHPORT_PIO(rhport); + return pio_usb_device_endpoint_transfer(pio_rhport, ep_addr, buffer, total_bytes); +} + +// Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack - optional, however, must be listed in usbd.c +bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) +{ + (void) rhport; + (void) ep_addr; + (void) ff; + (void) total_bytes; + return false; +} + +// Stall endpoint +void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + (void) ep_addr; +} + +// clear stall, data toggle is also reset to DATA0 +void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + (void) ep_addr; +} + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ +extern void update_ep0_crc5_lut(uint8_t addr); + +static void __no_inline_not_in_flash_func(handle_endpoint_irq)(pio_hw_root_port_t* port, uint32_t flag) +{ + volatile uint32_t* ep_reg; + xfer_result_t result; + + if ( flag == PIO_USB_INTS_ENDPOINT_COMPLETE_BITS ) + { + ep_reg = &port->ep_complete; + result = XFER_RESULT_SUCCESS; + } + else if ( flag == PIO_USB_INTS_ENDPOINT_ERROR_BITS ) + { + ep_reg = &port->ep_error; + result = XFER_RESULT_FAILED; + } + else if ( flag == PIO_USB_INTS_ENDPOINT_STALLED_BITS ) + { + ep_reg = &port->ep_stalled; + result = XFER_RESULT_STALLED; + } + else + { + // something wrong + return; + } + + const uint32_t ep_all = *ep_reg; + + for(uint8_t ep_idx = 0; ep_idx < PIO_USB_EP_POOL_CNT; ep_idx++) + { + uint32_t const mask = (1u << ep_idx); + + if (ep_all & mask) + { + pio_hw_endpoint_t* ep = PIO_USB_HW_EP(ep_idx); + uint8_t const tu_rhport = port - PIO_USB_HW_RPORT(0) + 1; + + // address is changed, update crc5 lut + if (new_addr && ep->ep_num == 0x80 && ep->actual_len == 0) + { + update_ep0_crc5_lut(new_addr); + new_addr = 0; + } + + dcd_event_xfer_complete(tu_rhport, ep->ep_num, ep->actual_len, result, true); + } + } + + // clear all + (*ep_reg) &= ~ep_all; +} + +// IRQ Handler +void __no_inline_not_in_flash_func(pio_usb_device_irq_handler)(uint8_t root_id) +{ + uint8_t const tu_rhport = root_id + 1; + pio_hw_root_port_t* port = PIO_USB_HW_RPORT(root_id); + uint32_t const ints = port->ints; + + if (ints & PIO_USB_INTS_RESET_END_BITS) + { + new_addr = 0; + dcd_event_bus_reset(tu_rhport, TUSB_SPEED_FULL, true); + } + + if (ints & PIO_USB_INTS_SETUP_REQ_BITS) + { + dcd_event_setup_received(tu_rhport, port->setup_packet, true); + } + + if ( ints & PIO_USB_INTS_ENDPOINT_COMPLETE_BITS ) + { + handle_endpoint_irq(port, PIO_USB_INTS_ENDPOINT_COMPLETE_BITS); + } + + // clear all + port->ints &= ~ints; +} + +#endif diff --git a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c index c2ef54b9e..4bd318448 100644 --- a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c @@ -116,19 +116,19 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const bool const need_pre = (dev_tree.hub_addr && dev_tree.speed == TUSB_SPEED_LOW); rhport = RHPORT_PIO(rhport); - return pio_usb_endpoint_open(rhport, dev_addr, (uint8_t const*) desc_ep, need_pre); + return pio_usb_host_endpoint_open(rhport, dev_addr, (uint8_t const*) desc_ep, need_pre); } bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) { rhport = RHPORT_PIO(rhport); - return pio_usb_endpoint_transfer(rhport, dev_addr, ep_addr, buffer, buflen); + return pio_usb_host_endpoint_transfer(rhport, dev_addr, ep_addr, buffer, buflen); } bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) { rhport = RHPORT_PIO(rhport); - return pio_usb_endpoint_send_setup(rhport, dev_addr, setup_packet); + return pio_usb_host_send_setup(rhport, dev_addr, setup_packet); } //bool hcd_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) @@ -153,7 +153,7 @@ bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) return true; } -void __no_inline_not_in_flash_func(handle_endpoint_irq)(pio_hw_root_port_t* port, uint32_t flag) +static void __no_inline_not_in_flash_func(handle_endpoint_irq)(pio_hw_root_port_t* port, uint32_t flag) { volatile uint32_t* ep_reg; xfer_result_t result; @@ -200,37 +200,35 @@ void __no_inline_not_in_flash_func(handle_endpoint_irq)(pio_hw_root_port_t* port void __no_inline_not_in_flash_func(pio_usb_host_irq_handler)(uint8_t root_id) { pio_hw_root_port_t* port = PIO_USB_HW_RPORT(root_id); + uint32_t const ints = port->ints; - if ( port->ints & PIO_USB_INTS_CONNECT_BITS ) + if ( ints & PIO_USB_INTS_CONNECT_BITS ) { - port->ints &= ~PIO_USB_INTS_CONNECT_BITS; - hcd_event_device_attach(root_id+1, true); } - if ( port->ints & PIO_USB_INTS_DISCONNECT_BITS ) + if ( ints & PIO_USB_INTS_DISCONNECT_BITS ) { - port->ints &= ~PIO_USB_INTS_DISCONNECT_BITS; hcd_event_device_remove(root_id+1, true); } - if ( port->ints & PIO_USB_INTS_ENDPOINT_COMPLETE_BITS ) + if ( ints & PIO_USB_INTS_ENDPOINT_COMPLETE_BITS ) { - port->ints &= ~PIO_USB_INTS_ENDPOINT_COMPLETE_BITS; handle_endpoint_irq(port, PIO_USB_INTS_ENDPOINT_COMPLETE_BITS); } - if ( port->ints & PIO_USB_INTS_ENDPOINT_ERROR_BITS ) + if ( ints & PIO_USB_INTS_ENDPOINT_ERROR_BITS ) { - port->ints &= ~PIO_USB_INTS_ENDPOINT_ERROR_BITS; handle_endpoint_irq(port, PIO_USB_INTS_ENDPOINT_ERROR_BITS); } - if ( port->ints & PIO_USB_INTS_ENDPOINT_STALLED_BITS ) + if ( ints & PIO_USB_INTS_ENDPOINT_STALLED_BITS ) { - port->ints &= ~PIO_USB_INTS_ENDPOINT_STALLED_BITS; handle_endpoint_irq(port, PIO_USB_INTS_ENDPOINT_STALLED_BITS); } + + // clear all + port->ints &= ~ints; } #endif From 05bfc1a9eba9fc901c35bdd1844cf962c5732310 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 15 Apr 2022 01:04:12 +0700 Subject: [PATCH 288/504] pio device works well --- examples/device/hid_boot_interface/src/main.c | 2 - lib/Pico-PIO-USB | 2 +- .../raspberrypi/pio_usb/dcd_pio_usb.c | 45 +++++++------------ 3 files changed, 18 insertions(+), 31 deletions(-) diff --git a/examples/device/hid_boot_interface/src/main.c b/examples/device/hid_boot_interface/src/main.c index ed7f235b7..031b17a2e 100644 --- a/examples/device/hid_boot_interface/src/main.c +++ b/examples/device/hid_boot_interface/src/main.c @@ -61,8 +61,6 @@ int main(void) while (1) { - pio_usb_device_task(); - tud_task(); // tinyusb device task led_blinking_task(); diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB index 84a00b976..d2b37b42b 160000 --- a/lib/Pico-PIO-USB +++ b/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit 84a00b976041d8c34cf660fda6fa88198c9721dc +Subproject commit d2b37b42befb6c761433b3c164c59a049721762f diff --git a/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c index 08d8b6086..dc9cbb45b 100644 --- a/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c @@ -41,8 +41,6 @@ #define RHPORT_OFFSET 1 #define RHPORT_PIO(_x) ((_x)-RHPORT_OFFSET) -static uint8_t new_addr = 0; - //------------- -------------// static usb_device_t *usb_device = NULL; static usb_descriptor_buffers_t desc; @@ -75,10 +73,12 @@ void dcd_int_disable (uint8_t rhport) // Receive Set Address request, mcu port must also include status IN response void dcd_set_address (uint8_t rhport, uint8_t dev_addr) { - // store addr, will update crc5 lut when status is complete - new_addr = dev_addr; + uint8_t const pio_rhport = RHPORT_PIO(rhport); - dcd_edpt_xfer(rhport, 0x80, NULL, 0); + // must be called before queuing status + pio_usb_device_set_address(pio_rhport, dev_addr); + + pio_usb_device_endpoint_transfer(pio_rhport, 0x80, NULL, 0); } // Wake up host @@ -104,11 +104,10 @@ void dcd_disconnect(uint8_t rhport) //--------------------------------------------------------------------+ // Configure endpoint's registers according to descriptor -bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) +bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) { - (void) rhport; - (void) ep_desc; - return false; + uint8_t const pio_rhport = RHPORT_PIO(rhport); + return pio_usb_device_endpoint_open(pio_rhport, (uint8_t const*) desc_ep); } void dcd_edpt_close_all (uint8_t rhport) @@ -119,19 +118,19 @@ void dcd_edpt_close_all (uint8_t rhport) // 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) { - uint8_t pio_rhport = RHPORT_PIO(rhport); + uint8_t const pio_rhport = RHPORT_PIO(rhport); return pio_usb_device_endpoint_transfer(pio_rhport, ep_addr, buffer, total_bytes); } // Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack - optional, however, must be listed in usbd.c -bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) -{ - (void) rhport; - (void) ep_addr; - (void) ff; - (void) total_bytes; - return false; -} +//bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) +//{ +// (void) rhport; +// (void) ep_addr; +// (void) ff; +// (void) total_bytes; +// return false; +//} // Stall endpoint void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) @@ -150,7 +149,6 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ -extern void update_ep0_crc5_lut(uint8_t addr); static void __no_inline_not_in_flash_func(handle_endpoint_irq)(pio_hw_root_port_t* port, uint32_t flag) { @@ -188,14 +186,6 @@ static void __no_inline_not_in_flash_func(handle_endpoint_irq)(pio_hw_root_port_ { pio_hw_endpoint_t* ep = PIO_USB_HW_EP(ep_idx); uint8_t const tu_rhport = port - PIO_USB_HW_RPORT(0) + 1; - - // address is changed, update crc5 lut - if (new_addr && ep->ep_num == 0x80 && ep->actual_len == 0) - { - update_ep0_crc5_lut(new_addr); - new_addr = 0; - } - dcd_event_xfer_complete(tu_rhport, ep->ep_num, ep->actual_len, result, true); } } @@ -213,7 +203,6 @@ void __no_inline_not_in_flash_func(pio_usb_device_irq_handler)(uint8_t root_id) if (ints & PIO_USB_INTS_RESET_END_BITS) { - new_addr = 0; dcd_event_bus_reset(tu_rhport, TUSB_SPEED_FULL, true); } From 00a0e3f21ba588f892022159e435938b48305b99 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 15 Apr 2022 20:14:47 +0700 Subject: [PATCH 289/504] update lib pio --- lib/Pico-PIO-USB | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB index d2b37b42b..ed84b4de8 160000 --- a/lib/Pico-PIO-USB +++ b/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit d2b37b42befb6c761433b3c164c59a049721762f +Subproject commit ed84b4de88e7c22bb56cb53bf85f1a2c5dd8b8fc From b5a9537eea81bd6ffd8d575dbd2b5823c2fc1f0e Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 16 Apr 2022 01:19:51 +0700 Subject: [PATCH 290/504] support pio dcd endpiont stall --- lib/Pico-PIO-USB | 2 +- src/portable/raspberrypi/pio_usb/dcd_pio_usb.c | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB index ed84b4de8..d6712cad5 160000 --- a/lib/Pico-PIO-USB +++ b/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit ed84b4de88e7c22bb56cb53bf85f1a2c5dd8b8fc +Subproject commit d6712cad5bfbddb25647974f0d583596e703c06f diff --git a/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c index dc9cbb45b..7744a11cd 100644 --- a/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c @@ -136,14 +136,17 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) { (void) rhport; - (void) ep_addr; + pio_hw_endpoint_t *ep = pio_usb_device_get_ep(ep_addr); + ep->stalled = true; } // clear stall, data toggle is also reset to DATA0 void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) { (void) rhport; - (void) ep_addr; + pio_hw_endpoint_t *ep = pio_usb_device_get_ep(ep_addr); + ep->data_id = 0; + ep->stalled = false; } //--------------------------------------------------------------------+ From 11f0ffd9a833f4ea9b28fd12f4dff03e9bb99331 Mon Sep 17 00:00:00 2001 From: Reinhard Panhuber Date: Sat, 16 Apr 2022 14:47:42 +0200 Subject: [PATCH 291/504] Generalize feedback value min and max --- src/class/audio/audio_device.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 2e2653e48..b0a49fb04 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -312,6 +312,8 @@ typedef struct #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER volatile uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). + uint32_t fb_val_min; // Maximum allowed feedback value according to UAC2 FMT-2.0 section 2.3.1.1. + uint32_t fb_val_max; // Maximum allowed feedback value according to UAC2 FMT-2.0 section 2.3.1.1. uint8_t fb_n_frames; // Number of (micro)frames used to estimate feedback value volatile uint8_t fb_n_frames_current; // Current (micro)frame number volatile uint32_t fb_n_cycles_old; // Old cycle count @@ -2094,6 +2096,9 @@ TU_ATTR_WEAK bool tud_audio_set_fb_params(uint8_t func_id, uint32_t f_m, uint32_ audio->fb_param_factor_D = (uint64_t)f_m * audio->fb_n_frames; #endif + audio->fb_val_min = ((TUSB_SPEED_FULL == tud_speed_get() ? (f_s/1000) : (f_s/8000)) - 1) << 16; // Minimal value in 16.16 format for full speed (1ms per frame) or high speed (125 us per frame) + audio->fb_val_max = ((TUSB_SPEED_FULL == tud_speed_get() ? (f_s/1000) : (f_s/8000)) + 1) << 16; // Maximum value in 16.16 format + return true; } @@ -2139,16 +2144,18 @@ TU_ATTR_WEAK void audiod_sof (uint8_t rhport, uint32_t frame_count) feedback = ((n_cylces - audio->fb_n_cycles_old) << 3) * audio->fb_param_factor_N / audio->fb_param_factor_D; // feeback_param_factor_N has scaling factor of 13 bits, n_cycles 3 and feeback_param_factor_D 1, hence 16.16 precision #endif - // Buffer count checks ? + // For Windows: https://docs.microsoft.com/en-us/windows-hardware/drivers/audio/usb-2-0-audio-drivers + // The size of isochronous packets created by the device must be within the limits specified in FMT-2.0 section 2.3.1.1. This means that the deviation of actual packet size from nominal size must not exceed +/- one audio slot (audio slot = channel count samples). - // Magic checks - where are they from? - if (feedback > 2949166){ // 45.0007 in 16.16 format - feedback = 2949166; + if (feedback > audio->fb_val_max){ + feedback = audio->fb_val_max; } - if ( feedback < 2883630) { // 44.0007 in 16.16 format - feedback = 2883630; + if ( feedback < audio->fb_val_min) { + feedback = audio->fb_val_min; } + // Buffer count checks ? + tud_audio_n_fb_set(i, feedback); audio->fb_n_frames_current = 0; audio->fb_n_cycles_old = n_cylces; From 16c13bc110fb0959e704b417706dd303afc69981 Mon Sep 17 00:00:00 2001 From: Skyler Mansfield Date: Sun, 17 Apr 2022 01:16:49 +0100 Subject: [PATCH 292/504] tusb_types: Added descriptive strings for edpt_dir and edpt_type --- src/common/tusb_types.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index e2fa17532..7eab396ef 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -513,6 +513,16 @@ static inline uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const* desc_ep) return tu_le16toh(desc_ep->wMaxPacketSize) & TU_GENMASK(10, 0); } +static inline const char *tu_edpt_dir_str(tusb_dir_t dir) { + static const char *str[] = {"out", "in"}; + return str[dir]; +} + +static inline const char *tu_edpt_type_str(tusb_xfer_type_t t) { + static const char *str[] = {"control", "isochronous", "bulk", "interrupt"}; + return str[t]; +} + //--------------------------------------------------------------------+ // Descriptor helper //--------------------------------------------------------------------+ From 35668fc523c7c972bf91f32dbb3b50ad8b4f3c74 Mon Sep 17 00:00:00 2001 From: Skyler Mansfield Date: Sun, 17 Apr 2022 01:30:03 +0100 Subject: [PATCH 293/504] hcd_rp2040: Add bulk in/out+interrupt out support. Added support for allocating hw_endpoints for non-interrupt endpoints. Allow endpoints to be used in either direction by updating bit checks. --- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 33 +++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 234bea203..0c7a5220d 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -139,16 +139,20 @@ static void hw_handle_buff_status(void) for (uint i = 1; i <= USB_HOST_INTERRUPT_ENDPOINTS && remaining_buffers; i++) { // EPX is bit 0 - // IEP1 is bit 2 - // IEP2 is bit 4 - // IEP3 is bit 6 + // IEP1 IN is bit 2 + // IEP1 OUT is bit 3 + // IEP2 IN is bit 4 + // IEP2 OUT is bit 5 + // IEP3 IN is bit 6 + // IEP3 OUT is bit 7 // etc - bit = 1 << (i*2); - - if (remaining_buffers & bit) - { - remaining_buffers &= ~bit; - _handle_buff_status_bit(bit, &ep_pool[i]); + for(int 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]); + } } } @@ -259,10 +263,10 @@ static struct hw_endpoint *_hw_endpoint_allocate(uint8_t transfer_type) { struct hw_endpoint *ep = NULL; - if (transfer_type == TUSB_XFER_INTERRUPT) + if (transfer_type != TUSB_XFER_CONTROL) { ep = _next_free_interrupt_ep(); - pico_info("Allocate interrupt ep %d\n", ep->interrupt_num); + 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; @@ -320,8 +324,9 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t pico_trace("endpoint control (0x%p) <- 0x%x\n", ep->endpoint_control, ep_reg); ep->configured = true; - if (bmInterval) + if (ep != &epx) { + // Endpoint has its own addr_endp and interrupt bits to be setup! // This is an interrupt endpoint // so need to set up interrupt endpoint address control register with: // device address @@ -492,6 +497,9 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * // Get appropriate ep. Either EPX or interrupt endpoint struct hw_endpoint *ep = get_dev_ep(dev_addr, ep_addr); assert(ep); + // Should we maybe be able to check if endpt is busy/active instead? + if(ep->active) + return false; // Control endpoint can change direction 0x00 <-> 0x80 if ( ep_addr != ep->ep_addr ) @@ -535,6 +543,7 @@ 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(0); + assert(ep == &epx); // EP0 out _hw_endpoint_init(ep, dev_addr, 0x00, ep->wMaxPacketSize, 0, 0); From a32cb1bb93ce986af9ed83f5d378c26bb4df2b1e Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 18 Apr 2022 17:49:21 +0700 Subject: [PATCH 294/504] clean up pio driver --- lib/Pico-PIO-USB | 2 +- src/device/dcd.h | 32 ++++++++++++++--- src/device/usbd.c | 36 ++----------------- src/device/usbd.h | 2 +- .../raspberrypi/pio_usb/dcd_pio_usb.c | 7 ++-- .../raspberrypi/pio_usb/hcd_pio_usb.c | 6 ++-- 6 files changed, 39 insertions(+), 46 deletions(-) diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB index d6712cad5..98e3feefc 160000 --- a/lib/Pico-PIO-USB +++ b/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit d6712cad5bfbddb25647974f0d583596e703c06f +Subproject commit 98e3feefcd1c7218bced0ea2ea35530fd1b550e4 diff --git a/src/device/dcd.h b/src/device/dcd.h index 8efbc90ef..bc68c9be6 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -174,16 +174,40 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr); extern void dcd_event_handler(dcd_event_t const * event, bool in_isr); // helper to send bus signal event -extern void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr); +TU_ATTR_ALWAYS_INLINE static inline void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr) +{ + dcd_event_t event = { .rhport = rhport, .event_id = eid }; + dcd_event_handler(&event, in_isr); +} // helper to send bus reset event -extern void dcd_event_bus_reset (uint8_t rhport, tusb_speed_t speed, bool in_isr); +TU_ATTR_ALWAYS_INLINE static inline void dcd_event_bus_reset (uint8_t rhport, tusb_speed_t speed, bool in_isr) +{ + dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_BUS_RESET }; + event.bus_reset.speed = speed; + dcd_event_handler(&event, in_isr); +} // helper to send setup received -extern void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr); +TU_ATTR_ALWAYS_INLINE static inline void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr) +{ + dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SETUP_RECEIVED }; + memcpy(&event.setup_received, setup, 8); + + dcd_event_handler(&event, in_isr); +} // helper to send transfer complete event -extern void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr); +TU_ATTR_ALWAYS_INLINE static inline void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr) +{ + dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_XFER_COMPLETE }; + + event.xfer_complete.ep_addr = ep_addr; + event.xfer_complete.len = xferred_bytes; + event.xfer_complete.result = result; + + dcd_event_handler(&event, in_isr); +} #ifdef __cplusplus } diff --git a/src/device/usbd.c b/src/device/usbd.c index 7ab2660f4..8d5d54b86 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -265,7 +265,7 @@ static inline usbd_class_driver_t const * get_driver(uint8_t drvid) //--------------------------------------------------------------------+ enum { RHPORT_INVALID = 0xFFu }; -static uint8_t _usbd_rhport = RHPORT_INVALID; +static volatile uint8_t _usbd_rhport = RHPORT_INVALID; // Event queue // usbd_int_set() is used as mutex in OS NONE config @@ -1065,7 +1065,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const //--------------------------------------------------------------------+ // DCD Event Handler //--------------------------------------------------------------------+ -void dcd_event_handler(dcd_event_t const * event, bool in_isr) +void __no_inline_not_in_flash_func(dcd_event_handler)(dcd_event_t const * event, bool in_isr) { switch (event->event_id) { @@ -1115,38 +1115,6 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr) } } -void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr) -{ - dcd_event_t event = { .rhport = rhport, .event_id = eid }; - dcd_event_handler(&event, in_isr); -} - -void dcd_event_bus_reset (uint8_t rhport, tusb_speed_t speed, bool in_isr) -{ - dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_BUS_RESET }; - event.bus_reset.speed = speed; - dcd_event_handler(&event, in_isr); -} - -void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr) -{ - dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SETUP_RECEIVED }; - memcpy(&event.setup_received, setup, 8); - - dcd_event_handler(&event, in_isr); -} - -void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr) -{ - dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_XFER_COMPLETE }; - - event.xfer_complete.ep_addr = ep_addr; - event.xfer_complete.len = xferred_bytes; - event.xfer_complete.result = result; - - dcd_event_handler(&event, in_isr); -} - //--------------------------------------------------------------------+ // USBD API For Class Driver //--------------------------------------------------------------------+ diff --git a/src/device/usbd.h b/src/device/usbd.h index b2bf8ba9d..32c82e75a 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -46,7 +46,7 @@ bool tud_inited(void); // Task function should be called in main/rtos loop void tud_task (void); -// Check if there is pending events need proccessing by tud_task() +// Check if there is pending events need processing by tud_task() bool tud_task_event_ready(void); // Interrupt handler, name alias to DCD diff --git a/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c index 7744a11cd..38867ea1c 100644 --- a/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c @@ -78,7 +78,7 @@ void dcd_set_address (uint8_t rhport, uint8_t dev_addr) // must be called before queuing status pio_usb_device_set_address(pio_rhport, dev_addr); - pio_usb_device_endpoint_transfer(pio_rhport, 0x80, NULL, 0); + dcd_edpt_xfer(rhport, 0x80, NULL, 0); } // Wake up host @@ -118,8 +118,9 @@ void dcd_edpt_close_all (uint8_t rhport) // 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) { - uint8_t const pio_rhport = RHPORT_PIO(rhport); - return pio_usb_device_endpoint_transfer(pio_rhport, ep_addr, buffer, total_bytes); + (void) rhport; + pio_hw_endpoint_t *ep = pio_usb_device_get_ep(ep_addr); + return pio_usb_endpoint_transfer(ep, buffer, total_bytes); } // Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack - optional, however, must be listed in usbd.c diff --git a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c index 4bd318448..e311f16d0 100644 --- a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c @@ -51,7 +51,7 @@ static pio_usb_configuration_t pio_host_config = PIO_USB_DEFAULT_CONFIG; bool hcd_init(uint8_t rhport) { // To run USB SOF interrupt in core1, call this init in core1 - pio_usb_host_controller_init(&pio_host_config); + pio_usb_host_init(&pio_host_config); return true; } @@ -59,13 +59,13 @@ bool hcd_init(uint8_t rhport) void hcd_port_reset(uint8_t rhport) { rhport = RHPORT_PIO(rhport); - pio_usb_hw_port_reset_start(rhport); + pio_usb_host_port_reset_start(rhport); } void hcd_port_reset_end(uint8_t rhport) { rhport = RHPORT_PIO(rhport); - pio_usb_hw_port_reset_end(rhport); + pio_usb_host_port_reset_end(rhport); } bool hcd_port_connect_status(uint8_t rhport) From 52190e7308c723df952c8bfced25f70d333e22fe Mon Sep 17 00:00:00 2001 From: Nikitarc Date: Tue, 19 Apr 2022 21:53:00 +0200 Subject: [PATCH 295/504] Update dwc2_stm32.h Support STM32H7 with only 1 USB port: H72x / H73x / H7Ax / H7Bx --- src/portable/synopsys/dwc2/dwc2_stm32.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index 469045ac4..c4a4d310f 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -56,6 +56,11 @@ #define EP_FIFO_SIZE_FS 4096 #define EP_MAX_HS 9 #define EP_FIFO_SIZE_HS 4096 + #if (! defined USB2_OTG_FS) + // H7 with only 1 USB port: H72x / H73x / H7Ax / H7Bx + // USB_OTG_FS_PERIPH_BASE and OTG_FS_IRQn not defined + #define USB_OTG_FS_PERIPH_BASE USB1_OTG_HS_PERIPH_BASE + #define OTG_FS_IRQn OTG_HS_IRQn #elif CFG_TUSB_MCU == OPT_MCU_STM32F7 #include "stm32f7xx.h" From a90839688c11338451729838e45ae3aaa58864fe Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 20 Apr 2022 13:25:38 +0700 Subject: [PATCH 296/504] add msec timeout to osal_queue_receive(), tud_task() and tuh_task() both pending for event queue with timeout of 1 ms --- src/device/usbd.c | 3 +- src/host/usbh.c | 2 +- src/osal/osal.h | 22 +++++++-------- src/osal/osal_freertos.h | 29 ++++++++++--------- src/osal/osal_mynewt.h | 22 ++++++++------- src/osal/osal_none.h | 28 +++++++++--------- src/osal/osal_pico.h | 44 +++++++++++++++-------------- src/osal/osal_rtthread.h | 28 +++++++++--------- src/osal/osal_rtx4.h | 28 +++++++++--------- src/portable/sony/cxd56/dcd_cxd56.c | 2 +- src/tusb_option.h | 2 +- 11 files changed, 109 insertions(+), 101 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 7ab2660f4..36b9c7cff 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -475,8 +475,7 @@ void tud_task (void) while (1) { dcd_event_t event; - - if ( !osal_queue_receive(_usbd_q, &event) ) return; + if ( !osal_queue_receive(_usbd_q, &event, 1) ) return; #if CFG_TUSB_DEBUG >= 2 if (event.event_id == DCD_EVENT_SETUP_RECEIVED) TU_LOG2("\r\n"); // extra line for setup diff --git a/src/host/usbh.c b/src/host/usbh.c index f534070de..ad90a1b1b 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -401,7 +401,7 @@ void tuh_task(void) while (1) { hcd_event_t event; - if ( !osal_queue_receive(_usbh_q, &event) ) return; + if ( !osal_queue_receive(_usbh_q, &event, 1) ) return; switch (event.event_id) { diff --git a/src/osal/osal.h b/src/osal/osal.h index 7111bbdb2..9d11866df 100644 --- a/src/osal/osal.h +++ b/src/osal/osal.h @@ -66,19 +66,19 @@ typedef void (*osal_task_func_t)( void * ); // OSAL Porting API // Should be implemented as static inline function in osal_port.h header /* - static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef); - static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr); - static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec); - static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl); // TODO removed + osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef); + bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr); + bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec); + void osal_semaphore_reset(osal_semaphore_t sem_hdl); // TODO removed - static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef); - static inline bool osal_mutex_lock (osal_mutex_t sem_hdl, uint32_t msec); - static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl); + osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef); + bool osal_mutex_lock (osal_mutex_t sem_hdl, uint32_t msec); + bool osal_mutex_unlock(osal_mutex_t mutex_hdl); - static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef); - static inline bool osal_queue_receive(osal_queue_t qhdl, void* data); - static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr); - static inline bool osal_queue_empty(osal_queue_t qhdl); + osal_queue_t osal_queue_create(osal_queue_def_t* qdef); + bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec); + bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr); + bool osal_queue_empty(osal_queue_t qhdl); */ //--------------------------------------------------------------------+ diff --git a/src/osal/osal_freertos.h b/src/osal/osal_freertos.h index 69a026df5..c3a0756e1 100644 --- a/src/osal/osal_freertos.h +++ b/src/osal/osal_freertos.h @@ -40,7 +40,7 @@ extern "C" { //--------------------------------------------------------------------+ // TASK API //--------------------------------------------------------------------+ -static inline void osal_task_delay(uint32_t msec) +TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { vTaskDelay( pdMS_TO_TICKS(msec) ); } @@ -51,12 +51,12 @@ static inline void osal_task_delay(uint32_t msec) typedef StaticSemaphore_t osal_semaphore_def_t; typedef SemaphoreHandle_t osal_semaphore_t; -static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) +TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) { return xSemaphoreCreateBinaryStatic(semdef); } -static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { if ( !in_isr ) { @@ -78,13 +78,13 @@ static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) } } -static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) { uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec); return xSemaphoreTake(sem_hdl, ticks); } -static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) +TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) { xQueueReset(sem_hdl); } @@ -95,17 +95,17 @@ static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) typedef StaticSemaphore_t osal_mutex_def_t; typedef SemaphoreHandle_t osal_mutex_t; -static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) +TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) { return xSemaphoreCreateMutexStatic(mdef); } -static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) { return osal_semaphore_wait(mutex_hdl, msec); } -static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { return xSemaphoreGive(mutex_hdl); } @@ -114,7 +114,7 @@ static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) // QUEUE API //--------------------------------------------------------------------+ -// role device/host is used by OS NONE for mutex (disable usb isr) only +// _int_set is not used with an RTOS #define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ static _type _name##_##buf[_depth];\ osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf }; @@ -130,17 +130,18 @@ typedef struct typedef QueueHandle_t osal_queue_t; -static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) +TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { return xQueueCreateStatic(qdef->depth, qdef->item_sz, (uint8_t*) qdef->buf, &qdef->sq); } -static inline bool osal_queue_receive(osal_queue_t qhdl, void* data) +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) { - return xQueueReceive(qhdl, data, portMAX_DELAY); + uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec); + return xQueueReceive(qhdl, data, ticks); } -static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) { if ( !in_isr ) { @@ -162,7 +163,7 @@ static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in } } -static inline bool osal_queue_empty(osal_queue_t qhdl) +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { return uxQueueMessagesWaiting(qhdl) == 0; } diff --git a/src/osal/osal_mynewt.h b/src/osal/osal_mynewt.h index 78a257cd6..b8ea2087c 100644 --- a/src/osal/osal_mynewt.h +++ b/src/osal/osal_mynewt.h @@ -36,7 +36,7 @@ //--------------------------------------------------------------------+ // TASK API //--------------------------------------------------------------------+ -static inline void osal_task_delay(uint32_t msec) +TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { os_time_delay( os_time_ms_to_ticks32(msec) ); } @@ -47,18 +47,18 @@ static inline void osal_task_delay(uint32_t msec) typedef struct os_sem osal_semaphore_def_t; typedef struct os_sem* osal_semaphore_t; -static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) +TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) { return (os_sem_init(semdef, 0) == OS_OK) ? (osal_semaphore_t) semdef : NULL; } -static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { (void) in_isr; return os_sem_release(sem_hdl) == OS_OK; } -static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? OS_TIMEOUT_NEVER : os_time_ms_to_ticks32(msec); return os_sem_pend(sem_hdl, ticks) == OS_OK; @@ -75,18 +75,18 @@ static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) typedef struct os_mutex osal_mutex_def_t; typedef struct os_mutex* osal_mutex_t; -static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) +TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) { return (os_mutex_init(mdef) == OS_OK) ? (osal_mutex_t) mdef : NULL; } -static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) { uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? OS_TIMEOUT_NEVER : os_time_ms_to_ticks32(msec); return os_mutex_pend(mutex_hdl, ticks) == OS_OK; } -static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { return os_mutex_release(mutex_hdl) == OS_OK; } @@ -116,7 +116,7 @@ typedef struct typedef osal_queue_def_t* osal_queue_t; -static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) +TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { if ( OS_OK != os_mempool_init(&qdef->mpool, qdef->depth, qdef->item_sz, qdef->buf, "usbd queue") ) return NULL; if ( OS_OK != os_mempool_init(&qdef->epool, qdef->depth, sizeof(struct os_event), qdef->evbuf, "usbd evqueue") ) return NULL; @@ -125,8 +125,10 @@ static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) return (osal_queue_t) qdef; } -static inline bool osal_queue_receive(osal_queue_t qhdl, void* data) +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) { + (void) msec; // os_eventq_get() does not take timeout, always behave as msec = WAIT_FOREVER + struct os_event* ev; ev = os_eventq_get(&qhdl->evq); @@ -161,7 +163,7 @@ static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in return true; } -static inline bool osal_queue_empty(osal_queue_t qhdl) +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { return STAILQ_EMPTY(&qhdl->evq.evq_list); } diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 4217f0422..9c80e4548 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -46,13 +46,13 @@ typedef struct typedef osal_semaphore_def_t* osal_semaphore_t; -static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) +TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) { semdef->count = 0; return semdef; } -static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { (void) in_isr; sem_hdl->count++; @@ -60,7 +60,7 @@ static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) } // TODO blocking for now -static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) { (void) msec; @@ -70,7 +70,7 @@ static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) return true; } -static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) +TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) { sem_hdl->count = 0; } @@ -82,18 +82,18 @@ static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) typedef osal_semaphore_def_t osal_mutex_def_t; typedef osal_semaphore_t osal_mutex_t; -static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) +TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) { mdef->count = 1; return mdef; } -static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) { return osal_semaphore_wait(mutex_hdl, msec); } -static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { return osal_semaphore_post(mutex_hdl, false); } @@ -120,27 +120,29 @@ typedef osal_queue_def_t* osal_queue_t; } // lock queue by disable USB interrupt -static inline void _osal_q_lock(osal_queue_t qhdl) +TU_ATTR_ALWAYS_INLINE static inline void _osal_q_lock(osal_queue_t qhdl) { // disable dcd/hcd interrupt qhdl->interrupt_set(false); } // unlock queue -static inline void _osal_q_unlock(osal_queue_t qhdl) +TU_ATTR_ALWAYS_INLINE static inline void _osal_q_unlock(osal_queue_t qhdl) { // enable dcd/hcd interrupt qhdl->interrupt_set(true); } -static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) +TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { tu_fifo_clear(&qdef->ff); return (osal_queue_t) qdef; } -static inline bool osal_queue_receive(osal_queue_t qhdl, void* data) +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) { + (void) msec; // not used, always behave as msec = 0 + _osal_q_lock(qhdl); bool success = tu_fifo_read(&qhdl->ff, data); _osal_q_unlock(qhdl); @@ -148,7 +150,7 @@ static inline bool osal_queue_receive(osal_queue_t qhdl, void* data) return success; } -static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) { if (!in_isr) { _osal_q_lock(qhdl); @@ -165,7 +167,7 @@ static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in return success; } -static inline bool osal_queue_empty(osal_queue_t qhdl) +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { // Skip queue lock/unlock since this function is primarily called // with interrupt disabled before going into low power mode diff --git a/src/osal/osal_pico.h b/src/osal/osal_pico.h index 70432d22b..abef286b4 100644 --- a/src/osal/osal_pico.h +++ b/src/osal/osal_pico.h @@ -39,7 +39,7 @@ //--------------------------------------------------------------------+ // TASK API //--------------------------------------------------------------------+ -static inline void osal_task_delay(uint32_t msec) +TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { sleep_ms(msec); } @@ -49,25 +49,25 @@ static inline void osal_task_delay(uint32_t msec) //--------------------------------------------------------------------+ typedef struct semaphore osal_semaphore_def_t, *osal_semaphore_t; -static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) +TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) { sem_init(semdef, 0, 255); return semdef; } -static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { (void) in_isr; sem_release(sem_hdl); return true; } -static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) { return sem_acquire_timeout_ms(sem_hdl, msec); } -static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) +TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) { sem_reset(sem_hdl, 0); } @@ -78,21 +78,21 @@ static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) //--------------------------------------------------------------------+ typedef struct mutex osal_mutex_def_t, *osal_mutex_t; -static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) +TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) { - mutex_init(mdef); - return mdef; + mutex_init(mdef); + return mdef; } -static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) { - return mutex_enter_timeout_ms(mutex_hdl, msec); + return mutex_enter_timeout_ms(mutex_hdl, msec); } -static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { - mutex_exit(mutex_hdl); - return true; + mutex_exit(mutex_hdl); + return true; } //--------------------------------------------------------------------+ @@ -121,26 +121,28 @@ typedef osal_queue_def_t* osal_queue_t; } // lock queue by disable USB interrupt -static inline void _osal_q_lock(osal_queue_t qhdl) +TU_ATTR_ALWAYS_INLINE static inline void _osal_q_lock(osal_queue_t qhdl) { - critical_section_enter_blocking(&qhdl->critsec); + critical_section_enter_blocking(&qhdl->critsec); } // unlock queue -static inline void _osal_q_unlock(osal_queue_t qhdl) +TU_ATTR_ALWAYS_INLINE static inline void _osal_q_unlock(osal_queue_t qhdl) { - critical_section_exit(&qhdl->critsec); + critical_section_exit(&qhdl->critsec); } -static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) +TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { critical_section_init(&qdef->critsec); tu_fifo_clear(&qdef->ff); return (osal_queue_t) qdef; } -static inline bool osal_queue_receive(osal_queue_t qhdl, void* data) +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) { + (void) msec; // not used, always behave as msec = 0 + // TODO: revisit... docs say that mutexes are never used from IRQ context, // however osal_queue_recieve may be. therefore my assumption is that // the fifo mutex is not populated for queues used from an IRQ context @@ -153,7 +155,7 @@ static inline bool osal_queue_receive(osal_queue_t qhdl, void* data) return success; } -static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) { // TODO: revisit... docs say that mutexes are never used from IRQ context, // however osal_queue_recieve may be. therefore my assumption is that @@ -170,7 +172,7 @@ static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in return success; } -static inline bool osal_queue_empty(osal_queue_t qhdl) +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { // TODO: revisit; whether this is true or not currently, tu_fifo_empty is a single // volatile read. diff --git a/src/osal/osal_rtthread.h b/src/osal/osal_rtthread.h index 0845175b8..a790a5e27 100644 --- a/src/osal/osal_rtthread.h +++ b/src/osal/osal_rtthread.h @@ -37,7 +37,7 @@ extern "C" { //--------------------------------------------------------------------+ // TASK API //--------------------------------------------------------------------+ -static inline void osal_task_delay(uint32_t msec) { +TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { rt_thread_mdelay(msec); } @@ -47,22 +47,22 @@ static inline void osal_task_delay(uint32_t msec) { typedef struct rt_semaphore osal_semaphore_def_t; typedef rt_sem_t osal_semaphore_t; -static inline osal_semaphore_t +TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t *semdef) { rt_sem_init(semdef, "tusb", 0, RT_IPC_FLAG_FIFO); return semdef; } -static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { (void) in_isr; return rt_sem_release(sem_hdl) == RT_EOK; } -static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { return rt_sem_take(sem_hdl, rt_tick_from_millisecond(msec)) == RT_EOK; } -static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) { +TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) { // TODO: implement } @@ -72,16 +72,16 @@ static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) { typedef struct rt_mutex osal_mutex_def_t; typedef rt_mutex_t osal_mutex_t; -static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t *mdef) { +TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t *mdef) { rt_mutex_init(mdef, "tusb", RT_IPC_FLAG_FIFO); return mdef; } -static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) { +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) { return rt_mutex_take(mutex_hdl, rt_tick_from_millisecond(msec)) == RT_EOK; } -static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { return rt_mutex_release(mutex_hdl) == RT_EOK; } @@ -104,22 +104,24 @@ typedef struct { typedef rt_mq_t osal_queue_t; -static inline osal_queue_t osal_queue_create(osal_queue_def_t *qdef) { +TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t *qdef) { rt_mq_init(&(qdef->sq), "tusb", qdef->buf, qdef->item_sz, qdef->item_sz * qdef->depth, RT_IPC_FLAG_FIFO); return &(qdef->sq); } -static inline bool osal_queue_receive(osal_queue_t qhdl, void *data) { - return rt_mq_recv(qhdl, data, qhdl->msg_size, RT_WAITING_FOREVER) == RT_EOK; +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void *data, uint32_t msec) { + + rt_tick_t tick = rt_tick_from_millisecond((rt_int32_t) msec)); + return rt_mq_recv(qhdl, data, qhdl->msg_size, tick) == RT_EOK; } -static inline bool osal_queue_send(osal_queue_t qhdl, void const *data, bool in_isr) { +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const *data, bool in_isr) { (void) in_isr; return rt_mq_send(qhdl, (void *)data, qhdl->msg_size) == RT_EOK; } -static inline bool osal_queue_empty(osal_queue_t qhdl) { +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { return (qhdl->entry) == 0; } diff --git a/src/osal/osal_rtx4.h b/src/osal/osal_rtx4.h index 1856a5d9a..dea1c12c8 100644 --- a/src/osal/osal_rtx4.h +++ b/src/osal/osal_rtx4.h @@ -37,7 +37,7 @@ extern "C" { //--------------------------------------------------------------------+ // TASK API //--------------------------------------------------------------------+ -static inline void osal_task_delay(uint32_t msec) +TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { uint16_t hi = msec >> 16; uint16_t lo = msec; @@ -47,7 +47,7 @@ static inline void osal_task_delay(uint32_t msec) os_dly_wait(lo); } -static inline uint16_t msec2wait(uint32_t msec) { +TU_ATTR_ALWAYS_INLINE static inline uint16_t msec2wait(uint32_t msec) { if (msec == OSAL_TIMEOUT_WAIT_FOREVER) return 0xFFFF; else if (msec >= 0xFFFE) @@ -62,12 +62,12 @@ static inline uint16_t msec2wait(uint32_t msec) { typedef OS_SEM osal_semaphore_def_t; typedef OS_ID osal_semaphore_t; -static inline OS_ID osal_semaphore_create(osal_semaphore_def_t* semdef) { +TU_ATTR_ALWAYS_INLINE static inline OS_ID osal_semaphore_create(osal_semaphore_def_t* semdef) { os_sem_init(semdef, 0); return semdef; } -static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { if ( !in_isr ) { os_sem_send(sem_hdl); } else { @@ -76,11 +76,11 @@ static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { return true; } -static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) { +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) { return os_sem_wait(sem_hdl, msec2wait(msec)) != OS_R_TMO; } -static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) { +TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) { // TODO: implement } @@ -90,18 +90,18 @@ static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) { typedef OS_MUT osal_mutex_def_t; typedef OS_ID osal_mutex_t; -static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) +TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) { os_mut_init(mdef); return mdef; } -static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) { return os_mut_wait(mutex_hdl, msec2wait(msec)) != OS_R_TMO; } -static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { return os_mut_release(mutex_hdl) == OS_R_OK; } @@ -127,23 +127,23 @@ typedef struct typedef osal_queue_def_t* osal_queue_t; -static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) +TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { os_mbx_init(qdef->mbox, (qdef->depth + 4) * 4); _init_box(qdef->pool, ((qdef->item_sz+3)/4)*(qdef->depth) + 3, qdef->item_sz); return qdef; } -static inline bool osal_queue_receive(osal_queue_t qhdl, void* data) +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) { void* buf; - os_mbx_wait(qhdl->mbox, &buf, 0xFFFF); + os_mbx_wait(qhdl->mbox, &buf, msec2wait(msec)); memcpy(data, buf, qhdl->item_sz); _free_box(qhdl->pool, buf); return true; } -static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) { void* buf = _alloc_box(qhdl->pool); memcpy(buf, data, qhdl->item_sz); @@ -158,7 +158,7 @@ static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in return true; } -static inline bool osal_queue_empty(osal_queue_t qhdl) +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { return os_mbx_check(qhdl->mbox) == qhdl->depth; } diff --git a/src/portable/sony/cxd56/dcd_cxd56.c b/src/portable/sony/cxd56/dcd_cxd56.c index fbea03b1d..d3154e58f 100644 --- a/src/portable/sony/cxd56/dcd_cxd56.c +++ b/src/portable/sony/cxd56/dcd_cxd56.c @@ -363,7 +363,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to if (usbdcd_driver.setup_processed) { - if (osal_queue_receive(usbdcd_driver.setup_queue, &ctrl)) + if (osal_queue_receive(usbdcd_driver.setup_queue, &ctrl, 100)) { usbdcd_driver.setup_processed = false; dcd_event_setup_received(0, (uint8_t *)&ctrl, false); diff --git a/src/tusb_option.h b/src/tusb_option.h index bd87a953c..9cacedd4c 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -286,7 +286,7 @@ #endif // mutex is only needed for RTOS TODO also required with multiple core MCUs -#define TUSB_OPT_MUTEX (CFG_TUSB_OS != OPT_OS_NONE) +#define TUSB_OPT_MUTEX (CFG_TUSB_OS != OPT_OS_NONE) //-------------------------------------------------------------------- // DEVICE OPTIONS From 669e36d674d4b67b56127d8b41928a6dd3bdca7b Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 20 Apr 2022 14:37:42 +0700 Subject: [PATCH 297/504] fix freertos issue when 1 tick > 1 ms --- examples/device/cdc_msc_freertos/src/main.c | 6 ++---- src/osal/osal_freertos.h | 20 ++++++++++++++++---- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/examples/device/cdc_msc_freertos/src/main.c b/examples/device/cdc_msc_freertos/src/main.c index 0a1c964ae..c0fc722f4 100644 --- a/examples/device/cdc_msc_freertos/src/main.c +++ b/examples/device/cdc_msc_freertos/src/main.c @@ -132,6 +132,8 @@ void usb_device_task(void* param) { // tinyusb device task tud_task(); + + tud_cdc_write_flush(); } } @@ -194,12 +196,8 @@ void cdc_task(void* params) // for throughput test e.g // $ dd if=/dev/zero of=/dev/ttyACM0 count=10000 tud_cdc_write(buf, count); - tud_cdc_write_flush(); } } - - // For ESP32-S2 this delay is essential to allow idle how to run and reset wdt - vTaskDelay(pdMS_TO_TICKS(10)); } } diff --git a/src/osal/osal_freertos.h b/src/osal/osal_freertos.h index c3a0756e1..52db336f5 100644 --- a/src/osal/osal_freertos.h +++ b/src/osal/osal_freertos.h @@ -37,6 +37,20 @@ extern "C" { #endif +TU_ATTR_ALWAYS_INLINE static inline uint32_t _osal_ms2tick(uint32_t msec) +{ + if (msec == OSAL_TIMEOUT_WAIT_FOREVER) return portMAX_DELAY; + if (msec == 0) return 0; + + uint32_t ticks = pdMS_TO_TICKS(msec); + + // configTICK_RATE_HZ 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; +} + //--------------------------------------------------------------------+ // TASK API //--------------------------------------------------------------------+ @@ -80,8 +94,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t se TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) { - uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec); - return xSemaphoreTake(sem_hdl, ticks); + return xSemaphoreTake(sem_hdl, _osal_ms2tick(msec)); } TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) @@ -137,8 +150,7 @@ TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_de TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) { - uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec); - return xQueueReceive(qhdl, data, ticks); + return xQueueReceive(qhdl, data, _osal_ms2tick(msec)); } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) From ccafb42c8261d8304fce0af46c0ddc3adf6da56f Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 20 Apr 2022 14:40:55 +0700 Subject: [PATCH 298/504] disable blank issues, add online docs link --- .github/ISSUE_TEMPLATE/config.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 735a5ef22..28fd27467 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,4 +1,8 @@ +blank_issues_enabled: false contact_links: - name: TinyUSB Discussion url: https://github.com/hathach/tinyusb/discussions about: If you have other questions or need help, post it here. + - name: TinyUSB Docs + url: https://docs.tinyusb.org/ + about: Online documentation From c422b9ef419d4abc52b8c1e95ba4577ac6ae6a8c Mon Sep 17 00:00:00 2001 From: Nikitarc Date: Wed, 20 Apr 2022 11:29:03 +0200 Subject: [PATCH 299/504] Update dwc2_stm32.h Add missing #endif --- src/portable/synopsys/dwc2/dwc2_stm32.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index c4a4d310f..d54bf1fd7 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -61,6 +61,7 @@ // USB_OTG_FS_PERIPH_BASE and OTG_FS_IRQn not defined #define USB_OTG_FS_PERIPH_BASE USB1_OTG_HS_PERIPH_BASE #define OTG_FS_IRQn OTG_HS_IRQn + #endif #elif CFG_TUSB_MCU == OPT_MCU_STM32F7 #include "stm32f7xx.h" From b034c18077ef1350f2678f245ed1b885e9be79fc Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 20 Apr 2022 18:29:41 +0700 Subject: [PATCH 300/504] add tud_task_ext(), tuh_task_ext() as exteneded version that take timeout and in_isr also allow exit tud_task,tuh_task after processing all events for running other background task for user --- examples/device/cdc_msc_freertos/src/main.c | 3 +++ src/common/tusb_verify.h | 10 +++++----- src/device/usbd.c | 11 +++++++++-- src/device/usbd.h | 11 ++++++++++- src/host/usbh.c | 11 +++++++++-- src/host/usbh.h | 19 ++++++++++++++----- 6 files changed, 50 insertions(+), 15 deletions(-) diff --git a/examples/device/cdc_msc_freertos/src/main.c b/examples/device/cdc_msc_freertos/src/main.c index c0fc722f4..0d40782ef 100644 --- a/examples/device/cdc_msc_freertos/src/main.c +++ b/examples/device/cdc_msc_freertos/src/main.c @@ -198,6 +198,9 @@ void cdc_task(void* params) tud_cdc_write(buf, count); } } + + // For ESP32-Sx this delay is essential to allow idle how to run and reset watchdog + vTaskDelay(1); } } diff --git a/src/common/tusb_verify.h b/src/common/tusb_verify.h index f4a08ce2f..568bac8cc 100644 --- a/src/common/tusb_verify.h +++ b/src/common/tusb_verify.h @@ -99,8 +99,8 @@ *------------------------------------------------------------------*/ // Helper to implement optional parameter for TU_VERIFY Macro family -#define GET_3RD_ARG(arg1, arg2, arg3, ...) arg3 -#define GET_4TH_ARG(arg1, arg2, arg3, arg4, ...) arg4 +#define _GET_3RD_ARG(arg1, arg2, arg3, ...) arg3 +#define _GET_4TH_ARG(arg1, arg2, arg3, arg4, ...) arg4 /*------------- Generator for TU_VERIFY and TU_VERIFY_HDLR -------------*/ #define TU_VERIFY_DEFINE(_cond, _handler, _ret) do \ @@ -116,7 +116,7 @@ #define TU_VERIFY_1ARGS(_cond) TU_VERIFY_DEFINE(_cond, , false) #define TU_VERIFY_2ARGS(_cond, _ret) TU_VERIFY_DEFINE(_cond, , _ret) -#define TU_VERIFY(...) GET_3RD_ARG(__VA_ARGS__, TU_VERIFY_2ARGS, TU_VERIFY_1ARGS, UNUSED)(__VA_ARGS__) +#define TU_VERIFY(...) _GET_3RD_ARG(__VA_ARGS__, TU_VERIFY_2ARGS, TU_VERIFY_1ARGS, UNUSED)(__VA_ARGS__) /*------------------------------------------------------------------*/ @@ -127,7 +127,7 @@ #define TU_VERIFY_HDLR_2ARGS(_cond, _handler) TU_VERIFY_DEFINE(_cond, _handler, false) #define TU_VERIFY_HDLR_3ARGS(_cond, _handler, _ret) TU_VERIFY_DEFINE(_cond, _handler, _ret) -#define TU_VERIFY_HDLR(...) GET_4TH_ARG(__VA_ARGS__, TU_VERIFY_HDLR_3ARGS, TU_VERIFY_HDLR_2ARGS,UNUSED)(__VA_ARGS__) +#define TU_VERIFY_HDLR(...) _GET_4TH_ARG(__VA_ARGS__, TU_VERIFY_HDLR_3ARGS, TU_VERIFY_HDLR_2ARGS,UNUSED)(__VA_ARGS__) /*------------------------------------------------------------------*/ /* ASSERT @@ -139,7 +139,7 @@ #define ASSERT_2ARGS(_cond, _ret) TU_VERIFY_DEFINE(_cond, _MESS_FAILED(); TU_BREAKPOINT(), _ret) #ifndef TU_ASSERT -#define TU_ASSERT(...) GET_3RD_ARG(__VA_ARGS__, ASSERT_2ARGS, ASSERT_1ARGS,UNUSED)(__VA_ARGS__) +#define TU_ASSERT(...) _GET_3RD_ARG(__VA_ARGS__, ASSERT_2ARGS, ASSERT_1ARGS,UNUSED)(__VA_ARGS__) #endif /*------------------------------------------------------------------*/ diff --git a/src/device/usbd.c b/src/device/usbd.c index 36b9c7cff..167a053e2 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -466,8 +466,10 @@ bool tud_task_event_ready(void) } @endcode */ -void tud_task (void) +void tud_task_ext(uint32_t timeout_ms, bool in_isr) { + (void) in_isr; // not implemented yet + // Skip if stack is not initialized if ( !tusb_inited() ) return; @@ -475,7 +477,7 @@ void tud_task (void) while (1) { dcd_event_t event; - if ( !osal_queue_receive(_usbd_q, &event, 1) ) return; + if ( !osal_queue_receive(_usbd_q, &event, timeout_ms) ) return; #if CFG_TUSB_DEBUG >= 2 if (event.event_id == DCD_EVENT_SETUP_RECEIVED) TU_LOG2("\r\n"); // extra line for setup @@ -592,6 +594,11 @@ void tud_task (void) TU_BREAKPOINT(); 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(_usbd_q)) return; +#endif } } diff --git a/src/device/usbd.h b/src/device/usbd.h index b2bf8ba9d..30373abb9 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -43,8 +43,17 @@ bool tud_init (uint8_t rhport); // Check if device stack is already initialized bool tud_inited(void); +// Task function should be called in main/rtos loop, extended version of tud_task() +// - timeout_ms: millisecond to wait, zero = no wait, 0xFFFFFFFF = wait forever +// - in_isr: if function is called in ISR +void tud_task_ext(uint32_t timeout_ms, bool in_isr); + // Task function should be called in main/rtos loop -void tud_task (void); +TU_ATTR_ALWAYS_INLINE static inline +void tud_task (void) +{ + tud_task_ext(OSAL_TIMEOUT_WAIT_FOREVER, false); +} // Check if there is pending events need proccessing by tud_task() bool tud_task_event_ready(void); diff --git a/src/host/usbh.c b/src/host/usbh.c index ad90a1b1b..80d176142 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -392,8 +392,10 @@ bool tuh_init(uint8_t rhport) } @endcode */ -void tuh_task(void) +void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { + (void) in_isr; // not implemented yet + // Skip if stack is not initialized if ( !tusb_inited() ) return; @@ -401,7 +403,7 @@ void tuh_task(void) while (1) { hcd_event_t event; - if ( !osal_queue_receive(_usbh_q, &event, 1) ) return; + if ( !osal_queue_receive(_usbh_q, &event, timeout_ms) ) return; switch (event.event_id) { @@ -497,6 +499,11 @@ void tuh_task(void) default: 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 } } diff --git a/src/host/usbh.h b/src/host/usbh.h index e883ac90b..1580717fd 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -91,8 +91,17 @@ bool tuh_init(uint8_t rhport); // Check if host stack is already initialized bool tuh_inited(void); +// Task function should be called in main/rtos loop, extended version of tuh_task() +// - timeout_ms: millisecond to wait, zero = no wait, 0xFFFFFFFF = wait forever +// - in_isr: if function is called in ISR +void tuh_task_ext(uint32_t timeout_ms, bool in_isr); + // Task function should be called in main/rtos loop -void tuh_task(void); +TU_ATTR_ALWAYS_INLINE static inline +void tuh_task(void) +{ + tuh_task_ext(OSAL_TIMEOUT_WAIT_FOREVER, false); +} // Interrupt handler, name alias to HCD extern void hcd_int_handler(uint8_t rhport); @@ -106,8 +115,8 @@ tusb_speed_t tuh_speed_get(uint8_t daddr); bool tuh_mounted(uint8_t daddr); // Check if device is suspended -TU_ATTR_ALWAYS_INLINE -static inline bool tuh_suspended(uint8_t daddr) +TU_ATTR_ALWAYS_INLINE static inline +bool tuh_suspended(uint8_t daddr) { // TODO implement suspend & resume on host (void) daddr; @@ -115,8 +124,8 @@ static inline bool tuh_suspended(uint8_t daddr) } // Check if device is ready to communicate with -TU_ATTR_ALWAYS_INLINE -static inline bool tuh_ready(uint8_t daddr) +TU_ATTR_ALWAYS_INLINE static inline +bool tuh_ready(uint8_t daddr) { return tuh_mounted(daddr) && !tuh_suspended(daddr); } From 6a022c73dbf1551a441fafbea3a27c1a9951816f Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 20 Apr 2022 18:35:38 +0700 Subject: [PATCH 301/504] add note for tud_task() behavior in freertos example --- examples/device/cdc_msc_freertos/src/main.c | 5 +++-- examples/device/hid_composite_freertos/src/main.c | 4 +++- src/device/usbd.h | 2 +- src/host/usbh.h | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/examples/device/cdc_msc_freertos/src/main.c b/examples/device/cdc_msc_freertos/src/main.c index 0d40782ef..0492f2724 100644 --- a/examples/device/cdc_msc_freertos/src/main.c +++ b/examples/device/cdc_msc_freertos/src/main.c @@ -130,10 +130,10 @@ void usb_device_task(void* param) // RTOS forever loop while (1) { - // tinyusb device task + // put this thread to waiting state until there is new events tud_task(); - tud_cdc_write_flush(); + // following code only run if tud_task() process at least 1 event } } @@ -196,6 +196,7 @@ void cdc_task(void* params) // for throughput test e.g // $ dd if=/dev/zero of=/dev/ttyACM0 count=10000 tud_cdc_write(buf, count); + tud_cdc_write_flush(); } } diff --git a/examples/device/hid_composite_freertos/src/main.c b/examples/device/hid_composite_freertos/src/main.c index 1695f968c..317b64611 100644 --- a/examples/device/hid_composite_freertos/src/main.c +++ b/examples/device/hid_composite_freertos/src/main.c @@ -132,8 +132,10 @@ void usb_device_task(void* param) // RTOS forever loop while (1) { - // tinyusb device task + // put this thread to waiting state until there is new events tud_task(); + + // following code only run if tud_task() process at least 1 event } } diff --git a/src/device/usbd.h b/src/device/usbd.h index 30373abb9..583962611 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -52,7 +52,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr); TU_ATTR_ALWAYS_INLINE static inline void tud_task (void) { - tud_task_ext(OSAL_TIMEOUT_WAIT_FOREVER, false); + tud_task_ext(UINT32_MAX, false); } // Check if there is pending events need proccessing by tud_task() diff --git a/src/host/usbh.h b/src/host/usbh.h index 1580717fd..c6d36fb7f 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -100,7 +100,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr); TU_ATTR_ALWAYS_INLINE static inline void tuh_task(void) { - tuh_task_ext(OSAL_TIMEOUT_WAIT_FOREVER, false); + tuh_task_ext(UINT32_MAX, false); } // Interrupt handler, name alias to HCD From 87572871d586856242c1fa44b1532a09e624162d Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 20 Apr 2022 18:52:15 +0700 Subject: [PATCH 302/504] update example for better cdc echo --- examples/device/cdc_msc_freertos/src/main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/device/cdc_msc_freertos/src/main.c b/examples/device/cdc_msc_freertos/src/main.c index 0492f2724..a5e907199 100644 --- a/examples/device/cdc_msc_freertos/src/main.c +++ b/examples/device/cdc_msc_freertos/src/main.c @@ -134,6 +134,7 @@ void usb_device_task(void* param) tud_task(); // following code only run if tud_task() process at least 1 event + tud_cdc_write_flush(); } } @@ -183,7 +184,7 @@ void cdc_task(void* params) // if ( tud_cdc_connected() ) { // There are data available - if ( tud_cdc_available() ) + while ( tud_cdc_available() ) { uint8_t buf[64]; @@ -196,8 +197,9 @@ void cdc_task(void* params) // for throughput test e.g // $ dd if=/dev/zero of=/dev/ttyACM0 count=10000 tud_cdc_write(buf, count); - tud_cdc_write_flush(); } + + tud_cdc_write_flush(); } // For ESP32-Sx this delay is essential to allow idle how to run and reset watchdog From 328039058ef1c654246304a3a0acbee724278b85 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 21 Apr 2022 01:45:03 +0700 Subject: [PATCH 303/504] update lib pio --- lib/Pico-PIO-USB | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB index 98e3feefc..d15fffd95 160000 --- a/lib/Pico-PIO-USB +++ b/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit 98e3feefcd1c7218bced0ea2ea35530fd1b550e4 +Subproject commit d15fffd950018c60cba5c98d676a4fafaeea2648 From 12debd7763bfc6f55566e5f4f8c982a55f206815 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 22 Apr 2022 01:06:17 +0700 Subject: [PATCH 304/504] keep up with pio usb --- hw/bsp/rp2040/family.cmake | 1 - lib/Pico-PIO-USB | 2 +- src/common/tusb_debug.h | 4 ++++ src/portable/raspberrypi/pio_usb/dcd_pio_usb.c | 10 +++++----- src/portable/raspberrypi/pio_usb/hcd_pio_usb.c | 4 ++-- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index d872c35ea..70e18293f 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -32,7 +32,6 @@ if (NOT TARGET _rp2040_family_inclusion_marker) ${TOP}/lib/Pico-PIO-USB/pio_usb.c ${TOP}/lib/Pico-PIO-USB/pio_usb_host.c ${TOP}/lib/Pico-PIO-USB/pio_usb_device.c - ${TOP}/lib/Pico-PIO-USB/pio_usb_hw.c ${TOP}/lib/Pico-PIO-USB/usb_crc.c ) diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB index d15fffd95..f656d703f 160000 --- a/lib/Pico-PIO-USB +++ b/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit d15fffd950018c60cba5c98d676a4fafaeea2648 +Subproject commit f656d703f3cee1e589eebb6606e204f59afb5611 diff --git a/src/common/tusb_debug.h b/src/common/tusb_debug.h index 647e8a8db..1ea2c19f5 100644 --- a/src/common/tusb_debug.h +++ b/src/common/tusb_debug.h @@ -65,6 +65,7 @@ static inline void tu_print_var(uint8_t const* buf, uint32_t bufsize) // Log with Level #define TU_LOG(n, ...) TU_XSTRCAT(TU_LOG, n)(__VA_ARGS__) #define TU_LOG_MEM(n, ...) TU_XSTRCAT3(TU_LOG, n, _MEM)(__VA_ARGS__) +#define TU_LOG_ARR(n, ...) TU_XSTRCAT3(TU_LOG, n, _ARR)(__VA_ARGS__) #define TU_LOG_VAR(n, ...) TU_XSTRCAT3(TU_LOG, n, _VAR)(__VA_ARGS__) #define TU_LOG_INT(n, ...) TU_XSTRCAT3(TU_LOG, n, _INT)(__VA_ARGS__) #define TU_LOG_HEX(n, ...) TU_XSTRCAT3(TU_LOG, n, _HEX)(__VA_ARGS__) @@ -74,6 +75,7 @@ static inline void tu_print_var(uint8_t const* buf, uint32_t bufsize) // Log Level 1: Error #define TU_LOG1 tu_printf #define TU_LOG1_MEM tu_print_mem +#define TU_LOG1_ARR(_x, _n) tu_print_var((uint8_t const*)(_x), _n) #define TU_LOG1_VAR(_x) tu_print_var((uint8_t const*)(_x), sizeof(*(_x))) #define TU_LOG1_INT(_x) tu_printf(#_x " = %ld\r\n", (unsigned long) (_x) ) #define TU_LOG1_HEX(_x) tu_printf(#_x " = %lX\r\n", (unsigned long) (_x) ) @@ -82,6 +84,7 @@ static inline void tu_print_var(uint8_t const* buf, uint32_t bufsize) #if CFG_TUSB_DEBUG >= 2 #define TU_LOG2 TU_LOG1 #define TU_LOG2_MEM TU_LOG1_MEM + #define TU_LOG2_ARR TU_LOG1_ARR #define TU_LOG2_VAR TU_LOG1_VAR #define TU_LOG2_INT TU_LOG1_INT #define TU_LOG2_HEX TU_LOG1_HEX @@ -91,6 +94,7 @@ static inline void tu_print_var(uint8_t const* buf, uint32_t bufsize) #if CFG_TUSB_DEBUG >= 3 #define TU_LOG3 TU_LOG1 #define TU_LOG3_MEM TU_LOG1_MEM + #define TU_LOG3_ARR TU_LOG1_ARR #define TU_LOG3_VAR TU_LOG1_VAR #define TU_LOG3_INT TU_LOG1_INT #define TU_LOG3_HEX TU_LOG1_HEX diff --git a/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c index 38867ea1c..1cb850654 100644 --- a/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c @@ -119,8 +119,8 @@ void dcd_edpt_close_all (uint8_t rhport) bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) { (void) rhport; - pio_hw_endpoint_t *ep = pio_usb_device_get_ep(ep_addr); - return pio_usb_endpoint_transfer(ep, buffer, total_bytes); + endpoint_t *ep = pio_usb_device_get_ep(ep_addr); + return pio_usb_ll_endpoint_transfer(ep, buffer, total_bytes); } // Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack - optional, however, must be listed in usbd.c @@ -137,7 +137,7 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) { (void) rhport; - pio_hw_endpoint_t *ep = pio_usb_device_get_ep(ep_addr); + endpoint_t *ep = pio_usb_device_get_ep(ep_addr); ep->stalled = true; } @@ -145,7 +145,7 @@ void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) { (void) rhport; - pio_hw_endpoint_t *ep = pio_usb_device_get_ep(ep_addr); + endpoint_t *ep = pio_usb_device_get_ep(ep_addr); ep->data_id = 0; ep->stalled = false; } @@ -188,7 +188,7 @@ static void __no_inline_not_in_flash_func(handle_endpoint_irq)(pio_hw_root_port_ if (ep_all & mask) { - pio_hw_endpoint_t* ep = PIO_USB_HW_EP(ep_idx); + endpoint_t* ep = PIO_USB_HW_EP(ep_idx); uint8_t const tu_rhport = port - PIO_USB_HW_RPORT(0) + 1; dcd_event_xfer_complete(tu_rhport, ep->ep_num, ep->actual_len, result, true); } diff --git a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c index e311f16d0..2615b2356 100644 --- a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c @@ -73,7 +73,7 @@ bool hcd_port_connect_status(uint8_t rhport) rhport = RHPORT_PIO(rhport); pio_hw_root_port_t *root = PIO_USB_HW_RPORT(rhport); - port_pin_status_t line_state = pio_hw_get_line_state(root); + port_pin_status_t line_state = pio_usb_ll_get_line_state(root); return line_state != PORT_PIN_SE0; } @@ -187,7 +187,7 @@ static void __no_inline_not_in_flash_func(handle_endpoint_irq)(pio_hw_root_port_ if (ep_all & mask) { - pio_hw_endpoint_t* ep = PIO_USB_HW_EP(ep_idx); + endpoint_t* ep = PIO_USB_HW_EP(ep_idx); hcd_event_xfer_complete(ep->dev_addr, ep->ep_num, ep->actual_len, result, true); } } From 2f9b9a31be9d511d0bbb99671a2f5e7818cf8a55 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 22 Apr 2022 18:23:38 +0700 Subject: [PATCH 305/504] more with pio usb --- lib/Pico-PIO-USB | 2 +- .../raspberrypi/pio_usb/dcd_pio_usb.c | 29 ++++++++++--------- .../raspberrypi/pio_usb/hcd_pio_usb.c | 13 +++++---- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB index f656d703f..496454021 160000 --- a/lib/Pico-PIO-USB +++ b/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit f656d703f3cee1e589eebb6606e204f59afb5611 +Subproject commit 496454021deab00e1c425a6eb70009666fa036b3 diff --git a/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c index 1cb850654..d73419fe3 100644 --- a/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c @@ -31,6 +31,7 @@ #include "pico.h" #include "hardware/pio.h" #include "pio_usb.h" +#include "pio_usb_ll.h" #include "device/dcd.h" @@ -119,7 +120,7 @@ void dcd_edpt_close_all (uint8_t rhport) bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) { (void) rhport; - endpoint_t *ep = pio_usb_device_get_ep(ep_addr); + endpoint_t *ep = pio_usb_device_get_endpoint_by_address(ep_addr); return pio_usb_ll_endpoint_transfer(ep, buffer, total_bytes); } @@ -137,7 +138,7 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) { (void) rhport; - endpoint_t *ep = pio_usb_device_get_ep(ep_addr); + endpoint_t *ep = pio_usb_device_get_endpoint_by_address(ep_addr); ep->stalled = true; } @@ -145,7 +146,7 @@ void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) { (void) rhport; - endpoint_t *ep = pio_usb_device_get_ep(ep_addr); + endpoint_t *ep = pio_usb_device_get_endpoint_by_address(ep_addr); ep->data_id = 0; ep->stalled = false; } @@ -154,24 +155,24 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) // //--------------------------------------------------------------------+ -static void __no_inline_not_in_flash_func(handle_endpoint_irq)(pio_hw_root_port_t* port, uint32_t flag) +static void __no_inline_not_in_flash_func(handle_endpoint_irq)(root_port_t* rport, uint32_t flag) { volatile uint32_t* ep_reg; xfer_result_t result; if ( flag == PIO_USB_INTS_ENDPOINT_COMPLETE_BITS ) { - ep_reg = &port->ep_complete; + ep_reg = &rport->ep_complete; result = XFER_RESULT_SUCCESS; } else if ( flag == PIO_USB_INTS_ENDPOINT_ERROR_BITS ) { - ep_reg = &port->ep_error; + ep_reg = &rport->ep_error; result = XFER_RESULT_FAILED; } else if ( flag == PIO_USB_INTS_ENDPOINT_STALLED_BITS ) { - ep_reg = &port->ep_stalled; + ep_reg = &rport->ep_stalled; result = XFER_RESULT_STALLED; } else @@ -188,8 +189,8 @@ static void __no_inline_not_in_flash_func(handle_endpoint_irq)(pio_hw_root_port_ if (ep_all & mask) { - endpoint_t* ep = PIO_USB_HW_EP(ep_idx); - uint8_t const tu_rhport = port - PIO_USB_HW_RPORT(0) + 1; + endpoint_t* ep = PIO_USB_ENDPOINT(ep_idx); + uint8_t const tu_rhport = rport - PIO_USB_ROOT_PORT(0) + 1; dcd_event_xfer_complete(tu_rhport, ep->ep_num, ep->actual_len, result, true); } } @@ -202,8 +203,8 @@ static void __no_inline_not_in_flash_func(handle_endpoint_irq)(pio_hw_root_port_ void __no_inline_not_in_flash_func(pio_usb_device_irq_handler)(uint8_t root_id) { uint8_t const tu_rhport = root_id + 1; - pio_hw_root_port_t* port = PIO_USB_HW_RPORT(root_id); - uint32_t const ints = port->ints; + root_port_t* rport = PIO_USB_ROOT_PORT(root_id); + uint32_t const ints = rport->ints; if (ints & PIO_USB_INTS_RESET_END_BITS) { @@ -212,16 +213,16 @@ void __no_inline_not_in_flash_func(pio_usb_device_irq_handler)(uint8_t root_id) if (ints & PIO_USB_INTS_SETUP_REQ_BITS) { - dcd_event_setup_received(tu_rhport, port->setup_packet, true); + dcd_event_setup_received(tu_rhport, rport->setup_packet, true); } if ( ints & PIO_USB_INTS_ENDPOINT_COMPLETE_BITS ) { - handle_endpoint_irq(port, PIO_USB_INTS_ENDPOINT_COMPLETE_BITS); + handle_endpoint_irq(rport, PIO_USB_INTS_ENDPOINT_COMPLETE_BITS); } // clear all - port->ints &= ~ints; + rport->ints &= ~ints; } #endif diff --git a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c index 2615b2356..f881716ec 100644 --- a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c @@ -31,6 +31,7 @@ #include "pico.h" #include "hardware/pio.h" #include "pio_usb.h" +#include "pio_usb_ll.h" //--------------------------------------------------------------------+ // INCLUDE @@ -72,8 +73,8 @@ bool hcd_port_connect_status(uint8_t rhport) { rhport = RHPORT_PIO(rhport); - pio_hw_root_port_t *root = PIO_USB_HW_RPORT(rhport); - port_pin_status_t line_state = pio_usb_ll_get_line_state(root); + root_port_t *root = PIO_USB_ROOT_PORT(rhport); + port_pin_status_t line_state = pio_usb_bus_get_line_state(root); return line_state != PORT_PIN_SE0; } @@ -82,7 +83,7 @@ tusb_speed_t hcd_port_speed_get(uint8_t rhport) { // TODO determine link speed rhport = RHPORT_PIO(rhport); - return PIO_USB_HW_RPORT(rhport)->is_fullspeed ? TUSB_SPEED_FULL : TUSB_SPEED_LOW; + return PIO_USB_ROOT_PORT(rhport)->is_fullspeed ? TUSB_SPEED_FULL : TUSB_SPEED_LOW; } // Close all opened endpoint belong to this device @@ -153,7 +154,7 @@ bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) return true; } -static void __no_inline_not_in_flash_func(handle_endpoint_irq)(pio_hw_root_port_t* port, uint32_t flag) +static void __no_inline_not_in_flash_func(handle_endpoint_irq)(root_port_t* port, uint32_t flag) { volatile uint32_t* ep_reg; xfer_result_t result; @@ -187,7 +188,7 @@ static void __no_inline_not_in_flash_func(handle_endpoint_irq)(pio_hw_root_port_ if (ep_all & mask) { - endpoint_t* ep = PIO_USB_HW_EP(ep_idx); + endpoint_t* ep = PIO_USB_ENDPOINT(ep_idx); hcd_event_xfer_complete(ep->dev_addr, ep->ep_num, ep->actual_len, result, true); } } @@ -199,7 +200,7 @@ static void __no_inline_not_in_flash_func(handle_endpoint_irq)(pio_hw_root_port_ // IRQ Handler void __no_inline_not_in_flash_func(pio_usb_host_irq_handler)(uint8_t root_id) { - pio_hw_root_port_t* port = PIO_USB_HW_RPORT(root_id); + root_port_t* port = PIO_USB_ROOT_PORT(root_id); uint32_t const ints = port->ints; if ( ints & PIO_USB_INTS_CONNECT_BITS ) From 3a1c7339cd54cc03233c2337e95403260992738f Mon Sep 17 00:00:00 2001 From: Grant Slater Date: Sun, 24 Apr 2022 16:48:49 +0100 Subject: [PATCH 306/504] Replace actions/setup-ruby with replacement ruby/setup-ruby --- .github/workflows/build_arm.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml index 177f1076e..fc5eec1df 100644 --- a/.github/workflows/build_arm.yml +++ b/.github/workflows/build_arm.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Setup Ruby - uses: actions/setup-ruby@v1 + uses: ruby/setup-ruby@v1 with: ruby-version: '2.7' From 35d1a71ed7d3b3ea42b4d38c7cdc85233b815348 Mon Sep 17 00:00:00 2001 From: Grant Slater Date: Sun, 24 Apr 2022 16:49:29 +0100 Subject: [PATCH 307/504] GH Update to actions/checkout@v3 --- .github/workflows/build_aarch64.yml | 4 ++-- .github/workflows/build_arm.yml | 8 ++++---- .github/workflows/build_esp.yml | 4 ++-- .github/workflows/build_msp430.yml | 4 ++-- .github/workflows/build_renesas.yml | 4 ++-- .github/workflows/build_riscv.yml | 4 ++-- .github/workflows/trigger.yml | 2 +- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/build_aarch64.yml b/.github/workflows/build_aarch64.yml index 8cf7852b9..1720ba592 100644 --- a/.github/workflows/build_aarch64.yml +++ b/.github/workflows/build_aarch64.yml @@ -24,13 +24,13 @@ jobs: uses: actions/setup-python@v2 - name: Checkout TinyUSB - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Checkout common submodules in lib run: git submodule update --init lib/FreeRTOS-Kernel lib/lwip lib/sct_neopixel - name: Checkout hathach/linkermap - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: hathach/linkermap path: linkermap diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml index fc5eec1df..133671f82 100644 --- a/.github/workflows/build_arm.yml +++ b/.github/workflows/build_arm.yml @@ -20,7 +20,7 @@ jobs: ruby-version: '2.7' - name: Checkout TinyUSB - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Unit Tests run: | @@ -66,13 +66,13 @@ jobs: uses: actions/setup-python@v2 - name: Checkout TinyUSB - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Checkout common submodules in lib run: git submodule update --init lib/FreeRTOS-Kernel lib/lwip lib/sct_neopixel - name: Checkout hathach/linkermap - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: hathach/linkermap path: linkermap @@ -135,7 +135,7 @@ jobs: uses: actions/setup-python@v2 - name: Checkout TinyUSB - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Checkout common submodules in lib run: git submodule update --init lib/FreeRTOS-Kernel lib/lwip diff --git a/.github/workflows/build_esp.yml b/.github/workflows/build_esp.yml index 1ed76ef4d..6a46773b2 100644 --- a/.github/workflows/build_esp.yml +++ b/.github/workflows/build_esp.yml @@ -29,10 +29,10 @@ jobs: run: docker pull espressif/idf:latest - name: Checkout TinyUSB - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Checkout hathach/linkermap - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: hathach/linkermap path: linkermap diff --git a/.github/workflows/build_msp430.yml b/.github/workflows/build_msp430.yml index 98dc36cd9..6a468ab04 100644 --- a/.github/workflows/build_msp430.yml +++ b/.github/workflows/build_msp430.yml @@ -21,13 +21,13 @@ jobs: uses: actions/setup-python@v2 - name: Checkout TinyUSB - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Checkout common submodules in lib run: git submodule update --init lib/FreeRTOS-Kernel lib/lwip - name: Checkout hathach/linkermap - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: hathach/linkermap path: linkermap diff --git a/.github/workflows/build_renesas.yml b/.github/workflows/build_renesas.yml index 6eb042d72..50618ff6b 100644 --- a/.github/workflows/build_renesas.yml +++ b/.github/workflows/build_renesas.yml @@ -21,13 +21,13 @@ jobs: uses: actions/setup-python@v2 - name: Checkout TinyUSB - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Checkout common submodules in lib run: git submodule update --init lib/FreeRTOS-Kernel lib/lwip - name: Checkout hathach/linkermap - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: hathach/linkermap path: linkermap diff --git a/.github/workflows/build_riscv.yml b/.github/workflows/build_riscv.yml index 0c7b2d154..2d670138d 100644 --- a/.github/workflows/build_riscv.yml +++ b/.github/workflows/build_riscv.yml @@ -22,13 +22,13 @@ jobs: uses: actions/setup-python@v2 - name: Checkout TinyUSB - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Checkout common submodules in lib run: git submodule update --init lib/FreeRTOS-Kernel lib/lwip - name: Checkout hathach/linkermap - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: hathach/linkermap path: linkermap diff --git a/.github/workflows/trigger.yml b/.github/workflows/trigger.yml index 40750a2f9..780d6f4f3 100644 --- a/.github/workflows/trigger.yml +++ b/.github/workflows/trigger.yml @@ -22,7 +22,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Push to tinyusb_src run: | From 15c01f20ecdb3b9ff184f2311e65e95e4cd8e5cd Mon Sep 17 00:00:00 2001 From: Nikitarc Date: Mon, 25 Apr 2022 14:06:15 +0200 Subject: [PATCH 308/504] Update tusb_option.h Makes ISO compiler happy --- src/tusb_option.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tusb_option.h b/src/tusb_option.h index bd87a953c..66313419a 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -27,6 +27,9 @@ #ifndef _TUSB_OPTION_H_ #define _TUSB_OPTION_H_ +// To avoid GCC compiler warnings when -pedantic option is used (strict ISO C) +typedef int make_iso_compilers_happy ; + #include "common/tusb_compiler.h" #define TUSB_VERSION_MAJOR 0 From 26a25279bc7196d93ca074203ac35260298df472 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 26 Apr 2022 00:35:16 +0700 Subject: [PATCH 309/504] follow pio usb changes --- lib/Pico-PIO-USB | 2 +- .../raspberrypi/pio_usb/dcd_pio_usb.c | 11 ++--- .../raspberrypi/pio_usb/hcd_pio_usb.c | 40 ++++++++++--------- 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB index 496454021..d2c70ae7b 160000 --- a/lib/Pico-PIO-USB +++ b/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit 496454021deab00e1c425a6eb70009666fa036b3 +Subproject commit d2c70ae7b6a122027b7c5c9aa4769fab19e8e886 diff --git a/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c index d73419fe3..09be69afa 100644 --- a/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c @@ -74,11 +74,8 @@ void dcd_int_disable (uint8_t rhport) // Receive Set Address request, mcu port must also include status IN response void dcd_set_address (uint8_t rhport, uint8_t dev_addr) { - uint8_t const pio_rhport = RHPORT_PIO(rhport); - // must be called before queuing status - pio_usb_device_set_address(pio_rhport, dev_addr); - + pio_usb_device_set_address(dev_addr); dcd_edpt_xfer(rhport, 0x80, NULL, 0); } @@ -107,8 +104,8 @@ void dcd_disconnect(uint8_t rhport) // Configure endpoint's registers according to descriptor bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) { - uint8_t const pio_rhport = RHPORT_PIO(rhport); - return pio_usb_device_endpoint_open(pio_rhport, (uint8_t const*) desc_ep); + (void) rhport; + return pio_usb_device_endpoint_open((uint8_t const*) desc_ep); } void dcd_edpt_close_all (uint8_t rhport) @@ -121,7 +118,7 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t { (void) rhport; endpoint_t *ep = pio_usb_device_get_endpoint_by_address(ep_addr); - return pio_usb_ll_endpoint_transfer(ep, buffer, total_bytes); + return pio_usb_ll_transfer_start(ep, buffer, total_bytes); } // Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack - optional, however, must be listed in usbd.c diff --git a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c index f881716ec..2b3d72df8 100644 --- a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c @@ -59,21 +59,21 @@ bool hcd_init(uint8_t rhport) void hcd_port_reset(uint8_t rhport) { - rhport = RHPORT_PIO(rhport); - pio_usb_host_port_reset_start(rhport); + uint8_t pio_rhport = RHPORT_PIO(rhport); + pio_usb_host_port_reset_start(pio_rhport); } void hcd_port_reset_end(uint8_t rhport) { - rhport = RHPORT_PIO(rhport); - pio_usb_host_port_reset_end(rhport); + uint8_t pio_rhport = RHPORT_PIO(rhport); + pio_usb_host_port_reset_end(pio_rhport); } bool hcd_port_connect_status(uint8_t rhport) { - rhport = RHPORT_PIO(rhport); + uint8_t pio_rhport = RHPORT_PIO(rhport); - root_port_t *root = PIO_USB_ROOT_PORT(rhport); + root_port_t *root = PIO_USB_ROOT_PORT(pio_rhport); port_pin_status_t line_state = pio_usb_bus_get_line_state(root); return line_state != PORT_PIN_SE0; @@ -82,28 +82,31 @@ bool hcd_port_connect_status(uint8_t rhport) tusb_speed_t hcd_port_speed_get(uint8_t rhport) { // TODO determine link speed - rhport = RHPORT_PIO(rhport); - return PIO_USB_ROOT_PORT(rhport)->is_fullspeed ? TUSB_SPEED_FULL : TUSB_SPEED_LOW; + uint8_t pio_rhport = RHPORT_PIO(rhport); + return PIO_USB_ROOT_PORT(pio_rhport)->is_fullspeed ? TUSB_SPEED_FULL : TUSB_SPEED_LOW; } // Close all opened endpoint belong to this device void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { - rhport = RHPORT_PIO(rhport); - pio_usb_host_close_device(rhport, dev_addr); + uint8_t pio_rhport = RHPORT_PIO(rhport); + pio_usb_host_close_device(pio_rhport, dev_addr); } uint32_t hcd_frame_number(uint8_t rhport) { + (void) rhport; return 0; } void hcd_int_enable(uint8_t rhport) { + (void) rhport; } void hcd_int_disable(uint8_t rhport) { + (void) rhport; } //--------------------------------------------------------------------+ @@ -116,20 +119,20 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const hcd_devtree_get_info(dev_addr, &dev_tree); bool const need_pre = (dev_tree.hub_addr && dev_tree.speed == TUSB_SPEED_LOW); - rhport = RHPORT_PIO(rhport); - return pio_usb_host_endpoint_open(rhport, dev_addr, (uint8_t const*) desc_ep, need_pre); + uint8_t pio_rhport = RHPORT_PIO(rhport); + return pio_usb_host_endpoint_open(pio_rhport, dev_addr, (uint8_t const*) desc_ep, need_pre); } bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) { - rhport = RHPORT_PIO(rhport); - return pio_usb_host_endpoint_transfer(rhport, dev_addr, ep_addr, buffer, buflen); + uint8_t pio_rhport = RHPORT_PIO(rhport); + return pio_usb_host_endpoint_transfer(pio_rhport, dev_addr, ep_addr, buffer, buflen); } bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) { - rhport = RHPORT_PIO(rhport); - return pio_usb_host_send_setup(rhport, dev_addr, setup_packet); + uint8_t pio_rhport = RHPORT_PIO(rhport); + return pio_usb_host_send_setup(pio_rhport, dev_addr, setup_packet); } //bool hcd_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) @@ -200,17 +203,18 @@ static void __no_inline_not_in_flash_func(handle_endpoint_irq)(root_port_t* port // IRQ Handler void __no_inline_not_in_flash_func(pio_usb_host_irq_handler)(uint8_t root_id) { + uint8_t const tu_rhport = root_id + 1; root_port_t* port = PIO_USB_ROOT_PORT(root_id); uint32_t const ints = port->ints; if ( ints & PIO_USB_INTS_CONNECT_BITS ) { - hcd_event_device_attach(root_id+1, true); + hcd_event_device_attach(tu_rhport, true); } if ( ints & PIO_USB_INTS_DISCONNECT_BITS ) { - hcd_event_device_remove(root_id+1, true); + hcd_event_device_remove(tu_rhport, true); } if ( ints & PIO_USB_INTS_ENDPOINT_COMPLETE_BITS ) From 4d11c658fffa810f271fdafb6453eff1f2b77b3f Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 26 Apr 2022 13:08:03 +0700 Subject: [PATCH 310/504] improve pio usb endpoint handler --- .../raspberrypi/pio_usb/dcd_pio_usb.c | 38 +++++---------- .../raspberrypi/pio_usb/hcd_pio_usb.c | 46 +++++-------------- 2 files changed, 23 insertions(+), 61 deletions(-) diff --git a/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c index 09be69afa..77f34238a 100644 --- a/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c @@ -152,32 +152,8 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) // //--------------------------------------------------------------------+ -static void __no_inline_not_in_flash_func(handle_endpoint_irq)(root_port_t* rport, uint32_t flag) +static void __no_inline_not_in_flash_func(handle_endpoint_irq)(root_port_t* rport, xfer_result_t result, volatile uint32_t* ep_reg) { - volatile uint32_t* ep_reg; - xfer_result_t result; - - if ( flag == PIO_USB_INTS_ENDPOINT_COMPLETE_BITS ) - { - ep_reg = &rport->ep_complete; - result = XFER_RESULT_SUCCESS; - } - else if ( flag == PIO_USB_INTS_ENDPOINT_ERROR_BITS ) - { - ep_reg = &rport->ep_error; - result = XFER_RESULT_FAILED; - } - else if ( flag == PIO_USB_INTS_ENDPOINT_STALLED_BITS ) - { - ep_reg = &rport->ep_stalled; - result = XFER_RESULT_STALLED; - } - else - { - // something wrong - return; - } - const uint32_t ep_all = *ep_reg; for(uint8_t ep_idx = 0; ep_idx < PIO_USB_EP_POOL_CNT; ep_idx++) @@ -215,7 +191,17 @@ void __no_inline_not_in_flash_func(pio_usb_device_irq_handler)(uint8_t root_id) if ( ints & PIO_USB_INTS_ENDPOINT_COMPLETE_BITS ) { - handle_endpoint_irq(rport, PIO_USB_INTS_ENDPOINT_COMPLETE_BITS); + handle_endpoint_irq(rport, XFER_RESULT_SUCCESS, &rport->ep_complete); + } + + if ( ints & PIO_USB_INTS_ENDPOINT_STALLED_BITS ) + { + handle_endpoint_irq(rport, XFER_RESULT_STALLED, &rport->ep_stalled); + } + + if ( ints & PIO_USB_INTS_ENDPOINT_ERROR_BITS ) + { + handle_endpoint_irq(rport, XFER_RESULT_FAILED, &rport->ep_error); } // clear all diff --git a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c index 2b3d72df8..8101fb2d3 100644 --- a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c @@ -157,32 +157,8 @@ bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) return true; } -static void __no_inline_not_in_flash_func(handle_endpoint_irq)(root_port_t* port, uint32_t flag) +static void __no_inline_not_in_flash_func(handle_endpoint_irq)(root_port_t* port, xfer_result_t result, volatile uint32_t* ep_reg) { - volatile uint32_t* ep_reg; - xfer_result_t result; - - if ( flag == PIO_USB_INTS_ENDPOINT_COMPLETE_BITS ) - { - ep_reg = &port->ep_complete; - result = XFER_RESULT_SUCCESS; - } - else if ( flag == PIO_USB_INTS_ENDPOINT_ERROR_BITS ) - { - ep_reg = &port->ep_error; - result = XFER_RESULT_FAILED; - } - else if ( flag == PIO_USB_INTS_ENDPOINT_STALLED_BITS ) - { - ep_reg = &port->ep_stalled; - result = XFER_RESULT_STALLED; - } - else - { - // something wrong - return; - } - const uint32_t ep_all = *ep_reg; for(uint8_t ep_idx = 0; ep_idx < PIO_USB_EP_POOL_CNT; ep_idx++) @@ -204,8 +180,8 @@ static void __no_inline_not_in_flash_func(handle_endpoint_irq)(root_port_t* port void __no_inline_not_in_flash_func(pio_usb_host_irq_handler)(uint8_t root_id) { uint8_t const tu_rhport = root_id + 1; - root_port_t* port = PIO_USB_ROOT_PORT(root_id); - uint32_t const ints = port->ints; + root_port_t* rport = PIO_USB_ROOT_PORT(root_id); + uint32_t const ints = rport->ints; if ( ints & PIO_USB_INTS_CONNECT_BITS ) { @@ -219,21 +195,21 @@ void __no_inline_not_in_flash_func(pio_usb_host_irq_handler)(uint8_t root_id) if ( ints & PIO_USB_INTS_ENDPOINT_COMPLETE_BITS ) { - handle_endpoint_irq(port, PIO_USB_INTS_ENDPOINT_COMPLETE_BITS); - } - - if ( ints & PIO_USB_INTS_ENDPOINT_ERROR_BITS ) - { - handle_endpoint_irq(port, PIO_USB_INTS_ENDPOINT_ERROR_BITS); + handle_endpoint_irq(rport, XFER_RESULT_SUCCESS, &rport->ep_complete); } if ( ints & PIO_USB_INTS_ENDPOINT_STALLED_BITS ) { - handle_endpoint_irq(port, PIO_USB_INTS_ENDPOINT_STALLED_BITS); + handle_endpoint_irq(rport, XFER_RESULT_STALLED, &rport->ep_stalled); + } + + if ( ints & PIO_USB_INTS_ENDPOINT_ERROR_BITS ) + { + handle_endpoint_irq(rport, XFER_RESULT_FAILED, &rport->ep_error); } // clear all - port->ints &= ~ints; + rport->ints &= ~ints; } #endif From 455bddddcd051acd6d62bca97783be04fc508e96 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 26 Apr 2022 18:47:09 +0700 Subject: [PATCH 311/504] minor clean up --- lib/Pico-PIO-USB | 2 +- src/portable/raspberrypi/pio_usb/dcd_pio_usb.c | 9 ++++----- src/portable/raspberrypi/pio_usb/hcd_pio_usb.c | 3 ++- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB index d2c70ae7b..125753a97 160000 --- a/lib/Pico-PIO-USB +++ b/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit d2c70ae7b6a122027b7c5c9aa4769fab19e8e886 +Subproject commit 125753a9783bc1724a185770b04f83c4ebd4b6c5 diff --git a/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c index 77f34238a..3daa39a8b 100644 --- a/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c @@ -152,7 +152,7 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) // //--------------------------------------------------------------------+ -static void __no_inline_not_in_flash_func(handle_endpoint_irq)(root_port_t* rport, xfer_result_t result, volatile uint32_t* ep_reg) +static void __no_inline_not_in_flash_func(handle_endpoint_irq)(uint8_t tu_rhport, xfer_result_t result, volatile uint32_t* ep_reg) { const uint32_t ep_all = *ep_reg; @@ -163,7 +163,6 @@ static void __no_inline_not_in_flash_func(handle_endpoint_irq)(root_port_t* rpor if (ep_all & mask) { endpoint_t* ep = PIO_USB_ENDPOINT(ep_idx); - uint8_t const tu_rhport = rport - PIO_USB_ROOT_PORT(0) + 1; dcd_event_xfer_complete(tu_rhport, ep->ep_num, ep->actual_len, result, true); } } @@ -191,17 +190,17 @@ void __no_inline_not_in_flash_func(pio_usb_device_irq_handler)(uint8_t root_id) if ( ints & PIO_USB_INTS_ENDPOINT_COMPLETE_BITS ) { - handle_endpoint_irq(rport, XFER_RESULT_SUCCESS, &rport->ep_complete); + handle_endpoint_irq(tu_rhport, XFER_RESULT_SUCCESS, &rport->ep_complete); } if ( ints & PIO_USB_INTS_ENDPOINT_STALLED_BITS ) { - handle_endpoint_irq(rport, XFER_RESULT_STALLED, &rport->ep_stalled); + handle_endpoint_irq(tu_rhport, XFER_RESULT_STALLED, &rport->ep_stalled); } if ( ints & PIO_USB_INTS_ENDPOINT_ERROR_BITS ) { - handle_endpoint_irq(rport, XFER_RESULT_FAILED, &rport->ep_error); + handle_endpoint_irq(tu_rhport, XFER_RESULT_FAILED, &rport->ep_error); } // clear all diff --git a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c index 8101fb2d3..f6caabb54 100644 --- a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c @@ -157,8 +157,9 @@ bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) return true; } -static void __no_inline_not_in_flash_func(handle_endpoint_irq)(root_port_t* port, xfer_result_t result, volatile uint32_t* ep_reg) +static void __no_inline_not_in_flash_func(handle_endpoint_irq)(root_port_t* rport, xfer_result_t result, volatile uint32_t* ep_reg) { + (void) rport; const uint32_t ep_all = *ep_reg; for(uint8_t ep_idx = 0; ep_idx < PIO_USB_EP_POOL_CNT; ep_idx++) From fd827a80a9f3b1e482cc8b1609c055cbad252b37 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 27 Apr 2022 01:09:30 +0700 Subject: [PATCH 312/504] everything work great --- lib/Pico-PIO-USB | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB index 125753a97..aecced02e 160000 --- a/lib/Pico-PIO-USB +++ b/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit 125753a9783bc1724a185770b04f83c4ebd4b6c5 +Subproject commit aecced02e756f3a35805cacdd9be25976b6dd978 From 4a661dead0899cb154325a8257d19281f2536af3 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 27 Apr 2022 17:57:52 +0700 Subject: [PATCH 313/504] add TU_ATTR_FAST_FUNC for rp2040 __not_in_flash() section --- examples/device/hid_boot_interface/src/main.c | 2 -- hw/bsp/rp2040/family.cmake | 2 +- src/common/tusb_mcu.h | 7 +++++++ src/device/usbd.c | 3 ++- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/examples/device/hid_boot_interface/src/main.c b/examples/device/hid_boot_interface/src/main.c index 031b17a2e..e5e2f6856 100644 --- a/examples/device/hid_boot_interface/src/main.c +++ b/examples/device/hid_boot_interface/src/main.c @@ -31,8 +31,6 @@ #include "tusb.h" #include "usb_descriptors.h" -#include "pio_usb.h" - //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index 70e18293f..bb146d085 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -47,7 +47,7 @@ if (NOT TARGET _rp2040_family_inclusion_marker) hardware_irq hardware_resets pico_sync - # for usb-pio + # for usb-pio hardware_dma hardware_pio pico_multicore diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 8eb4ad475..c1cf2a810 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -228,6 +228,8 @@ #elif TU_CHECK_MCU(OPT_MCU_RP2040) #define TUP_DCD_ENDPOINT_MAX 16 + #define TU_ATTR_FAST_FUNC __attribute__((section(".time_critical.tinyusb"))) + //------------- Silabs -------------// #elif TU_CHECK_MCU(OPT_MCU_EFM32GG) #define TUP_USBIP_DWC2 @@ -282,4 +284,9 @@ #define TUP_RHPORT_HIGHSPEED 0x00 #endif +// fast function, normally mean placing function in SRAM +#ifndef TU_ATTR_FAST_FUNC + #define TU_ATTR_FAST_FUNC +#endif + #endif diff --git a/src/device/usbd.c b/src/device/usbd.c index 12b4071af..4c2cd3abd 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -1071,7 +1071,8 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const //--------------------------------------------------------------------+ // DCD Event Handler //--------------------------------------------------------------------+ -void __no_inline_not_in_flash_func(dcd_event_handler)(dcd_event_t const * event, bool in_isr) +TU_ATTR_FAST_FUNC +void dcd_event_handler(dcd_event_t const * event, bool in_isr) { switch (event->event_id) { From ae5490e5a5cd8650a45578b4ac70dbe89b002fb1 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 27 Apr 2022 20:52:56 +0700 Subject: [PATCH 314/504] clean up --- examples/device/hid_boot_interface/src/tusb_config.h | 6 ++---- examples/host/cdc_msc_hid/src/tusb_config.h | 7 +++---- src/common/tusb_debug.h | 6 +++--- src/device/usbd.c | 2 +- src/host/usbh.c | 6 +++--- src/portable/raspberrypi/pio_usb/dcd_pio_usb.c | 1 - src/portable/raspberrypi/pio_usb/hcd_pio_usb.c | 1 - 7 files changed, 12 insertions(+), 17 deletions(-) diff --git a/examples/device/hid_boot_interface/src/tusb_config.h b/examples/device/hid_boot_interface/src/tusb_config.h index c8bb8a807..8bc85b722 100644 --- a/examples/device/hid_boot_interface/src/tusb_config.h +++ b/examples/device/hid_boot_interface/src/tusb_config.h @@ -40,10 +40,8 @@ #endif // Use raspberry pio-usb for device -#define CFG_TUD_RPI_PIO_USB 1 -#if CFG_TUD_RPI_PIO_USB -#define BOARD_DEVICE_RHPORT_NUM 1 -#endif +// #define CFG_TUD_RPI_PIO_USB 1 +// #define BOARD_DEVICE_RHPORT_NUM 1 // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_DEVICE_RHPORT_NUM diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index 9d083c771..e9e68cf5a 100644 --- a/examples/host/cdc_msc_hid/src/tusb_config.h +++ b/examples/host/cdc_msc_hid/src/tusb_config.h @@ -40,13 +40,12 @@ #endif // Use raspberry pio-usb for host -#define CFG_TUH_RPI_PIO_USB 1 -//#define CFG_TUSB_RPI_PIO_INC_PATH 1 - +// #define CFG_TUH_RPI_PIO_USB 1 +// #define CFG_TUH_RPI_PIO_USB 1 #if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | OPT_MODE_HIGH_SPEED) -#elif CFG_TUH_RPI_PIO_USB +#elif defined(CFG_TUH_RPI_PIO_USB) && CFG_TUH_RPI_PIO_USB // rp2040: port0 is native, port 1 for PIO-USB #define CFG_TUSB_RHPORT1_MODE OPT_MODE_HOST #else diff --git a/src/common/tusb_debug.h b/src/common/tusb_debug.h index 1ea2c19f5..ac5bee6ec 100644 --- a/src/common/tusb_debug.h +++ b/src/common/tusb_debug.h @@ -57,7 +57,7 @@ void tu_print_mem(void const *buf, uint32_t count, uint8_t indent); #define tu_printf printf #endif -static inline void tu_print_var(uint8_t const* buf, uint32_t bufsize) +static inline void tu_print_arr(uint8_t const* buf, uint32_t bufsize) { for(uint32_t i=0; i Date: Wed, 27 Apr 2022 20:54:21 +0700 Subject: [PATCH 315/504] make hcd_event_handler() fastfunc, and force inline other helper --- src/host/hcd.h | 42 +++++++++++++++++++++++++++++++++++++++--- src/host/usbh.c | 48 +----------------------------------------------- 2 files changed, 40 insertions(+), 50 deletions(-) diff --git a/src/host/hcd.h b/src/host/hcd.h index 9b41f2447..036394c72 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -171,13 +171,49 @@ extern void hcd_devtree_get_info(uint8_t dev_addr, hcd_devtree_info_t* devtree_i extern void hcd_event_handler(hcd_event_t const* event, bool in_isr); // Helper to send device attach event -extern void hcd_event_device_attach(uint8_t rhport, bool in_isr); +TU_ATTR_ALWAYS_INLINE static inline +void hcd_event_device_attach(uint8_t rhport, bool in_isr) +{ + hcd_event_t event; + event.rhport = rhport; + event.event_id = HCD_EVENT_DEVICE_ATTACH; + event.connection.hub_addr = 0; + event.connection.hub_port = 0; + hcd_event_handler(&event, in_isr); +} // Helper to send device removal event -extern void hcd_event_device_remove(uint8_t rhport, bool in_isr); +TU_ATTR_ALWAYS_INLINE static inline +void hcd_event_device_remove(uint8_t rhport, bool in_isr) +{ + hcd_event_t event; + event.rhport = rhport; + event.event_id = HCD_EVENT_DEVICE_REMOVE; + event.connection.hub_addr = 0; + event.connection.hub_port = 0; + + hcd_event_handler(&event, in_isr); +} // Helper to send USB transfer event -extern void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, uint32_t xferred_bytes, xfer_result_t result, bool in_isr); +TU_ATTR_ALWAYS_INLINE static inline +void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, uint32_t xferred_bytes, xfer_result_t result, bool in_isr) +{ + hcd_event_t event = + { + .rhport = 0, // TODO correct rhport + .event_id = HCD_EVENT_XFER_COMPLETE, + .dev_addr = dev_addr, + .xfer_complete = + { + .ep_addr = ep_addr, + .result = result, + .len = xferred_bytes + } + }; + + hcd_event_handler(&event, in_isr); +} #ifdef __cplusplus } diff --git a/src/host/usbh.c b/src/host/usbh.c index a0d9d83d3..99ba964d2 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -855,7 +855,7 @@ void hcd_devtree_get_info(uint8_t dev_addr, hcd_devtree_info_t* devtree_info) } } -void hcd_event_handler(hcd_event_t const* event, bool in_isr) +TU_ATTR_FAST_FUNC void hcd_event_handler(hcd_event_t const* event, bool in_isr) { switch (event->event_id) { @@ -865,52 +865,6 @@ void hcd_event_handler(hcd_event_t const* event, bool in_isr) } } -void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, uint32_t xferred_bytes, xfer_result_t result, bool in_isr) -{ - hcd_event_t event = - { - .rhport = 0, // TODO correct rhport - .event_id = HCD_EVENT_XFER_COMPLETE, - .dev_addr = dev_addr, - .xfer_complete = - { - .ep_addr = ep_addr, - .result = result, - .len = xferred_bytes - } - }; - - hcd_event_handler(&event, in_isr); -} - -void hcd_event_device_attach(uint8_t rhport, bool in_isr) -{ - hcd_event_t event = - { - .rhport = rhport, - .event_id = HCD_EVENT_DEVICE_ATTACH - }; - - event.connection.hub_addr = 0; - event.connection.hub_port = 0; - - hcd_event_handler(&event, in_isr); -} - -void hcd_event_device_remove(uint8_t hostid, bool in_isr) -{ - hcd_event_t event = - { - .rhport = hostid, - .event_id = HCD_EVENT_DEVICE_REMOVE - }; - - event.connection.hub_addr = 0; - event.connection.hub_port = 0; - - hcd_event_handler(&event, in_isr); -} - //--------------------------------------------------------------------+ // Descriptors Async //--------------------------------------------------------------------+ From 85dcb737749576d1c2946f3993b964c59974f38c Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 28 Apr 2022 18:00:30 +0700 Subject: [PATCH 316/504] more clean up --- lib/Pico-PIO-USB | 2 +- src/device/usbd.c | 3 +-- src/host/usbh.c | 9 +++++---- src/portable/raspberrypi/pio_usb/dcd_pio_usb.c | 1 + 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB index aecced02e..6f76de3c0 160000 --- a/lib/Pico-PIO-USB +++ b/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit aecced02e756f3a35805cacdd9be25976b6dd978 +Subproject commit 6f76de3c0fb4679afc9f953cd4fec0637ebd2f15 diff --git a/src/device/usbd.c b/src/device/usbd.c index e545e8056..1dd1a352e 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -1071,8 +1071,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const //--------------------------------------------------------------------+ // DCD Event Handler //--------------------------------------------------------------------+ -TU_ATTR_FAST_FUNC -void dcd_event_handler(dcd_event_t const * event, bool in_isr) +TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const * event, bool in_isr) { switch (event->event_id) { diff --git a/src/host/usbh.c b/src/host/usbh.c index 99ba964d2..74ffb5c38 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -1139,7 +1139,7 @@ enum { //ENUM_HUB_GET_STATUS_1, ENUM_HUB_CLEAR_RESET_1, ENUM_ADDR0_DEVICE_DESC, - ENUM_RESET_2, // 2nd reset before set address + ENUM_RESET_2, // 2nd reset before set address (not used) ENUM_HUB_GET_STATUS_2, ENUM_HUB_CLEAR_RESET_2, ENUM_SET_ADDR, @@ -1227,17 +1227,17 @@ static void process_enumeration(tuh_xfer_t* xfer) } break; +#if 0 case ENUM_RESET_2: + // XXX note used by now, but may be needed for some devices !? // Reset device again before Set Address - TU_LOG2("Port reset \r\n"); + TU_LOG2("Port reset2 \r\n"); if (_dev0.hub_addr == 0) { // connected directly to roothub -#if !CFG_TUH_RPI_PIO_USB // FIXME skip this reset for pio-usb hcd_port_reset( _dev0.rhport ); osal_task_delay(RESET_DELAY); hcd_port_reset_end(_dev0.rhport); -#endif // TODO: fall through to SET ADDRESS, refactor later } #if CFG_TUH_HUB @@ -1249,6 +1249,7 @@ static void process_enumeration(tuh_xfer_t* xfer) } #endif __attribute__((fallthrough)); +#endif case ENUM_SET_ADDR: enum_request_set_addr(); diff --git a/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c index fb10087b5..1bc5594d8 100644 --- a/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c @@ -135,6 +135,7 @@ void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) { (void) rhport; endpoint_t *ep = pio_usb_device_get_endpoint_by_address(ep_addr); + ep->has_transfer = false; ep->stalled = true; } From 608577e05c9f2e2e8831d8819090ed376d08284b Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 29 Apr 2022 18:05:50 +0700 Subject: [PATCH 317/504] update pio --- lib/Pico-PIO-USB | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB index 6f76de3c0..7e147ad44 160000 --- a/lib/Pico-PIO-USB +++ b/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit 6f76de3c0fb4679afc9f953cd4fec0637ebd2f15 +Subproject commit 7e147ad44dbd5038590449418b26fb867024db6c From 0b30a10ab3c2f1fdcf4fae8f530c80bf5cffaf96 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 29 Apr 2022 22:24:36 +0700 Subject: [PATCH 318/504] configure hid_to_cdc example to build with rp2040 with pio usb as host --- examples/host/hid_to_cdc/CMakeLists.txt | 3 +- examples/host/hid_to_cdc/only.txt | 1 + examples/host/hid_to_cdc/src/main.c | 213 ++++++++++----------- examples/host/hid_to_cdc/src/tusb_config.h | 12 +- hw/bsp/rp2040/family.cmake | 56 ++++-- lib/Pico-PIO-USB | 2 +- src/host/usbh.c | 2 +- 7 files changed, 148 insertions(+), 141 deletions(-) diff --git a/examples/host/hid_to_cdc/CMakeLists.txt b/examples/host/hid_to_cdc/CMakeLists.txt index abc4d91da..ff9f58c4c 100644 --- a/examples/host/hid_to_cdc/CMakeLists.txt +++ b/examples/host/hid_to_cdc/CMakeLists.txt @@ -25,4 +25,5 @@ target_include_directories(${PROJECT} PUBLIC # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. -family_configure_device_example(${PROJECT}) \ No newline at end of file +family_configure_device_example(${PROJECT}) +family_configure_host_example(${PROJECT}) diff --git a/examples/host/hid_to_cdc/only.txt b/examples/host/hid_to_cdc/only.txt index 78d94e3ce..6ee8e3fde 100644 --- a/examples/host/hid_to_cdc/only.txt +++ b/examples/host/hid_to_cdc/only.txt @@ -1,2 +1,3 @@ board:mimxrt1060_evk board:mimxrt1064_evk +mcu:RP2040 diff --git a/examples/host/hid_to_cdc/src/main.c b/examples/host/hid_to_cdc/src/main.c index cdf5d264e..f0e78887b 100644 --- a/examples/host/hid_to_cdc/src/main.c +++ b/examples/host/hid_to_cdc/src/main.c @@ -73,12 +73,14 @@ enum { static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; void led_blinking_task(void); -void cdc_task(void); /*------------- MAIN -------------*/ int main(void) { board_init(); + + printf("TinyUSB Host HID <-> Device CDC Example\r\n"); + tusb_init(); while (1) @@ -86,15 +88,13 @@ int main(void) tud_task(); // tinyusb device task tuh_task(); // tinyusb host task led_blinking_task(); - - cdc_task(); } return 0; } //--------------------------------------------------------------------+ -// Device callbacks +// Device CDC //--------------------------------------------------------------------+ // Invoked when device is mounted @@ -124,8 +124,20 @@ void tud_resume_cb(void) blink_interval_ms = BLINK_MOUNTED; } +// Invoked when CDC interface received data from host +void tud_cdc_rx_cb(uint8_t itf) +{ + (void) itf; + + char buf[64]; + uint32_t count = tud_cdc_read(buf, sizeof(buf)); + + // TODO control LED on keyboard of host stack + (void) count; +} + //--------------------------------------------------------------------+ -// Host callbacks +// Host HID //--------------------------------------------------------------------+ // Invoked when device with hid interface is mounted @@ -137,169 +149,138 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re { (void)desc_report; (void)desc_len; + + // Interface protocol (hid_interface_protocol_enum_t) + const char* protocol_str[] = { "None", "Keyboard", "Mouse" }; + uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance); + uint16_t vid, pid; tuh_vid_pid_get(dev_addr, &vid, &pid); - printf("HID device address = %d, instance = %d is mounted\r\n", dev_addr, instance); - printf("VID = %04x, PID = %04x\r\n", vid, pid); + printf("[%04x:%04x][%u] HID Interface instance = %d, Protocol = %s\r\n", vid, pid, dev_addr, instance, protocol_str[itf_protocol]); - // Receive any report and treat it like a keyboard. + // Receive report from boot keyboard & mouse only // tuh_hid_report_received_cb() will be invoked when report is available - if ( !tuh_hid_receive_report(dev_addr, instance) ) + if (itf_protocol == HID_ITF_PROTOCOL_KEYBOARD || itf_protocol == HID_ITF_PROTOCOL_MOUSE) { - printf("Error: cannot request to receive report\r\n"); + if ( !tuh_hid_receive_report(dev_addr, instance) ) + { + printf("Error: cannot request report\r\n"); + } } } // Invoked when device with hid interface is un-mounted void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) { - printf("HID device address = %d, instance = %d is unmounted\r\n", dev_addr, instance); + printf("[%u] HID Interface instance = %d is unmounted\r\n", dev_addr, instance); } // keycodes from last report to check if key is holding or newly pressed uint8_t last_keycodes[6] = {0}; // look up new key in previous keys -static inline bool key_in_last_report(const uint8_t key_arr[6], uint8_t keycode) +static inline bool find_key_in_report(hid_keyboard_report_t const *report, uint8_t keycode) { for(uint8_t i=0; i<6; i++) { - if (key_arr[i] == keycode) return true; + if (report->keycode[i] == keycode) return true; } return false; } -// Invoked when received report from device via interrupt endpoint -void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len) + +// convert hid keycode to ascii and print via usb device CDC (ignore non-printable) +static void process_kbd_report(hid_keyboard_report_t const *report) { - if (len != 8) - { - char ch_num; - - tud_cdc_write_str("incorrect report len: "); - - if ( len > 10 ) - { - ch_num = '0' + (len / 10); - tud_cdc_write(&ch_num, 1); - len = len % 10; - } - - ch_num = '0' + len; - tud_cdc_write(&ch_num, 1); - - tud_cdc_write_str("\r\n"); - tud_cdc_write_flush(); - - // Don't request a new report for a wrong sized endpoint. - return; - } - - uint8_t const modifiers = report[0]; + static hid_keyboard_report_t prev_report = { 0, 0, {0} }; // previous report to check key released bool flush = false; - for (int i = 2; i < 8; i++) + for(uint8_t i=0; i<6; i++) { - uint8_t keycode = report[i]; - - if (keycode) + uint8_t keycode = report->keycode[i]; + if ( keycode ) { - if ( key_in_last_report(last_keycodes, keycode) ) + if ( find_key_in_report(&prev_report, keycode) ) { // exist in previous report means the current key is holding - // do nothing }else { // not existed in previous report means the current key is pressed - // Only print keycodes 0 - 128. - if (keycode < 128) - { - // remap the key code for Colemak layout so @tannewt can type. - #ifdef KEYBOARD_COLEMAK - uint8_t colemak_key_code = colemak[keycode]; - if (colemak_key_code != 0) keycode = colemak_key_code; - #endif - bool const is_shift = modifiers & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT); - char c = keycode2ascii[keycode][is_shift ? 1 : 0]; - if (c) - { - if (c == '\n') tud_cdc_write("\r", 1); - tud_cdc_write(&c, 1); - flush = true; - } + // remap the key code for Colemak layout + #ifdef KEYBOARD_COLEMAK + uint8_t colemak_key_code = colemak[keycode]; + if (colemak_key_code != 0) keycode = colemak_key_code; + #endif + + bool const is_shift = report->modifier & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT); + uint8_t ch = keycode2ascii[keycode][is_shift ? 1 : 0]; + + if (ch) + { + if (ch == '\n') tud_cdc_write("\r", 1); + tud_cdc_write(&ch, 1); + flush = true; } } } + // TODO example skips key released } if (flush) tud_cdc_write_flush(); - // save current report - memcpy(last_keycodes, report+2, 6); + prev_report = *report; +} + +// send mouse report to usb device CDC +static void process_mouse_report(hid_mouse_report_t const * report) +{ + static hid_mouse_report_t prev_report = { 0 }; + + char tempbuf[32]; + int count; + + //------------- button state -------------// + //uint8_t button_changed_mask = report->buttons ^ prev_report.buttons; + char l = report->buttons & MOUSE_BUTTON_LEFT ? 'L' : '-'; + char m = report->buttons & MOUSE_BUTTON_MIDDLE ? 'M' : '-'; + char r = report->buttons & MOUSE_BUTTON_RIGHT ? 'R' : '-'; + + count = sprintf(tempbuf, " %c%c%c %d %d %d\r\n", l, m, r, report->x, report->y, report->wheel); + + tud_cdc_write(tempbuf, count); + tud_cdc_write_flush(); +} + +// Invoked when received report from device via interrupt endpoint +void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len) +{ + uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance); + + switch(itf_protocol) + { + case HID_ITF_PROTOCOL_KEYBOARD: + process_kbd_report( (hid_keyboard_report_t const*) report ); + break; + + case HID_ITF_PROTOCOL_MOUSE: + process_mouse_report( (hid_mouse_report_t const*) report ); + break; + + default: break; + } // continue to request to receive report if ( !tuh_hid_receive_report(dev_addr, instance) ) { - printf("Error: cannot request to receive report\r\n"); + printf("Error: cannot request report\r\n"); } } - - //--------------------------------------------------------------------+ -// USB CDC -//--------------------------------------------------------------------+ -void cdc_task(void) -{ - // connected() check for DTR bit - // Most but not all terminal client set this when making connection - // if ( tud_cdc_connected() ) - { - // connected and there are data available - if ( tud_cdc_available() ) - { - // read datas - char buf[64]; - uint32_t count = tud_cdc_read(buf, sizeof(buf)); - (void) count; - - // Echo back - // Note: Skip echo by commenting out write() and write_flush() - // for throughput test e.g - // $ dd if=/dev/zero of=/dev/ttyACM0 count=10000 - tud_cdc_write(buf, count); - tud_cdc_write_flush(); - } - } -} - -// Invoked when cdc when line state changed e.g connected/disconnected -void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) -{ - (void) itf; - (void) rts; - - // TODO set some indicator - if ( dtr ) - { - // Terminal connected - }else - { - // Terminal disconnected - } -} - -// Invoked when CDC interface received data from host -void tud_cdc_rx_cb(uint8_t itf) -{ - (void) itf; -} - -//--------------------------------------------------------------------+ -// BLINKING TASK +// Blinking Task //--------------------------------------------------------------------+ void led_blinking_task(void) { diff --git a/examples/host/hid_to_cdc/src/tusb_config.h b/examples/host/hid_to_cdc/src/tusb_config.h index 9a35ffc30..0fa4899a9 100644 --- a/examples/host/hid_to_cdc/src/tusb_config.h +++ b/examples/host/hid_to_cdc/src/tusb_config.h @@ -49,6 +49,9 @@ #define BOARD_HOST_RHPORT_NUM 1 #endif +// Use raspberry pio-usb for host +#define CFG_TUH_RPI_PIO_USB 1 + // RHPort max operational speed can defined by board.mk // Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed #ifndef BOARD_DEVICE_RHPORT_SPEED @@ -124,10 +127,6 @@ //------------- CLASS -------------// #define CFG_TUD_CDC 1 -#define CFG_TUD_MSC 0 -#define CFG_TUD_HID 0 -#define CFG_TUD_MIDI 0 -#define CFG_TUD_VENDOR 0 // CDC FIFO size of TX and RX #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) @@ -144,14 +143,9 @@ #define CFG_TUH_ENUMERATION_BUFSIZE 256 #define CFG_TUH_HUB 1 -#define CFG_TUH_CDC 0 -#define CFG_TUH_MSC 0 -#define CFG_TUH_VENDOR 0 - // max device support (excluding hub device) #define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB ? 4 : 1) // hub typically has 4 ports -//------------- HID -------------// #define CFG_TUH_HID 4 #define CFG_TUH_HID_EPIN_BUFSIZE 64 #define CFG_TUH_HID_EPOUT_BUFSIZE 64 diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index bb146d085..c3ea077bb 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -23,23 +23,20 @@ if (NOT TARGET _rp2040_family_inclusion_marker) set(PICO_TINYUSB_PATH ${TOP}) endif() + #------------------------------------ # Base config for both device and host; wrapped by SDK's tinyusb_common + #------------------------------------ add_library(tinyusb_common_base INTERFACE) - + target_sources(tinyusb_common_base INTERFACE ${TOP}/src/tusb.c ${TOP}/src/common/tusb_fifo.c - ${TOP}/lib/Pico-PIO-USB/pio_usb.c - ${TOP}/lib/Pico-PIO-USB/pio_usb_host.c - ${TOP}/lib/Pico-PIO-USB/pio_usb_device.c - ${TOP}/lib/Pico-PIO-USB/usb_crc.c ) target_include_directories(tinyusb_common_base INTERFACE ${TOP}/src ${TOP}/src/common ${TOP}/hw - ${TOP}/lib/Pico-PIO-USB ) target_link_libraries(tinyusb_common_base INTERFACE @@ -47,10 +44,6 @@ if (NOT TARGET _rp2040_family_inclusion_marker) hardware_irq hardware_resets pico_sync - # for usb-pio - hardware_dma - hardware_pio - pico_multicore ) set(TINYUSB_DEBUG_LEVEL 0) @@ -65,7 +58,35 @@ if (NOT TARGET _rp2040_family_inclusion_marker) CFG_TUSB_DEBUG=${TINYUSB_DEBUG_LEVEL} ) + #------------------------------------ + # PIO USB for both host and device + #------------------------------------ + add_library(tinyusb_pio_usb_base INTERFACE) + + target_sources(tinyusb_pio_usb_base INTERFACE + ${TOP}/lib/Pico-PIO-USB/pio_usb.c + ${TOP}/lib/Pico-PIO-USB/pio_usb_host.c + ${TOP}/lib/Pico-PIO-USB/pio_usb_device.c + ${TOP}/lib/Pico-PIO-USB/usb_crc.c + ) + + target_include_directories(tinyusb_pio_usb_base INTERFACE + ${TOP}/lib/Pico-PIO-USB + ) + + target_link_libraries(tinyusb_pio_usb_base INTERFACE + hardware_dma + hardware_pio + pico_multicore + ) + + target_compile_definitions(tinyusb_pio_usb_base INTERFACE + PIO_USB_USE_TINYUSB + ) + + #------------------------------------ # Base config for device mode; wrapped by SDK's tinyusb_device + #------------------------------------ add_library(tinyusb_device_base INTERFACE) target_sources(tinyusb_device_base INTERFACE ${TOP}/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -87,7 +108,9 @@ if (NOT TARGET _rp2040_family_inclusion_marker) ${TOP}/src/class/video/video_device.c ) + #------------------------------------ # Base config for host mode; wrapped by SDK's tinyusb_host + #------------------------------------ add_library(tinyusb_host_base INTERFACE) target_sources(tinyusb_host_base INTERFACE ${TOP}/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -105,7 +128,10 @@ if (NOT TARGET _rp2040_family_inclusion_marker) target_compile_definitions(tinyusb_host_base INTERFACE RP2040_USB_HOST_MODE=1 ) - + + #------------------------------------ + # BSP & Additions + #------------------------------------ add_library(tinyusb_bsp INTERFACE) target_sources(tinyusb_bsp INTERFACE ${TOP}/hw/bsp/rp2040/family.c @@ -139,6 +165,10 @@ if (NOT TARGET _rp2040_family_inclusion_marker) ) endif() + #------------------------------------ + # Functions + #------------------------------------ + function(family_configure_target TARGET) pico_add_extra_outputs(${TARGET}) pico_enable_stdio_uart(${TARGET} 1) @@ -147,12 +177,12 @@ if (NOT TARGET _rp2040_family_inclusion_marker) function(family_configure_device_example TARGET) family_configure_target(${TARGET}) - target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_device) + target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_device tinyusb_pio_usb_base) endfunction() function(family_configure_host_example TARGET) family_configure_target(${TARGET}) - target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_host) + target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_host tinyusb_pio_usb_base) endfunction() function(family_initialize_project PROJECT DIR) diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB index 7e147ad44..1ab409f13 160000 --- a/lib/Pico-PIO-USB +++ b/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit 7e147ad44dbd5038590449418b26fb867024db6c +Subproject commit 1ab409f13bd888b8f1f7c9bf3bd7269d1ccc1c79 diff --git a/src/host/usbh.c b/src/host/usbh.c index 74ffb5c38..e0e41a8d1 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -630,7 +630,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result if (XFER_RESULT_SUCCESS != result) { - TU_LOG2("[%u:%u] Control %s\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED"); + TU_LOG1("[%u:%u] Control %s\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED"); // terminate transfer if any stage failed _xfer_complete(dev_addr, result); From c289438b75af9b256a954c6a9293a21825c53e04 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 29 Apr 2022 23:03:52 +0700 Subject: [PATCH 319/504] fix ci build --- examples/host/hid_to_cdc/src/main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/host/hid_to_cdc/src/main.c b/examples/host/hid_to_cdc/src/main.c index f0e78887b..cc811cd71 100644 --- a/examples/host/hid_to_cdc/src/main.c +++ b/examples/host/hid_to_cdc/src/main.c @@ -237,8 +237,6 @@ static void process_kbd_report(hid_keyboard_report_t const *report) // send mouse report to usb device CDC static void process_mouse_report(hid_mouse_report_t const * report) { - static hid_mouse_report_t prev_report = { 0 }; - char tempbuf[32]; int count; From d51743a21cb23f7e0c81844f12bba08420a52a29 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Sun, 1 May 2022 14:04:36 +0200 Subject: [PATCH 320/504] Add TU_BREAKPOINT for mips architecture _mips is provided by xc32-gcc --- src/common/tusb_verify.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/common/tusb_verify.h b/src/common/tusb_verify.h index 568bac8cc..a52a6d269 100644 --- a/src/common/tusb_verify.h +++ b/src/common/tusb_verify.h @@ -90,6 +90,9 @@ #elif defined(__riscv) #define TU_BREAKPOINT() do { __asm("ebreak\n"); } while(0) +#elif defined(_mips) + #define TU_BREAKPOINT() do { __asm("sdbbp 0"); } while (0) + #else #define TU_BREAKPOINT() do {} while (0) #endif From c145777e0eb6b9add414504dd8cf4ec7da6cc61a Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Sun, 1 May 2022 14:14:42 +0200 Subject: [PATCH 321/504] dcd_pic32: Add asserts transfer sanity check TU_ASSERTS added to detect transfer inconsistency. --- src/portable/microchip/pic32mz/dcd_pic32mz.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/portable/microchip/pic32mz/dcd_pic32mz.c b/src/portable/microchip/pic32mz/dcd_pic32mz.c index 7d48f755b..1683d95b4 100644 --- a/src/portable/microchip/pic32mz/dcd_pic32mz.c +++ b/src/portable/microchip/pic32mz/dcd_pic32mz.c @@ -530,6 +530,7 @@ static void ep0_handle_rx(void) transferred = rx_fifo_read(0, xfer->buffer + xfer->transferred); xfer->transferred += transferred; + TU_ASSERT(xfer->transferred <= xfer->total_len,); if (transferred < xfer->max_packet_size || xfer->transferred == xfer->total_len) { ep0_set_stage(EP0_STAGE_DATA_OUT_COMPLETE); @@ -560,6 +561,7 @@ static void epn_handle_rx_int(uint8_t epnum) transferred = rx_fifo_read(epnum, xfer->buffer + xfer->transferred); USB_REGS->EPCSR[epnum].RXCSRL_HOSTbits.RXPKTRDY = 0; xfer->transferred += transferred; + TU_ASSERT(xfer->transferred <= xfer->total_len,); if (transferred < xfer->max_packet_size || xfer->transferred == xfer->total_len) { xfer_complete(xfer, XFER_RESULT_SUCCESS, true); @@ -579,6 +581,7 @@ static void epn_handle_tx_int(uint8_t epnum) else { xfer->transferred += xfer->last_packet_size; + TU_ASSERT(xfer->transferred <= xfer->total_len,); if (xfer->last_packet_size < xfer->max_packet_size || xfer->transferred == xfer->total_len) { xfer->last_packet_size = 0; From e49cad84e2798ddd4ee49d3684ce7b414d30ccb2 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Sun, 1 May 2022 14:18:53 +0200 Subject: [PATCH 322/504] dcd_pic32: Fix memory overwrite in incoming data When transfer was finished rx_fifo_read() read all that was to read RXPKTRDY was cleared allowing next packet to be received. Then xfer_complete was called. Interrupt for OUT endpoint was left enable, that would not be a problem if data was handled fast and new transfer was scheduled. For MSC when host sends a lot of data this interrupt that was enabled could cause epn_handle_rx_int() to be called after transfer was completed and next was not scheduled yet. Without TU_ASSERT that was added to detect this, incoming data was written past buffer provided by user code resulting in random memory corruption. This just blocks RX interrupt when transfer is finished, and also only unmasked rx interrupts are handled. --- src/portable/microchip/pic32mz/dcd_pic32mz.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/portable/microchip/pic32mz/dcd_pic32mz.c b/src/portable/microchip/pic32mz/dcd_pic32mz.c index 1683d95b4..2103d41fb 100644 --- a/src/portable/microchip/pic32mz/dcd_pic32mz.c +++ b/src/portable/microchip/pic32mz/dcd_pic32mz.c @@ -564,6 +564,7 @@ static void epn_handle_rx_int(uint8_t epnum) TU_ASSERT(xfer->transferred <= xfer->total_len,); if (transferred < xfer->max_packet_size || xfer->transferred == xfer->total_len) { + USB_REGS->INTRRXEbits.w &= ~(1u << epnum); xfer_complete(xfer, XFER_RESULT_SUCCESS, true); } } @@ -692,7 +693,7 @@ void dcd_int_handler(uint8_t rhport) int i; uint8_t mask; __USBCSR2bits_t csr2_bits; - uint16_t rxints = USB_REGS->INTRRX; + uint16_t rxints = USB_REGS->INTRRX & USB_REGS->INTRRXEbits.w; uint16_t txints = USB_REGS->INTRTX; csr2_bits = USBCSR2bits; (void) rhport; From f452ab745ef953d74704bc5429ff16a80a5b325a Mon Sep 17 00:00:00 2001 From: Pascal Speck Date: Tue, 3 May 2022 09:52:10 +0200 Subject: [PATCH 323/504] overwrite grstctl on edpt_disable --- src/portable/synopsys/dwc2/dcd_dwc2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index c71f38d2d..01b74d05e 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -796,7 +796,7 @@ static void dcd_edpt_disable (uint8_t rhport, uint8_t ep_addr, bool stall) } // Flush the FIFO, and wait until we have confirmed it cleared. - dwc2->grstctl |= (epnum << GRSTCTL_TXFNUM_Pos); + dwc2->grstctl = (epnum << GRSTCTL_TXFNUM_Pos); dwc2->grstctl |= GRSTCTL_TXFFLSH; while ( (dwc2->grstctl & GRSTCTL_TXFFLSH_Msk) != 0 ) {} } From f19d913b5d67ecf1b4f4d84c9d9a5880376f5a21 Mon Sep 17 00:00:00 2001 From: caleb crome Date: Thu, 5 May 2022 14:36:02 -0700 Subject: [PATCH 324/504] set irq priority for freertos --- hw/bsp/imxrt/family.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hw/bsp/imxrt/family.c b/hw/bsp/imxrt/family.c index a811a7e40..8d34d4b9f 100644 --- a/hw/bsp/imxrt/family.c +++ b/hw/bsp/imxrt/family.c @@ -51,7 +51,10 @@ void board_init(void) SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) -// NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + NVIC_SetPriority(USB_OTG1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); +#ifdef USB_OTG2_IRQn + NVIC_SetPriority(USB_OTG2_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); +#endif #endif // LED From 79b5ab822ec1a17d6bfe88f6135613ba50acedbd Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 6 May 2022 17:22:52 +0700 Subject: [PATCH 325/504] fix incorrect total number of interface --- examples/host/hid_to_cdc/src/usb_descriptors.c | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/host/hid_to_cdc/src/usb_descriptors.c b/examples/host/hid_to_cdc/src/usb_descriptors.c index 7dd73937c..e55899f65 100644 --- a/examples/host/hid_to_cdc/src/usb_descriptors.c +++ b/examples/host/hid_to_cdc/src/usb_descriptors.c @@ -81,7 +81,6 @@ enum { ITF_NUM_CDC = 0, ITF_NUM_CDC_DATA, - ITF_NUM_MSC, ITF_NUM_TOTAL }; From 26ee62222290abf016ff4eb801d1289e05e595a1 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 10 May 2022 12:51:48 +0700 Subject: [PATCH 326/504] move pio usb files to src --- hw/bsp/rp2040/family.cmake | 14 +++++++------- lib/Pico-PIO-USB | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index c3ea077bb..f51976d39 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -64,14 +64,14 @@ if (NOT TARGET _rp2040_family_inclusion_marker) add_library(tinyusb_pio_usb_base INTERFACE) target_sources(tinyusb_pio_usb_base INTERFACE - ${TOP}/lib/Pico-PIO-USB/pio_usb.c - ${TOP}/lib/Pico-PIO-USB/pio_usb_host.c - ${TOP}/lib/Pico-PIO-USB/pio_usb_device.c - ${TOP}/lib/Pico-PIO-USB/usb_crc.c + ${TOP}/lib/Pico-PIO-USB/src/pio_usb.c + ${TOP}/lib/Pico-PIO-USB/src/pio_usb_host.c + ${TOP}/lib/Pico-PIO-USB/src/pio_usb_device.c + ${TOP}/lib/Pico-PIO-USB/src/usb_crc.c ) target_include_directories(tinyusb_pio_usb_base INTERFACE - ${TOP}/lib/Pico-PIO-USB + ${TOP}/lib/Pico-PIO-USB/src ) target_link_libraries(tinyusb_pio_usb_base INTERFACE @@ -190,8 +190,8 @@ if (NOT TARGET _rp2040_family_inclusion_marker) _family_initialize_project(${PROJECT} ${DIR}) enable_language(C CXX ASM) pico_sdk_init() - pico_generate_pio_header(tinyusb_common_base ${TOP}/lib/Pico-PIO-USB/usb_tx.pio) - pico_generate_pio_header(tinyusb_common_base ${TOP}/lib/Pico-PIO-USB/usb_rx.pio) + pico_generate_pio_header(tinyusb_common_base ${TOP}/lib/Pico-PIO-USB/src/usb_tx.pio) + pico_generate_pio_header(tinyusb_common_base ${TOP}/lib/Pico-PIO-USB/src/usb_rx.pio) endfunction() # This method must be called from the project scope to suppress known warnings in TinyUSB source files diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB index 1ab409f13..d2c6c4592 160000 --- a/lib/Pico-PIO-USB +++ b/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit 1ab409f13bd888b8f1f7c9bf3bd7269d1ccc1c79 +Subproject commit d2c6c459277816466cc087a5e27f41d2ce257f46 From e3b57cea05b5e023bba7472bf8c583d4adc29e3e Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 10 May 2022 13:01:28 +0700 Subject: [PATCH 327/504] rename host/hid_to_cdc to dual/host_hid_to_device_cdc --- .../hid_to_cdc => dual/host_hid_to_device_cdc}/CMakeLists.txt | 0 .../{host/hid_to_cdc => dual/host_hid_to_device_cdc}/Makefile | 0 .../{host/hid_to_cdc => dual/host_hid_to_device_cdc}/only.txt | 0 .../{host/hid_to_cdc => dual/host_hid_to_device_cdc}/src/main.c | 0 .../hid_to_cdc => dual/host_hid_to_device_cdc}/src/tusb_config.h | 0 .../host_hid_to_device_cdc}/src/usb_descriptors.c | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename examples/{host/hid_to_cdc => dual/host_hid_to_device_cdc}/CMakeLists.txt (100%) rename examples/{host/hid_to_cdc => dual/host_hid_to_device_cdc}/Makefile (100%) rename examples/{host/hid_to_cdc => dual/host_hid_to_device_cdc}/only.txt (100%) rename examples/{host/hid_to_cdc => dual/host_hid_to_device_cdc}/src/main.c (100%) rename examples/{host/hid_to_cdc => dual/host_hid_to_device_cdc}/src/tusb_config.h (100%) rename examples/{host/hid_to_cdc => dual/host_hid_to_device_cdc}/src/usb_descriptors.c (100%) diff --git a/examples/host/hid_to_cdc/CMakeLists.txt b/examples/dual/host_hid_to_device_cdc/CMakeLists.txt similarity index 100% rename from examples/host/hid_to_cdc/CMakeLists.txt rename to examples/dual/host_hid_to_device_cdc/CMakeLists.txt diff --git a/examples/host/hid_to_cdc/Makefile b/examples/dual/host_hid_to_device_cdc/Makefile similarity index 100% rename from examples/host/hid_to_cdc/Makefile rename to examples/dual/host_hid_to_device_cdc/Makefile diff --git a/examples/host/hid_to_cdc/only.txt b/examples/dual/host_hid_to_device_cdc/only.txt similarity index 100% rename from examples/host/hid_to_cdc/only.txt rename to examples/dual/host_hid_to_device_cdc/only.txt diff --git a/examples/host/hid_to_cdc/src/main.c b/examples/dual/host_hid_to_device_cdc/src/main.c similarity index 100% rename from examples/host/hid_to_cdc/src/main.c rename to examples/dual/host_hid_to_device_cdc/src/main.c diff --git a/examples/host/hid_to_cdc/src/tusb_config.h b/examples/dual/host_hid_to_device_cdc/src/tusb_config.h similarity index 100% rename from examples/host/hid_to_cdc/src/tusb_config.h rename to examples/dual/host_hid_to_device_cdc/src/tusb_config.h diff --git a/examples/host/hid_to_cdc/src/usb_descriptors.c b/examples/dual/host_hid_to_device_cdc/src/usb_descriptors.c similarity index 100% rename from examples/host/hid_to_cdc/src/usb_descriptors.c rename to examples/dual/host_hid_to_device_cdc/src/usb_descriptors.c From 993f7b6a2c0b325683ebb4f7dc5b0039d92c1eab Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 10 May 2022 13:15:07 +0700 Subject: [PATCH 328/504] include dual examples to ci --- tools/build_board.py | 11 +++++------ tools/build_family.py | 11 +++++------ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/tools/build_board.py b/tools/build_board.py index b2a80c680..4d895329a 100644 --- a/tools/build_board.py +++ b/tools/build_board.py @@ -28,12 +28,11 @@ def filter_with_input(mylist): # If examples are not specified in arguments, build all all_examples = [] -for entry in os.scandir("examples/device"): - if entry.is_dir(): - all_examples.append("device/" + entry.name) -for entry in os.scandir("examples/host"): - if entry.is_dir(): - all_examples.append("host/" + entry.name) +for dir1 in os.scandir("examples"): + if dir1.is_dir(): + for entry in os.scandir(dir1.path): + if entry.is_dir(): + all_examples.append(dir1.name + '/' + entry.name) filter_with_input(all_examples) all_examples.sort() diff --git a/tools/build_family.py b/tools/build_family.py index 4094d07db..095ca4ff7 100644 --- a/tools/build_family.py +++ b/tools/build_family.py @@ -28,12 +28,11 @@ def filter_with_input(mylist): # If examples are not specified in arguments, build all all_examples = [] -for entry in os.scandir("examples/device"): - if entry.is_dir(): - all_examples.append("device/" + entry.name) -for entry in os.scandir("examples/host"): - if entry.is_dir(): - all_examples.append("host/" + entry.name) +for dir1 in os.scandir("examples"): + if dir1.is_dir(): + for entry in os.scandir(dir1.path): + if entry.is_dir(): + all_examples.append(dir1.name + '/' + entry.name) filter_with_input(all_examples) all_examples.sort() From 717a47412548923123141503749f721184222cf0 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 10 May 2022 21:56:47 +0700 Subject: [PATCH 329/504] move pio-usb init to family_configure_pio_usb_example() to stay compatible --- examples/dual/host_hid_to_device_cdc/CMakeLists.txt | 1 + examples/host/bare_api/CMakeLists.txt | 5 ++++- examples/host/cdc_msc_hid/CMakeLists.txt | 3 +++ examples/host/hid_controller/CMakeLists.txt | 5 ++++- hw/bsp/rp2040/family.cmake | 13 +++++++++---- 5 files changed, 21 insertions(+), 6 deletions(-) diff --git a/examples/dual/host_hid_to_device_cdc/CMakeLists.txt b/examples/dual/host_hid_to_device_cdc/CMakeLists.txt index ff9f58c4c..bf3e042d1 100644 --- a/examples/dual/host_hid_to_device_cdc/CMakeLists.txt +++ b/examples/dual/host_hid_to_device_cdc/CMakeLists.txt @@ -27,3 +27,4 @@ target_include_directories(${PROJECT} PUBLIC # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) family_configure_host_example(${PROJECT}) +family_configure_pio_usb_example(${PROJECT}) diff --git a/examples/host/bare_api/CMakeLists.txt b/examples/host/bare_api/CMakeLists.txt index bff281a8c..e2e8d4fd5 100644 --- a/examples/host/bare_api/CMakeLists.txt +++ b/examples/host/bare_api/CMakeLists.txt @@ -24,4 +24,7 @@ target_include_directories(${PROJECT} PUBLIC # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. -family_configure_host_example(${PROJECT}) \ No newline at end of file +family_configure_host_example(${PROJECT}) + +# For rp2040, un-comment to enable pico-pio-usb +# family_configure_pio_usb_example(${PROJECT}) diff --git a/examples/host/cdc_msc_hid/CMakeLists.txt b/examples/host/cdc_msc_hid/CMakeLists.txt index 95c07339e..ca0f8e48a 100644 --- a/examples/host/cdc_msc_hid/CMakeLists.txt +++ b/examples/host/cdc_msc_hid/CMakeLists.txt @@ -27,3 +27,6 @@ target_include_directories(${PROJECT} PUBLIC # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_host_example(${PROJECT}) + +# For rp2040, un-comment to enable pico-pio-usb +# family_configure_pio_usb_example(${PROJECT}) diff --git a/examples/host/hid_controller/CMakeLists.txt b/examples/host/hid_controller/CMakeLists.txt index aaf8bc34f..60678fc1c 100644 --- a/examples/host/hid_controller/CMakeLists.txt +++ b/examples/host/hid_controller/CMakeLists.txt @@ -25,4 +25,7 @@ target_include_directories(${PROJECT} PUBLIC # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. -family_configure_host_example(${PROJECT}) \ No newline at end of file +family_configure_host_example(${PROJECT}) + +# For rp2040, un-comment to enable pico-pio-usb +# family_configure_pio_usb_example(${PROJECT}) diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index f51976d39..06ca74988 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -177,12 +177,19 @@ if (NOT TARGET _rp2040_family_inclusion_marker) function(family_configure_device_example TARGET) family_configure_target(${TARGET}) - target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_device tinyusb_pio_usb_base) + target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_device) endfunction() function(family_configure_host_example TARGET) family_configure_target(${TARGET}) - target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_host tinyusb_pio_usb_base) + target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_host) + endfunction() + + function(family_configure_pio_usb_example TARGET) + family_configure_target(${TARGET}) + target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_pio_usb_base) + pico_generate_pio_header(tinyusb_common_base ${TOP}/lib/Pico-PIO-USB/src/usb_tx.pio) + pico_generate_pio_header(tinyusb_common_base ${TOP}/lib/Pico-PIO-USB/src/usb_rx.pio) endfunction() function(family_initialize_project PROJECT DIR) @@ -190,8 +197,6 @@ if (NOT TARGET _rp2040_family_inclusion_marker) _family_initialize_project(${PROJECT} ${DIR}) enable_language(C CXX ASM) pico_sdk_init() - pico_generate_pio_header(tinyusb_common_base ${TOP}/lib/Pico-PIO-USB/src/usb_tx.pio) - pico_generate_pio_header(tinyusb_common_base ${TOP}/lib/Pico-PIO-USB/src/usb_rx.pio) endfunction() # This method must be called from the project scope to suppress known warnings in TinyUSB source files From 35b77a4a81b62da0558630a7148fb3934faa4391 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 10 May 2022 22:14:00 +0700 Subject: [PATCH 330/504] cmake lib rename --- .../dual/host_hid_to_device_cdc/CMakeLists.txt | 2 +- examples/host/bare_api/CMakeLists.txt | 2 +- examples/host/cdc_msc_hid/CMakeLists.txt | 2 +- examples/host/hid_controller/CMakeLists.txt | 2 +- hw/bsp/rp2040/family.cmake | 14 +++++++------- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/dual/host_hid_to_device_cdc/CMakeLists.txt b/examples/dual/host_hid_to_device_cdc/CMakeLists.txt index bf3e042d1..24ebfdec3 100644 --- a/examples/dual/host_hid_to_device_cdc/CMakeLists.txt +++ b/examples/dual/host_hid_to_device_cdc/CMakeLists.txt @@ -27,4 +27,4 @@ target_include_directories(${PROJECT} PUBLIC # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) family_configure_host_example(${PROJECT}) -family_configure_pio_usb_example(${PROJECT}) +family_configure_pico_pio_usb_example(${PROJECT}) diff --git a/examples/host/bare_api/CMakeLists.txt b/examples/host/bare_api/CMakeLists.txt index e2e8d4fd5..607ef22eb 100644 --- a/examples/host/bare_api/CMakeLists.txt +++ b/examples/host/bare_api/CMakeLists.txt @@ -27,4 +27,4 @@ target_include_directories(${PROJECT} PUBLIC family_configure_host_example(${PROJECT}) # For rp2040, un-comment to enable pico-pio-usb -# family_configure_pio_usb_example(${PROJECT}) +# family_configure_pico_pio_usb_example(${PROJECT}) diff --git a/examples/host/cdc_msc_hid/CMakeLists.txt b/examples/host/cdc_msc_hid/CMakeLists.txt index ca0f8e48a..214e9f2e7 100644 --- a/examples/host/cdc_msc_hid/CMakeLists.txt +++ b/examples/host/cdc_msc_hid/CMakeLists.txt @@ -29,4 +29,4 @@ target_include_directories(${PROJECT} PUBLIC family_configure_host_example(${PROJECT}) # For rp2040, un-comment to enable pico-pio-usb -# family_configure_pio_usb_example(${PROJECT}) +# family_configure_pico_pio_usb_example(${PROJECT}) diff --git a/examples/host/hid_controller/CMakeLists.txt b/examples/host/hid_controller/CMakeLists.txt index 60678fc1c..6227e0790 100644 --- a/examples/host/hid_controller/CMakeLists.txt +++ b/examples/host/hid_controller/CMakeLists.txt @@ -28,4 +28,4 @@ target_include_directories(${PROJECT} PUBLIC family_configure_host_example(${PROJECT}) # For rp2040, un-comment to enable pico-pio-usb -# family_configure_pio_usb_example(${PROJECT}) +# family_configure_pico_pio_usb_example(${PROJECT}) diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index 06ca74988..f52274c15 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -61,26 +61,26 @@ if (NOT TARGET _rp2040_family_inclusion_marker) #------------------------------------ # PIO USB for both host and device #------------------------------------ - add_library(tinyusb_pio_usb_base INTERFACE) + add_library(pico_pio_usb INTERFACE) - target_sources(tinyusb_pio_usb_base INTERFACE + target_sources(pico_pio_usb INTERFACE ${TOP}/lib/Pico-PIO-USB/src/pio_usb.c ${TOP}/lib/Pico-PIO-USB/src/pio_usb_host.c ${TOP}/lib/Pico-PIO-USB/src/pio_usb_device.c ${TOP}/lib/Pico-PIO-USB/src/usb_crc.c ) - target_include_directories(tinyusb_pio_usb_base INTERFACE + target_include_directories(pico_pio_usb INTERFACE ${TOP}/lib/Pico-PIO-USB/src ) - target_link_libraries(tinyusb_pio_usb_base INTERFACE + target_link_libraries(pico_pio_usb INTERFACE hardware_dma hardware_pio pico_multicore ) - target_compile_definitions(tinyusb_pio_usb_base INTERFACE + target_compile_definitions(pico_pio_usb INTERFACE PIO_USB_USE_TINYUSB ) @@ -185,9 +185,9 @@ if (NOT TARGET _rp2040_family_inclusion_marker) target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_host) endfunction() - function(family_configure_pio_usb_example TARGET) + function(family_configure_pico_pio_usb_example TARGET) family_configure_target(${TARGET}) - target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_pio_usb_base) + target_link_libraries(${TARGET} PUBLIC pico_stdlib pico_pio_usb) pico_generate_pio_header(tinyusb_common_base ${TOP}/lib/Pico-PIO-USB/src/usb_tx.pio) pico_generate_pio_header(tinyusb_common_base ${TOP}/lib/Pico-PIO-USB/src/usb_rx.pio) endfunction() From 8473ca16fb74edcb32a050ef087d5f30f50c599b Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 10 May 2022 22:56:06 +0700 Subject: [PATCH 331/504] clean up --- .../dual/host_hid_to_device_cdc/src/main.c | 3 --- src/portable/raspberrypi/pio_usb/hcd_pio_usb.c | 18 ++++++++++-------- 2 files changed, 10 insertions(+), 11 deletions(-) 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 cc811cd71..c05d65c9e 100644 --- a/examples/dual/host_hid_to_device_cdc/src/main.c +++ b/examples/dual/host_hid_to_device_cdc/src/main.c @@ -176,9 +176,6 @@ void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) printf("[%u] HID Interface instance = %d is unmounted\r\n", dev_addr, instance); } -// keycodes from last report to check if key is holding or newly pressed -uint8_t last_keycodes[6] = {0}; - // look up new key in previous keys static inline bool find_key_in_report(hid_keyboard_report_t const *report, uint8_t keycode) { diff --git a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c index 3c7378561..1b2d29331 100644 --- a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c @@ -50,6 +50,8 @@ static pio_usb_configuration_t pio_host_config = PIO_USB_DEFAULT_CONFIG; //--------------------------------------------------------------------+ bool hcd_init(uint8_t rhport) { + (void) rhport; + // To run USB SOF interrupt in core1, call this init in core1 pio_usb_host_init(&pio_host_config); @@ -58,19 +60,19 @@ bool hcd_init(uint8_t rhport) void hcd_port_reset(uint8_t rhport) { - uint8_t pio_rhport = RHPORT_PIO(rhport); + uint8_t const pio_rhport = RHPORT_PIO(rhport); pio_usb_host_port_reset_start(pio_rhport); } void hcd_port_reset_end(uint8_t rhport) { - uint8_t pio_rhport = RHPORT_PIO(rhport); + uint8_t const pio_rhport = RHPORT_PIO(rhport); pio_usb_host_port_reset_end(pio_rhport); } bool hcd_port_connect_status(uint8_t rhport) { - uint8_t pio_rhport = RHPORT_PIO(rhport); + uint8_t const pio_rhport = RHPORT_PIO(rhport); root_port_t *root = PIO_USB_ROOT_PORT(pio_rhport); port_pin_status_t line_state = pio_usb_bus_get_line_state(root); @@ -81,14 +83,14 @@ bool hcd_port_connect_status(uint8_t rhport) tusb_speed_t hcd_port_speed_get(uint8_t rhport) { // TODO determine link speed - uint8_t pio_rhport = RHPORT_PIO(rhport); + uint8_t const pio_rhport = RHPORT_PIO(rhport); return PIO_USB_ROOT_PORT(pio_rhport)->is_fullspeed ? TUSB_SPEED_FULL : TUSB_SPEED_LOW; } // Close all opened endpoint belong to this device void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { - uint8_t pio_rhport = RHPORT_PIO(rhport); + uint8_t const pio_rhport = RHPORT_PIO(rhport); pio_usb_host_close_device(pio_rhport, dev_addr); } @@ -118,19 +120,19 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const hcd_devtree_get_info(dev_addr, &dev_tree); bool const need_pre = (dev_tree.hub_addr && dev_tree.speed == TUSB_SPEED_LOW); - uint8_t pio_rhport = RHPORT_PIO(rhport); + uint8_t const pio_rhport = RHPORT_PIO(rhport); return pio_usb_host_endpoint_open(pio_rhport, dev_addr, (uint8_t const*) desc_ep, need_pre); } bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) { - uint8_t pio_rhport = RHPORT_PIO(rhport); + uint8_t const pio_rhport = RHPORT_PIO(rhport); return pio_usb_host_endpoint_transfer(pio_rhport, dev_addr, ep_addr, buffer, buflen); } bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) { - uint8_t pio_rhport = RHPORT_PIO(rhport); + uint8_t const pio_rhport = RHPORT_PIO(rhport); return pio_usb_host_send_setup(pio_rhport, dev_addr, setup_packet); } From 8bd923f5f17fd124f9b479df031ecb82cd6cc2d9 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 11 May 2022 00:37:45 +0700 Subject: [PATCH 332/504] sync with pio usb --- lib/Pico-PIO-USB | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB index d2c6c4592..9d2b7dae4 160000 --- a/lib/Pico-PIO-USB +++ b/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit d2c6c459277816466cc087a5e27f41d2ce257f46 +Subproject commit 9d2b7dae4261e0f6a336a125972e16aab65be722 From f09df55ab986deea6d2df1168b1ad6f8eddd2ff1 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 11 May 2022 15:40:02 +0700 Subject: [PATCH 333/504] clean up example --- .../dual/host_hid_to_device_cdc/src/main.c | 28 +++++++++++-------- lib/Pico-PIO-USB | 2 +- 2 files changed, 17 insertions(+), 13 deletions(-) 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 c05d65c9e..3e5724451 100644 --- a/examples/dual/host_hid_to_device_cdc/src/main.c +++ b/examples/dual/host_hid_to_device_cdc/src/main.c @@ -23,10 +23,8 @@ * */ -// This example runs both host and device concurrently. The USB host looks for -// any HID device with reports that are 8 bytes long and then assumes they are -// keyboard reports. It translates the keypresses of the reports to ASCII and -// transmits it over CDC to the device's host. +// This example runs both host and device concurrently. The USB host receive +// reports from HID device and print it out over USB Device CDC interface. #include #include @@ -157,7 +155,11 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re uint16_t vid, pid; tuh_vid_pid_get(dev_addr, &vid, &pid); - printf("[%04x:%04x][%u] HID Interface instance = %d, Protocol = %s\r\n", vid, pid, dev_addr, instance, protocol_str[itf_protocol]); + char tempbuf[256]; + int count = sprintf(tempbuf, "[%04x:%04x][%u] HID Interface instance = %d, Protocol = %s\r\n", vid, pid, dev_addr, instance, protocol_str[itf_protocol]); + + tud_cdc_write(tempbuf, count); + tud_cdc_write_flush(); // Receive report from boot keyboard & mouse only // tuh_hid_report_received_cb() will be invoked when report is available @@ -165,7 +167,7 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re { if ( !tuh_hid_receive_report(dev_addr, instance) ) { - printf("Error: cannot request report\r\n"); + tud_cdc_write_str("Error: cannot request report\r\n"); } } } @@ -173,7 +175,10 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re // Invoked when device with hid interface is un-mounted void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) { - printf("[%u] HID Interface instance = %d is unmounted\r\n", dev_addr, instance); + char tempbuf[256]; + int count = sprintf(tempbuf, "[%u] HID Interface instance = %d is unmounted\r\n", dev_addr, instance); + tud_cdc_write(tempbuf, count); + tud_cdc_write_flush(); } // look up new key in previous keys @@ -234,16 +239,14 @@ static void process_kbd_report(hid_keyboard_report_t const *report) // send mouse report to usb device CDC static void process_mouse_report(hid_mouse_report_t const * report) { - char tempbuf[32]; - int count; - //------------- button state -------------// //uint8_t button_changed_mask = report->buttons ^ prev_report.buttons; char l = report->buttons & MOUSE_BUTTON_LEFT ? 'L' : '-'; char m = report->buttons & MOUSE_BUTTON_MIDDLE ? 'M' : '-'; char r = report->buttons & MOUSE_BUTTON_RIGHT ? 'R' : '-'; - count = sprintf(tempbuf, " %c%c%c %d %d %d\r\n", l, m, r, report->x, report->y, report->wheel); + char tempbuf[32]; + int count = sprintf(tempbuf, "%c%c%c %d %d %d\r\n", l, m, r, report->x, report->y, report->wheel); tud_cdc_write(tempbuf, count); tud_cdc_write_flush(); @@ -252,6 +255,7 @@ static void process_mouse_report(hid_mouse_report_t const * report) // Invoked when received report from device via interrupt endpoint void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len) { + (void) len; uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance); switch(itf_protocol) @@ -270,7 +274,7 @@ void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t cons // continue to request to receive report if ( !tuh_hid_receive_report(dev_addr, instance) ) { - printf("Error: cannot request report\r\n"); + tud_cdc_write_str("Error: cannot request report\r\n"); } } diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB index 9d2b7dae4..53ec09168 160000 --- a/lib/Pico-PIO-USB +++ b/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit 9d2b7dae4261e0f6a336a125972e16aab65be722 +Subproject commit 53ec09168c5a3cd30d8dcb577fa97dc328d769d4 From c5ba1ea8c17a379beb47d9689e85e2ce6e67206f Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 13 May 2022 22:54:47 +0700 Subject: [PATCH 334/504] changes proposal to audio feedback computation --- src/class/audio/audio_device.c | 251 ++++++++++++++------------------- src/class/audio/audio_device.h | 102 ++++---------- src/common/tusb_common.h | 6 - src/device/usbd.c | 6 +- src/device/usbd.h | 2 +- 5 files changed, 136 insertions(+), 231 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index b0a49fb04..c3a252a2c 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -261,6 +261,13 @@ osal_mutex_def_t rx_supp_ff_mutex_rd_3[CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO]; #endif #endif +enum { + FEEDBACK_COMPUTE_DISABLED, + FEEDBACK_COMPUTE_FLOAT, + FEEDBACK_COMPUTE_FIXED, + FEEDBACK_COMPUTE_POWER_OF_2, +}; + typedef struct { uint8_t rhport; @@ -305,38 +312,22 @@ typedef struct #endif #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER - uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). - uint8_t fb_n_frames; // Number of (micro)frames used to estimate feedback value -#endif -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER - volatile uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). - uint32_t fb_val_min; // Maximum allowed feedback value according to UAC2 FMT-2.0 section 2.3.1.1. - uint32_t fb_val_max; // Maximum allowed feedback value according to UAC2 FMT-2.0 section 2.3.1.1. - uint8_t fb_n_frames; // Number of (micro)frames used to estimate feedback value - volatile uint8_t fb_n_frames_current; // Current (micro)frame number - volatile uint32_t fb_n_cycles_old; // Old cycle count - uint32_t * fb_param_p_cycle_count; // Pointer to cycle counter + uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). + uint8_t fb_n_frames; // Number of (micro)frames used to estimate feedback value + uint8_t fb_n_frames_shift; + uint8_t fb_compute_method; -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT + uint32_t fb_val_min; // Maximum allowed feedback value according to UAC2 FMT-2.0 section 2.3.1.1. + uint32_t fb_val_max; // Maximum allowed feedback value according to UAC2 FMT-2.0 section 2.3.1.1. + + // should be union uint8_t fb_power_of_two_val; -#endif -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT float fb_float_val; -#endif -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT - uint64_t fb_param_factor_N; // Numerator of feedback parameter coefficient - uint64_t fb_param_factor_D; // Denominator of feedback parameter coefficient -#endif -#endif // CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER - -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER - volatile uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). - uint8_t fb_n_frames; // Number of (micro)frames used to estimate feedback value -#endif + uint32_t fb_param_factor_N; + uint32_t fb_param_factor_D; #endif // CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT @@ -453,8 +444,8 @@ static inline uint8_t tu_desc_subtype(void const* desc) } #endif -#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER) -static bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP +bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); #endif bool tud_audio_n_mounted(uint8_t func_id) @@ -1695,16 +1686,11 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && desc_ep->bmAttributes.usage == 1) // Check if usage is explicit data feedback { audio->ep_fb = ep_addr; - audio->fb_n_frames = desc_ep->bInterval; + audio->fb_n_frames = 1 << (desc_ep->bInterval -1); + audio->fb_n_frames_shift = desc_ep->bInterval -1; -#if ((CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER) || (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER)) - usbd_sof_enable(rhport, true); // Enable SOF interrupt -#endif - -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER - audio->fb_n_frames_current = 0; - audio->fb_n_cycles_old = 0; -#endif + // Enable SOF interrupt if callback is implemented + if (tud_audio_sof_isr) usbd_sof_enable(rhport, true); // // Invoke callback after ep_out is set // if (audio->ep_out != 0) @@ -1725,6 +1711,24 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * // Invoke one callback for a final set interface if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); + // Prepare feedback computation if callback is available + if (tud_audio_feedback_params_cb) + { + uint32_t sample_freq = 0; + uint32_t mclk_freq = 0; + uint8_t fixed_point = 0; + tud_audio_feedback_params_cb(func_id, alt, &sample_freq, &mclk_freq, &fixed_point); + + if ( sample_freq == 0 || mclk_freq == 0 ) + { + audio->fb_compute_method = FEEDBACK_COMPUTE_DISABLED; + }else + { + audio->fb_compute_method = fixed_point ? FEEDBACK_COMPUTE_FIXED : FEEDBACK_COMPUTE_FLOAT; + set_fb_params(audio, sample_freq, mclk_freq); + } + } + // We are done - abort loop break; } @@ -1734,22 +1738,17 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * } // Disable SOF interrupt if no driver has any enabled feedback EP -#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && ((CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER) || (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER)) - bool disable = true; - for(uint8_t i=0; i < CFG_TUD_AUDIO; i++) { if (_audiod_fct[i].ep_fb != 0) { disable = false; + break; } } - if (disable) usbd_sof_enable(rhport, false); -#endif - tud_control_status(rhport, p_request); return true; @@ -2022,7 +2021,7 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 // Transmission of feedback EP finished if (_audiod_fct[func_id].ep_fb == ep_addr) { - if (tud_audio_fb_done_cb) TU_VERIFY(tud_audio_fb_done_cb(rhport)); + if (tud_audio_fb_done_cb) tud_audio_fb_done_cb(func_id); // Schedule a transmit with the new value if EP is not busy if (!usbd_edpt_busy(rhport, _audiod_fct[func_id].ep_fb)) @@ -2038,81 +2037,93 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 return false; } -#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && ((CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER) || (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER)) +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP uint8_t tud_audio_n_get_fb_n_frames(uint8_t func_id) { return _audiod_fct[func_id].fb_n_frames; } #endif -#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER) +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -// This function must be called from the user within the tud_audio_set_itf_cb(rhport, p_request) callback function, where p_request needs to be checked as -// uint8_t const itf = tu_u16_low(p_request->wIndex); -// uint8_t const alt = tu_u16_low(p_request->wValue); -// such that tud_audio_set_fb_params() gets called with the parameters corresponding to the defined interface and alternate setting -// Also, start the main clock cycle counter (or reset its value) within tud_audio_set_itf_cb() -TU_ATTR_WEAK bool tud_audio_set_fb_params(uint8_t func_id, uint32_t f_m, uint32_t f_s, uint32_t * p_cycle_count) +static bool set_fb_params(audiod_function_t* audio, uint32_t f_s, uint32_t f_m) { - audiod_function_t* audio = &_audiod_fct[func_id]; - audio->fb_param_p_cycle_count = p_cycle_count; - // Check if frame interval is within sane limits // The interval value audio->fb_n_frames was taken from the descriptors within audiod_set_interface() - // n_frames_min is ceil(2^10 * f_s / f_m) for full speed and ceil(2^13 * f_s / f_m) for high speed - this lower limit ensures the measures feedback value has sufficient precision - if ((TUSB_SPEED_FULL == tud_speed_get() && ((2^10 * f_s / f_m) + 1) > audio->fb_n_frames) || (TUSB_SPEED_HIGH == tud_speed_get() && ((2^13 * f_s / f_m) + 1) > audio->fb_n_frames)) + // n_frames_min is ceil(2^10 * f_s / f_m) for full speed and ceil(2^13 * f_s / f_m) for high speed + // this lower limit ensures the measures feedback value has sufficient precision + uint32_t const k = (TUSB_SPEED_FULL == tud_speed_get()) ? 10 : 13; + if ( (((1UL << k) * f_s / f_m) + 1) > audio->fb_n_frames ) { - TU_LOG2(" UAC2 feedback interval too small\r\n"); TU_BREAKPOINT(); return false; + TU_LOG1(" UAC2 feedback interval too small\r\n"); TU_BREAKPOINT(); return false; } - -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT // Check if parameters really allow for a power of two division - if ((f_m % f_s) != 0 || !tu_is_power_of_two(audio->fb_n_frames * f_m / f_s)) + if ((f_m % f_s) == 0 && tu_is_power_of_two(f_m / f_s)) { - TU_LOG2(" FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT not possible!\r\n"); TU_BREAKPOINT(); return false; + audio->fb_compute_method = FEEDBACK_COMPUTE_POWER_OF_2; + audio->fb_power_of_two_val = 16 - audio->fb_n_frames_shift - tu_log2(f_m / f_s); + }else if ( audio->fb_compute_method == FEEDBACK_COMPUTE_FLOAT) + { + audio->fb_float_val = (float)f_s / f_m * (1UL << (16 - audio->fb_n_frames_shift)); + }else + { + audio->fb_param_factor_N = f_s; + audio->fb_param_factor_D = f_m; } - audio->fb_power_of_two_val = 16 - tu_log2(audio->fb_n_frames * f_m / f_s); -#endif - -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT - audio->fb_float_val = (float)f_s / audio->fb_n_frames / f_m * (1 << 16); -#endif - -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT - - // f_s max is 2^19-1 = 524287 Hz - // f_m max is 2^29/(1 ms * n_frames) for full speed and 2^29/(125 us * n_frames) for high speed, this means for f_m fitting in an uint32, n_frames must be < 125 for full speed and < 1000 for high speed (1000 does not fit into uint8 so the maximum possible value cannot even be reached by UAC2 - we don't need to check for it) - - if ((f_s > (2^19)-1) || (TUSB_SPEED_FULL == tud_speed_get() && (audio->fb_n_frames > 125))) - { - // If this check fails, not every thing is lost - you need to re-evaluate the scaling factors of the parameters such that the numbers fit into uint64 again. feedback = n_cycles * S_c / (n_frames * S_n) * f_s * S_s / (f_m * S_m). In the end S_c*S_s / (S_n * S_m) = 2^16 for a 16.16 fixed point precision. If you find something, define your own function of tud_audio_set_feedback_params_fm_fs() and audiod_sof() and use your values - TU_LOG2(" FEEDBACK_DETERMINATION_MODE_FIXED_POINT not possible!\r\n"); TU_BREAKPOINT(); return false; - } - - audio->fb_param_factor_N = (uint64_t)f_s << 13; - audio->fb_param_factor_D = (uint64_t)f_m * audio->fb_n_frames; -#endif - - audio->fb_val_min = ((TUSB_SPEED_FULL == tud_speed_get() ? (f_s/1000) : (f_s/8000)) - 1) << 16; // Minimal value in 16.16 format for full speed (1ms per frame) or high speed (125 us per frame) - audio->fb_val_max = ((TUSB_SPEED_FULL == tud_speed_get() ? (f_s/1000) : (f_s/8000)) + 1) << 16; // Maximum value in 16.16 format + // Minimal/Maximum value in 16.16 format for full speed (1ms per frame) or high speed (125 us per frame) + uint32_t const frame_div = (TUSB_SPEED_FULL == tud_speed_get()) ? 1000 : 8000; + audio->fb_val_min = (f_s/frame_div - 1) << 16; + audio->fb_val_max = (f_s/frame_div + 1) << 16; return true; - } #endif -TU_ATTR_WEAK void audiod_sof (uint8_t rhport, uint32_t frame_count) +uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles) +{ + audiod_function_t* audio = &_audiod_fct[func_id]; + uint32_t feedback; + + switch (audio->fb_compute_method) + { + case FEEDBACK_COMPUTE_POWER_OF_2: + feedback = cycles << audio->fb_power_of_two_val; + break; + + case FEEDBACK_COMPUTE_FLOAT: + feedback = (uint32_t) ((float) cylces * audio->fb_float_val); + break; + + case FEEDBACK_COMPUTE_FIXED: + { + uint64_t fb64 = (((uint64_t) cycles) * audio->fb_param_factor_N) << (16 - audio->fb_n_frames_shift); + feedback = (uint32_t) (fb64 / audio->fb_param_factor_D); + } + break; + + default: return 0; + } + + // For Windows: https://docs.microsoft.com/en-us/windows-hardware/drivers/audio/usb-2-0-audio-drivers + // The size of isochronous packets created by the device must be within the limits specified in FMT-2.0 section 2.3.1.1. + // This means that the deviation of actual packet size from nominal size must not exceed +/- one audio slot + // (audio slot = channel count samples). + if ( feedback > audio->fb_val_max ) feedback = audio->fb_val_max; + if ( feedback < audio->fb_val_min ) feedback = audio->fb_val_min; + + tud_audio_n_fb_set(func_id, feedback); + + return feedback; +} + +void audiod_sof_isr (uint8_t rhport, uint32_t frame_count) { (void) rhport; - (void) frame_count; // frame_count is not used since some devices may not provide the frame count value #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP - -#if (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER) - // Determine feedback value - The feedback method is described in 5.12.4.2 of the USB 2.0 spec // Boiled down, the feedback value Ff = n_samples / (micro)frame. // Since an accuracy of less than 1 Sample / second is desired, at least n_frames = ceil(2^K * f_s / f_m) frames need to be measured, where K = 10 for full speed and K = 13 for high speed, f_s is the sampling frequency e.g. 48 kHz and f_m is the cpu clock frequency e.g. 100 MHz (or any other master clock whose clock count is available and locked to f_s) @@ -2126,59 +2137,13 @@ TU_ATTR_WEAK void audiod_sof (uint8_t rhport, uint32_t frame_count) if (audio->ep_fb != 0) { - audio->fb_n_frames_current++; - if (audio->fb_n_frames_current == audio->fb_n_frames) + uint32_t const interval = (1UL << audio->fb_n_frames); + if ( 0 == (frame_count & (interval-1)) ) { - uint32_t n_cylces = *audio->fb_param_p_cycle_count; - uint32_t feedback; - -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT - feedback = (n_cylces - audio->fb_n_cycles_old) << audio->fb_power_of_two_val; -#endif - -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT - feedback = (uint32_t)((float)(n_cylces - audio->fb_n_cycles_old) * audio->fb_float_val); -#endif - -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT - feedback = ((n_cylces - audio->fb_n_cycles_old) << 3) * audio->fb_param_factor_N / audio->fb_param_factor_D; // feeback_param_factor_N has scaling factor of 13 bits, n_cycles 3 and feeback_param_factor_D 1, hence 16.16 precision -#endif - - // For Windows: https://docs.microsoft.com/en-us/windows-hardware/drivers/audio/usb-2-0-audio-drivers - // The size of isochronous packets created by the device must be within the limits specified in FMT-2.0 section 2.3.1.1. This means that the deviation of actual packet size from nominal size must not exceed +/- one audio slot (audio slot = channel count samples). - - if (feedback > audio->fb_val_max){ - feedback = audio->fb_val_max; - } - if ( feedback < audio->fb_val_min) { - feedback = audio->fb_val_min; - } - - // Buffer count checks ? - - tud_audio_n_fb_set(i, feedback); - audio->fb_n_frames_current = 0; - audio->fb_n_cycles_old = n_cylces; + if(tud_audio_sof_isr) tud_audio_sof_isr(i, frame_count); } } } - -#endif // (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER) - -#if (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER) - // Iterate over audio functions and call callback function - for(uint8_t i=0; i < CFG_TUD_AUDIO; i++) - { - audiod_function_t* audio = &_audiod_fct[i]; - - if (audio->ep_fb != 0) - { - tud_audio_sof_isr_cb(i, frame_count); - } - } - -#endif // (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER) - #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP } @@ -2459,11 +2424,7 @@ static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER -static bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) -#else bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) -#endif { TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index e8721cf27..9ed7d1da4 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -191,41 +191,6 @@ #define CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION 0 // 0 or 1 #endif -// Possible options for determination of feedback value -#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER 1 // Feedback value must be determined by the user itself and set by use of tud_audio_n_fb_set(). The feedback value may be determined e.g. from some fill status of some FIFO buffer. Advantage: No ISR interrupt is enabled, hence the CPU need not to handle an ISR every 1ms or 125us and thus less CPU load, disadvantage: typically a larger FIFO is needed to compensate for jitter (e.g. 8 frames), i.e. a larger delay is introduced. -#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER 2 // Feedback value is calculated within the audio driver by use of SOF interrupt. The driver needs information about the master clock f_m from which the audio sample frequency f_s is derived, f_s itself, and the cycle count of f_m at time of the SOF interrupt (e.g. by use of a hardware counter) - see tud_audio_set_fb_params(). Advantage: Reduced jitter in the feedback value computation, hence, the receive FIFO can be smaller (e.g. 2 frames) and thus a smaller delay is possible, disadvantage: higher CPU load due to SOF ISR handling every frame i.e. 1ms or 125us. This option is a great starting point to try the SOF ISR option but depending on your hardware setup (performance of the CPU) it might not work. If so, figure out why and use the next option. (The most critical point is the reading of the cycle counter value of f_m. It is read from within the SOF ISR - see: audiod_sof() -, hence, the ISR must has a high priority such that no software dependent "random" delay i.e. jitter is introduced). -#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER 3 // Feedback value is determined by the user by use of SOF interrupt. The user may use tud_audio_sof_isr_cb() which is called every SOF (of course only invoked when an alternate interface other than zero was set). The number of frames used to determine the feedback value for the currently active alternate setting can be get by tud_audio_get_fb_n_frames(). The feedback value must be set by use of tud_audio_n_fb_set(). - -// Determine feedback value within SOF ISR within audio driver - if disabled the user has to call tud_audio_n_fb_set() with a suitable feedback value on its own. If done within audio driver SOF ISR, tud_audio_n_fb_set() is disabled for user -#ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION -#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER -#endif - -#ifdef CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION -#if (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION != CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION != CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION != CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER) -#error Unknown CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION. Possible choices are: CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER, CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER, or CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER! -#endif -#endif - -// Feeback calculation mode -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER - -#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT 1 -#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT 2 -#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT 3 - -#ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE -#error You must tell the driver the feedback determination mode! Possible choices are: CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT, CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT, or CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT! -#endif - -#ifdef CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE -#if (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE != CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE != CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE != CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT) -#error Unknown CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE. Possible choices are: CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT, CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT, or CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT! -#endif -#endif - -#endif - // Audio interrupt control EP size - disabled if 0 #ifndef CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN #define CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN 0 // Audio interrupt control - if required - 6 Bytes according to UAC 2 specification (p. 74) @@ -493,9 +458,14 @@ TU_ATTR_WEAK bool tud_audio_rx_done_post_read_cb(uint8_t rhport, uint16_t n_byte #endif #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -TU_ATTR_WEAK bool tud_audio_fb_done_cb(uint8_t rhport); +TU_ATTR_WEAK void tud_audio_fb_done_cb(uint8_t func_id); -#if (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER) + +// determined by the user itself and set by use of tud_audio_n_fb_set(). The feedback value may be determined e.g. from some fill status of some FIFO buffer. Advantage: No ISR interrupt is enabled, hence the CPU need not to handle an ISR every 1ms or 125us and thus less CPU load, disadvantage: typically a larger FIFO is needed to compensate for jitter (e.g. 8 frames), i.e. a larger delay is introduced. + +// Feedback value is calculated within the audio driver by use of SOF interrupt. The driver needs information about the master clock f_m from which the audio sample frequency f_s is derived, f_s itself, and the cycle count of f_m at time of the SOF interrupt (e.g. by use of a hardware counter) - see tud_audio_set_fb_params(). Advantage: Reduced jitter in the feedback value computation, hence, the receive FIFO can be smaller (e.g. 2 frames) and thus a smaller delay is possible, disadvantage: higher CPU load due to SOF ISR handling every frame i.e. 1ms or 125us. This option is a great starting point to try the SOF ISR option but depending on your hardware setup (performance of the CPU) it might not work. If so, figure out why and use the next option. (The most critical point is the reading of the cycle counter value of f_m. It is read from within the SOF ISR - see: audiod_sof() -, hence, the ISR must has a high priority such that no software dependent "random" delay i.e. jitter is introduced). + +// Feedback value is determined by the user by use of SOF interrupt. The user may use tud_audio_sof_isr() which is called every SOF (of course only invoked when an alternate interface other than zero was set). The number of frames used to determine the feedback value for the currently active alternate setting can be get by tud_audio_get_fb_n_frames(). The feedback value must be set by use of tud_audio_n_fb_set(). // This function is used to provide data rate feedback from an asynchronous sink. Feedback value will be sent at FB endpoint interval till it's changed. // @@ -508,41 +478,11 @@ TU_ATTR_WEAK bool tud_audio_fb_done_cb(uint8_t rhport); // Feedback value can be determined from within the SOF ISR of the audio driver. This should reduce jitter. If the feature is used, the user can not set the feedback value. -bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); -static inline bool tud_audio_fb_set(uint32_t feedback); - -uint8_t tud_audio_n_get_fb_n_frames(uint8_t func_id); -static inline uint8_t tud_audio_get_fb_n_frames(); - -#endif // (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER) - -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER - -// f_m : Main clock frequency in Hz i.e. master clock to which sample clock is locked -// f_s : Current sample rate in Hz -// p_cycle_count : Pointer to main clock cycle counter register where the current count can be read from (e.g. a timer register) - -// This function must be called from the user within the tud_audio_set_itf_cb(rhport, p_request) callback function, where p_request needs to be checked as -// uint8_t const itf = tu_u16_low(p_request->wIndex); -// uint8_t const alt = tu_u16_low(p_request->wValue); -// such that tud_audio_set_fb_params() gets called with the parameters corresponding to the defined interface and alternate setting -// Also, start the main clock cycle counter (or reset its value) within tud_audio_set_itf_cb() -bool tud_audio_set_fb_params(uint8_t func_id, uint32_t f_m, uint32_t f_s, uint32_t * p_cycle_count); - -#endif // CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_AUDIO_DRIVER - -#if (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER) - -// This function is used to provide data rate feedback from an asynchronous sink. Feedback value will be sent at FB endpoint interval till it's changed. -// -// The feedback format is specified to be 16.16 for HS and 10.14 for FS devices (see Universal Serial Bus Specification Revision 2.0 5.12.4.2). By default, -// the choice of format is left to the caller and feedback argument is sent as-is. If CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION is set, then tinyusb -// expects 16.16 format and handles the conversion to 10.14 on FS. -// -// Note that due to a bug in its USB Audio 2.0 driver, Windows currently requires 16.16 format for _all_ USB 2.0 devices. On Linux and macOS it seems the -// driver can work with either format. So a good compromise is to keep format correction disabled and stick to 16.16 format. - -// Feedback value can be determined from within the SOF ISR of the audio driver. This should reduce jitter. If the feature is used, the user can not set the feedback value. +// Determine feedback value - The feedback method is described in 5.12.4.2 of the USB 2.0 spec +// Boiled down, the feedback value Ff = n_samples / (micro)frame. +// Since an accuracy of less than 1 Sample / second is desired, at least n_frames = ceil(2^K * f_s / f_m) frames need to be measured, where K = 10 for full speed and K = 13 for high speed, f_s is the sampling frequency e.g. 48 kHz and f_m is the cpu clock frequency e.g. 100 MHz (or any other master clock whose clock count is available and locked to f_s) +// The update interval in the (4.10.2.1) Feedback Endpoint Descriptor must be less or equal to 2^(K - P), where P = min( ceil(log2(f_m / f_s)), K) +// feedback = n_cycles / n_frames * f_s / f_m in 16.16 format, where n_cycles are the number of main clock cycles within fb_n_frames bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); static inline bool tud_audio_fb_set(uint32_t feedback); @@ -550,9 +490,18 @@ static inline bool tud_audio_fb_set(uint32_t feedback); uint8_t tud_audio_n_get_fb_n_frames(uint8_t func_id); static inline uint8_t tud_audio_get_fb_n_frames(); -TU_ATTR_WEAK void tud_audio_sof_isr_cb(uint8_t func_id, uint32_t frame); +// Update feedback value with passed cycles since last time this update function is called. +// Typically called within tud_audio_sof_isr(). Required tud_audio_feedback_params_cb() is implemented +// This function will also call tud_audio_feedback_set() +// return feedback value in 16.16 for reference (0 for error) +uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles); -#endif // (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER) +// mclk_freq : Main clock frequency in Hz i.e. master clock to which sample clock is locked +// sample_freq : sample frequency in Hz +// fixed_point : 0 float (default), 1 fixed point (for mcu without FPU) +TU_ATTR_WEAK void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, uint32_t* sample_freq, uint32_t* mclk_freq, uint8_t* fixed_point); + +TU_ATTR_WEAK void tud_audio_sof_isr(uint8_t func_id, uint32_t frame); #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP @@ -695,7 +644,8 @@ static inline uint16_t tud_audio_int_ctr_write(uint8_t const* buffer, uint16_t l } #endif -#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP && ((CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_NO_SOF_BY_USER) || (CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION == CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_OPTION_SOF_BY_USER)) +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP + static inline bool tud_audio_fb_set(uint32_t feedback) { return tud_audio_n_fb_set(0, feedback); @@ -716,7 +666,7 @@ void audiod_reset (uint8_t rhport); uint16_t audiod_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool audiod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); bool audiod_xfer_cb (uint8_t rhport, uint8_t edpt_addr, xfer_result_t result, uint32_t xferred_bytes); -void audiod_sof (uint8_t rhport, uint32_t frame_count); +void audiod_sof_isr (uint8_t rhport, uint32_t frame_count); #ifdef __cplusplus } diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index bcdf8933a..b1ee40a1a 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -134,12 +134,6 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_offset4k(uint32_t value) { retur //------------- Mathematics -------------// TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_div_ceil(uint32_t v, uint32_t d) { return (v + d -1)/d; } -/// inclusive range checking TODO remove -TU_ATTR_ALWAYS_INLINE static inline bool tu_within(uint32_t lower, uint32_t value, uint32_t upper) -{ - return (lower <= value) && (value <= upper); -} - // log2 of a value is its MSB's position // TODO use clz TODO remove static inline uint8_t tu_log2(uint32_t value) diff --git a/src/device/usbd.c b/src/device/usbd.c index 8ab67c8de..b32cee813 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -69,7 +69,7 @@ typedef struct volatile uint8_t cfg_num; // current active configuration (0x00 is not configured) uint8_t speed; - uint8_t itf2drv[16]; // map interface number to driver (0xff is invalid) + uint8_t itf2drv[CFG_TUD_INTERFACE_MAX]; // map interface number to driver (0xff is invalid) uint8_t ep2drv[CFG_TUD_ENDPPOINT_MAX][2]; // map endpoint to driver ( 0xff is invalid ), can use only 4-bit each tu_edpt_state_t ep_status[CFG_TUD_ENDPPOINT_MAX][2]; @@ -134,7 +134,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = audiod_open, .control_xfer_cb = audiod_control_xfer_cb, .xfer_cb = audiod_xfer_cb, - .sof_isr = audiod_sof + .sof_isr = audiod_sof_isr }, #endif @@ -170,7 +170,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = vendord_open, .control_xfer_cb = tud_vendor_control_xfer_cb, .xfer_cb = vendord_xfer_cb, - .sof_isr = NULL + .sof_isr = NULL }, #endif diff --git a/src/device/usbd.h b/src/device/usbd.h index d485d8711..30a27c5ee 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -33,7 +33,7 @@ extern "C" { #endif -typedef void (*tud_sof_isr_t) (uint32_t frame_count); +// typedef void (*tud_sof_isr_t) (uint32_t frame_count); //--------------------------------------------------------------------+ // Application API From 20b810d25b60f3ab1b2ec58186bbb739b6b5c9b7 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 13 May 2022 23:01:06 +0700 Subject: [PATCH 335/504] fix ci build --- src/class/audio/audio_device.c | 7 ++++++- src/class/audio/audio_device.h | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index c3a252a2c..a81ddc53e 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -1708,6 +1708,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * TU_VERIFY(foundEPs == nEps); +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // Invoke one callback for a final set interface if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); @@ -1728,6 +1729,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * set_fb_params(audio, sample_freq, mclk_freq); } } +#endif // We are done - abort loop break; @@ -1737,6 +1739,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * p_desc = tu_desc_next(p_desc); } +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // Disable SOF interrupt if no driver has any enabled feedback EP bool disable = true; for(uint8_t i=0; i < CFG_TUD_AUDIO; i++) @@ -1748,6 +1751,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * } } if (disable) usbd_sof_enable(rhport, false); +#endif tud_control_status(rhport, p_request); @@ -2080,7 +2084,6 @@ static bool set_fb_params(audiod_function_t* audio, uint32_t f_s, uint32_t f_m) return true; } -#endif uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles) { @@ -2118,10 +2121,12 @@ uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles) return feedback; } +#endif void audiod_sof_isr (uint8_t rhport, uint32_t frame_count) { (void) rhport; + (void) frame_count; #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // Determine feedback value - The feedback method is described in 5.12.4.2 of the USB 2.0 spec diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index 9ed7d1da4..22394aaca 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -490,6 +490,8 @@ static inline bool tud_audio_fb_set(uint32_t feedback); uint8_t tud_audio_n_get_fb_n_frames(uint8_t func_id); static inline uint8_t tud_audio_get_fb_n_frames(); +#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP + // Update feedback value with passed cycles since last time this update function is called. // Typically called within tud_audio_sof_isr(). Required tud_audio_feedback_params_cb() is implemented // This function will also call tud_audio_feedback_set() @@ -503,7 +505,6 @@ TU_ATTR_WEAK void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, TU_ATTR_WEAK void tud_audio_sof_isr(uint8_t func_id, uint32_t frame); -#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN TU_ATTR_WEAK bool tud_audio_int_ctr_done_cb(uint8_t rhport, uint16_t n_bytes_copied); From be2a51316cd708a99899732acf43920537b97526 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 16 May 2022 13:29:12 +0700 Subject: [PATCH 336/504] remove pico-usb fork --- .gitmodules | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index e1489d303..21bbf08c0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -146,6 +146,3 @@ [submodule "hw/mcu/allwinner"] path = hw/mcu/allwinner url = https://github.com/hathach/allwinner_driver.git -[submodule "lib/Pico-PIO-USB"] - path = lib/Pico-PIO-USB - url = https://github.com/hathach/Pico-PIO-USB.git From 4586d8f119f779d1ef5f937e5c79e0ea2c84579c Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 16 May 2022 13:44:06 +0700 Subject: [PATCH 337/504] add upstream Pico-PIO-USB --- .github/workflows/build_arm.yml | 2 +- .gitmodules | 3 +++ hw/bsp/rp2040/family.cmake | 18 +++++++++++------- hw/mcu/raspberry_pi/Pico-PIO-USB | 1 + 4 files changed, 16 insertions(+), 8 deletions(-) create mode 160000 hw/mcu/raspberry_pi/Pico-PIO-USB diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml index 085274eb5..bec879a93 100644 --- a/.github/workflows/build_arm.yml +++ b/.github/workflows/build_arm.yml @@ -82,7 +82,7 @@ jobs: run: | git clone --depth 1 -b develop https://github.com/raspberrypi/pico-sdk ~/pico-sdk echo >> $GITHUB_ENV PICO_SDK_PATH=~/pico-sdk - git submodule update --init lib/Pico-PIO-USB + git submodule update --init hw/mcu/raspberry_pi/Pico-PIO-USB - name: Set Toolchain URL run: echo >> $GITHUB_ENV TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v10.2.1-1.1/xpack-arm-none-eabi-gcc-10.2.1-1.1-linux-x64.tar.gz diff --git a/.gitmodules b/.gitmodules index 21bbf08c0..044ac24ec 100644 --- a/.gitmodules +++ b/.gitmodules @@ -146,3 +146,6 @@ [submodule "hw/mcu/allwinner"] path = hw/mcu/allwinner url = https://github.com/hathach/allwinner_driver.git +[submodule "hw/mcu/raspberry_pi/Pico-PIO-USB"] + path = hw/mcu/raspberry_pi/Pico-PIO-USB + url = https://github.com/sekigon-gonnoc/Pico-PIO-USB.git diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index f52274c15..17ae3de9b 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -63,15 +63,19 @@ if (NOT TARGET _rp2040_family_inclusion_marker) #------------------------------------ add_library(pico_pio_usb INTERFACE) + if (NOT DEFINED PICO_PIO_USB_PATH) + set(PICO_PIO_USB_PATH "${TOP}/hw/mcu/raspberry_pi/Pico-PIO-USB") + endif() + target_sources(pico_pio_usb INTERFACE - ${TOP}/lib/Pico-PIO-USB/src/pio_usb.c - ${TOP}/lib/Pico-PIO-USB/src/pio_usb_host.c - ${TOP}/lib/Pico-PIO-USB/src/pio_usb_device.c - ${TOP}/lib/Pico-PIO-USB/src/usb_crc.c + ${PICO_PIO_USB_PATH}/src/pio_usb.c + ${PICO_PIO_USB_PATH}/src/pio_usb_host.c + ${PICO_PIO_USB_PATH}/src/pio_usb_device.c + ${PICO_PIO_USB_PATH}/src/usb_crc.c ) target_include_directories(pico_pio_usb INTERFACE - ${TOP}/lib/Pico-PIO-USB/src + ${PICO_PIO_USB_PATH}/src ) target_link_libraries(pico_pio_usb INTERFACE @@ -188,8 +192,8 @@ if (NOT TARGET _rp2040_family_inclusion_marker) function(family_configure_pico_pio_usb_example TARGET) family_configure_target(${TARGET}) target_link_libraries(${TARGET} PUBLIC pico_stdlib pico_pio_usb) - pico_generate_pio_header(tinyusb_common_base ${TOP}/lib/Pico-PIO-USB/src/usb_tx.pio) - pico_generate_pio_header(tinyusb_common_base ${TOP}/lib/Pico-PIO-USB/src/usb_rx.pio) + pico_generate_pio_header(tinyusb_common_base ${PICO_PIO_USB_PATH}/src/usb_tx.pio) + pico_generate_pio_header(tinyusb_common_base ${PICO_PIO_USB_PATH}/src/usb_rx.pio) endfunction() function(family_initialize_project PROJECT DIR) diff --git a/hw/mcu/raspberry_pi/Pico-PIO-USB b/hw/mcu/raspberry_pi/Pico-PIO-USB new file mode 160000 index 000000000..2a9fefd6c --- /dev/null +++ b/hw/mcu/raspberry_pi/Pico-PIO-USB @@ -0,0 +1 @@ +Subproject commit 2a9fefd6ccf42e5d8570ae83fdc54c9c875ebdd1 From e0e9426c2a912c2c405da602b1bf8d75d16f92e7 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 16 May 2022 16:00:15 +0700 Subject: [PATCH 338/504] print addres of mouse input --- examples/dual/host_hid_to_device_cdc/src/main.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) 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 3e5724451..62ecb2c3f 100644 --- a/examples/dual/host_hid_to_device_cdc/src/main.c +++ b/examples/dual/host_hid_to_device_cdc/src/main.c @@ -156,7 +156,7 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re tuh_vid_pid_get(dev_addr, &vid, &pid); char tempbuf[256]; - int count = sprintf(tempbuf, "[%04x:%04x][%u] HID Interface instance = %d, Protocol = %s\r\n", vid, pid, dev_addr, instance, protocol_str[itf_protocol]); + int count = sprintf(tempbuf, "[%04x:%04x][%u] HID Interface%u, Protocol = %s\r\n", vid, pid, dev_addr, instance, protocol_str[itf_protocol]); tud_cdc_write(tempbuf, count); tud_cdc_write_flush(); @@ -176,7 +176,7 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) { char tempbuf[256]; - int count = sprintf(tempbuf, "[%u] HID Interface instance = %d is unmounted\r\n", dev_addr, instance); + int count = sprintf(tempbuf, "[%u] HID Interface%u is unmounted\r\n", dev_addr, instance); tud_cdc_write(tempbuf, count); tud_cdc_write_flush(); } @@ -194,8 +194,9 @@ static inline bool find_key_in_report(hid_keyboard_report_t const *report, uint8 // convert hid keycode to ascii and print via usb device CDC (ignore non-printable) -static void process_kbd_report(hid_keyboard_report_t const *report) +static void process_kbd_report(uint8_t dev_addr, hid_keyboard_report_t const *report) { + (void) dev_addr; static hid_keyboard_report_t prev_report = { 0, 0, {0} }; // previous report to check key released bool flush = false; @@ -237,7 +238,7 @@ static void process_kbd_report(hid_keyboard_report_t const *report) } // send mouse report to usb device CDC -static void process_mouse_report(hid_mouse_report_t const * report) +static void process_mouse_report(uint8_t dev_addr, hid_mouse_report_t const * report) { //------------- button state -------------// //uint8_t button_changed_mask = report->buttons ^ prev_report.buttons; @@ -246,7 +247,7 @@ static void process_mouse_report(hid_mouse_report_t const * report) char r = report->buttons & MOUSE_BUTTON_RIGHT ? 'R' : '-'; char tempbuf[32]; - int count = sprintf(tempbuf, "%c%c%c %d %d %d\r\n", l, m, r, report->x, report->y, report->wheel); + int count = sprintf(tempbuf, "[%u] %c%c%c %d %d %d\r\n", dev_addr, l, m, r, report->x, report->y, report->wheel); tud_cdc_write(tempbuf, count); tud_cdc_write_flush(); @@ -261,11 +262,11 @@ void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t cons switch(itf_protocol) { case HID_ITF_PROTOCOL_KEYBOARD: - process_kbd_report( (hid_keyboard_report_t const*) report ); + process_kbd_report(dev_addr, (hid_keyboard_report_t const*) report ); break; case HID_ITF_PROTOCOL_MOUSE: - process_mouse_report( (hid_mouse_report_t const*) report ); + process_mouse_report(dev_addr, (hid_mouse_report_t const*) report ); break; default: break; From 5766c9ac4ed3525b3223ad0751f871b08a1bb5fb Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 19 May 2022 13:44:10 +0700 Subject: [PATCH 339/504] rename tud_audio_sof_isr() to tud_audio_feedback_interval_isr() - also add interval_log2 to isr callback - also rename other variables --- src/class/audio/audio_device.c | 37 +++++++++++++++++----------------- src/class/audio/audio_device.h | 4 +++- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index a81ddc53e..db8bbb819 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -326,8 +326,8 @@ typedef struct float fb_float_val; - uint32_t fb_param_factor_N; - uint32_t fb_param_factor_D; + uint32_t fb_sample_freq; + uint32_t fb_mclk_freq; #endif // CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT @@ -1686,11 +1686,11 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && desc_ep->bmAttributes.usage == 1) // Check if usage is explicit data feedback { audio->ep_fb = ep_addr; - audio->fb_n_frames = 1 << (desc_ep->bInterval -1); + audio->fb_n_frames = 1U << (desc_ep->bInterval -1); // TODO correctly set USB frame interval for SOF (not micro-frame) audio->fb_n_frames_shift = desc_ep->bInterval -1; // Enable SOF interrupt if callback is implemented - if (tud_audio_sof_isr) usbd_sof_enable(rhport, true); + if (tud_audio_feedback_interval_isr) usbd_sof_enable(rhport, true); // // Invoke callback after ep_out is set // if (audio->ep_out != 0) @@ -2050,7 +2050,7 @@ uint8_t tud_audio_n_get_fb_n_frames(uint8_t func_id) #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -static bool set_fb_params(audiod_function_t* audio, uint32_t f_s, uint32_t f_m) +static bool set_fb_params(audiod_function_t* audio, uint32_t sample_freq, uint32_t mclk_freq) { // Check if frame interval is within sane limits // The interval value audio->fb_n_frames was taken from the descriptors within audiod_set_interface() @@ -2058,29 +2058,29 @@ static bool set_fb_params(audiod_function_t* audio, uint32_t f_s, uint32_t f_m) // n_frames_min is ceil(2^10 * f_s / f_m) for full speed and ceil(2^13 * f_s / f_m) for high speed // this lower limit ensures the measures feedback value has sufficient precision uint32_t const k = (TUSB_SPEED_FULL == tud_speed_get()) ? 10 : 13; - if ( (((1UL << k) * f_s / f_m) + 1) > audio->fb_n_frames ) + if ( (((1UL << k) * sample_freq / mclk_freq) + 1) > audio->fb_n_frames ) { TU_LOG1(" UAC2 feedback interval too small\r\n"); TU_BREAKPOINT(); return false; } // Check if parameters really allow for a power of two division - if ((f_m % f_s) == 0 && tu_is_power_of_two(f_m / f_s)) + if ((mclk_freq % sample_freq) == 0 && tu_is_power_of_two(mclk_freq / sample_freq)) { audio->fb_compute_method = FEEDBACK_COMPUTE_POWER_OF_2; - audio->fb_power_of_two_val = 16 - audio->fb_n_frames_shift - tu_log2(f_m / f_s); + audio->fb_power_of_two_val = 16 - audio->fb_n_frames_shift - tu_log2(mclk_freq / sample_freq); }else if ( audio->fb_compute_method == FEEDBACK_COMPUTE_FLOAT) { - audio->fb_float_val = (float)f_s / f_m * (1UL << (16 - audio->fb_n_frames_shift)); + audio->fb_float_val = (float)sample_freq / mclk_freq * (1UL << (16 - audio->fb_n_frames_shift)); }else { - audio->fb_param_factor_N = f_s; - audio->fb_param_factor_D = f_m; + audio->fb_sample_freq = sample_freq; + audio->fb_mclk_freq = mclk_freq; } // Minimal/Maximum value in 16.16 format for full speed (1ms per frame) or high speed (125 us per frame) uint32_t const frame_div = (TUSB_SPEED_FULL == tud_speed_get()) ? 1000 : 8000; - audio->fb_val_min = (f_s/frame_div - 1) << 16; - audio->fb_val_max = (f_s/frame_div + 1) << 16; + audio->fb_val_min = (sample_freq/frame_div - 1) << 16; + audio->fb_val_max = (sample_freq/frame_div + 1) << 16; return true; } @@ -2093,7 +2093,7 @@ uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles) switch (audio->fb_compute_method) { case FEEDBACK_COMPUTE_POWER_OF_2: - feedback = cycles << audio->fb_power_of_two_val; + feedback = (cycles << audio->fb_power_of_two_val); break; case FEEDBACK_COMPUTE_FLOAT: @@ -2102,8 +2102,8 @@ uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles) case FEEDBACK_COMPUTE_FIXED: { - uint64_t fb64 = (((uint64_t) cycles) * audio->fb_param_factor_N) << (16 - audio->fb_n_frames_shift); - feedback = (uint32_t) (fb64 / audio->fb_param_factor_D); + uint64_t fb64 = (((uint64_t) cycles) * audio->fb_sample_freq) << (16 - audio->fb_n_frames_shift); + feedback = (uint32_t) (fb64 / audio->fb_mclk_freq); } break; @@ -2142,10 +2142,11 @@ void audiod_sof_isr (uint8_t rhport, uint32_t frame_count) if (audio->ep_fb != 0) { - uint32_t const interval = (1UL << audio->fb_n_frames); + // TODO hs need to be adjusted to frame (SOF event is not generated for micro-frame) + uint32_t const interval = (1UL << audio->fb_n_frames_shift); if ( 0 == (frame_count & (interval-1)) ) { - if(tud_audio_sof_isr) tud_audio_sof_isr(i, frame_count); + if(tud_audio_feedback_interval_isr) tud_audio_feedback_interval_isr(i, frame_count, audio->fb_n_frames_shift); } } } diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index 22394aaca..e6d3b74e6 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -503,7 +503,9 @@ uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles); // fixed_point : 0 float (default), 1 fixed point (for mcu without FPU) TU_ATTR_WEAK void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, uint32_t* sample_freq, uint32_t* mclk_freq, uint8_t* fixed_point); -TU_ATTR_WEAK void tud_audio_sof_isr(uint8_t func_id, uint32_t frame); +// Callback in ISR context, invoked periodically according to feedback endpoint bInterval. +// Could be used to compute and update feedback value +TU_ATTR_WEAK void tud_audio_feedback_interval_isr(uint8_t func_id, uint32_t frame_number, uint8_t interval_log2); #if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN From e5113a1cfc25c0e5e7e75c2644ed91d252391c28 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 19 May 2022 16:05:55 +0700 Subject: [PATCH 340/504] prototype for feedback method --- src/class/audio/audio_device.c | 21 +++++++-------------- src/class/audio/audio_device.h | 28 ++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index db8bbb819..1dce6a664 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -261,13 +261,6 @@ osal_mutex_def_t rx_supp_ff_mutex_rd_3[CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO]; #endif #endif -enum { - FEEDBACK_COMPUTE_DISABLED, - FEEDBACK_COMPUTE_FLOAT, - FEEDBACK_COMPUTE_FIXED, - FEEDBACK_COMPUTE_POWER_OF_2, -}; - typedef struct { uint8_t rhport; @@ -1722,10 +1715,10 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * if ( sample_freq == 0 || mclk_freq == 0 ) { - audio->fb_compute_method = FEEDBACK_COMPUTE_DISABLED; + audio->fb_compute_method = AUDIO_FEEDBACK_METHOD_DISABLED; }else { - audio->fb_compute_method = fixed_point ? FEEDBACK_COMPUTE_FIXED : FEEDBACK_COMPUTE_FLOAT; + audio->fb_compute_method = fixed_point ? AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED : AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT; set_fb_params(audio, sample_freq, mclk_freq); } } @@ -2066,9 +2059,9 @@ static bool set_fb_params(audiod_function_t* audio, uint32_t sample_freq, uint32 // Check if parameters really allow for a power of two division if ((mclk_freq % sample_freq) == 0 && tu_is_power_of_two(mclk_freq / sample_freq)) { - audio->fb_compute_method = FEEDBACK_COMPUTE_POWER_OF_2; + audio->fb_compute_method = AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2; audio->fb_power_of_two_val = 16 - audio->fb_n_frames_shift - tu_log2(mclk_freq / sample_freq); - }else if ( audio->fb_compute_method == FEEDBACK_COMPUTE_FLOAT) + }else if ( audio->fb_compute_method == AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT) { audio->fb_float_val = (float)sample_freq / mclk_freq * (1UL << (16 - audio->fb_n_frames_shift)); }else @@ -2092,15 +2085,15 @@ uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles) switch (audio->fb_compute_method) { - case FEEDBACK_COMPUTE_POWER_OF_2: + case AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2: feedback = (cycles << audio->fb_power_of_two_val); break; - case FEEDBACK_COMPUTE_FLOAT: + case AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT: feedback = (uint32_t) ((float) cylces * audio->fb_float_val); break; - case FEEDBACK_COMPUTE_FIXED: + case AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED: { uint64_t fb64 = (((uint64_t) cycles) * audio->fb_sample_freq) << (16 - audio->fb_n_frames_shift); feedback = (uint32_t) (fb64 / audio->fb_mclk_freq); diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index e6d3b74e6..da4a45eee 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -498,6 +498,34 @@ static inline uint8_t tud_audio_get_fb_n_frames(); // return feedback value in 16.16 for reference (0 for error) uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles); +enum { + AUDIO_FEEDBACK_METHOD_DISABLED, + AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED, + AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT, + AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2, + AUDIO_FEEDBACK_METHOD_FIFO_COUNT_FIXED, + AUDIO_FEEDBACK_METHOD_FIFO_COUNT_FLOAT +}; + +typedef struct { + uint8_t method; + union { + struct { + uint32_t sample_freq; + uint32_t mclk_freq; + }frequency; + + struct { + uint32_t nominal; + uint32_t threshold; + // variation etc .. + }fifo_count; + }; +}audio_feedback_params_t; + + +// TU_ATTR_WEAK void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedback_params_t* feedback_param); + // mclk_freq : Main clock frequency in Hz i.e. master clock to which sample clock is locked // sample_freq : sample frequency in Hz // fixed_point : 0 float (default), 1 fixed point (for mcu without FPU) From 26c4d4b328ca93d0db5d8d7842a315cbde4d9f5a Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Fri, 20 May 2022 17:25:30 -0500 Subject: [PATCH 341/504] Minor cleanup of RP2040 code post addition of Pico-PIO_USB * Removed some compiler warnings, and cleaned out unnecessary warning suppression from CMake suppress_tinyusb_warnings() * Made explicit family_configure_dual_usb_example() for DUAL mode examples as family_configure_target() may not generally be called multiple times for the same target * Renamed library pico_pio_usb to tinyusb_picio_pio_usb to be clearer and avoid conflict if someone already has a pico_pio_usb in their project * Added family_add_pico_pio_usb() method for adding Pico-PIO_SUB support to an existing example * Allowed tinyusb_pico_pio_usb to be added to regular apps using the Pico SDK --- .../device/net_lwip_webserver/src/lwipopts.h | 2 + examples/dual/CMakeLists.txt | 12 ++ .../host_hid_to_device_cdc/CMakeLists.txt | 4 +- examples/host/bare_api/CMakeLists.txt | 2 +- examples/host/cdc_msc_hid/CMakeLists.txt | 2 +- examples/host/hid_controller/CMakeLists.txt | 2 +- hw/bsp/rp2040/family.c | 2 + hw/bsp/rp2040/family.cmake | 154 +++++++++--------- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 4 + src/portable/raspberrypi/rp2040/rp2040_usb.c | 2 +- 10 files changed, 106 insertions(+), 80 deletions(-) create mode 100644 examples/dual/CMakeLists.txt diff --git a/examples/device/net_lwip_webserver/src/lwipopts.h b/examples/device/net_lwip_webserver/src/lwipopts.h index a215017c7..639619f63 100644 --- a/examples/device/net_lwip_webserver/src/lwipopts.h +++ b/examples/device/net_lwip_webserver/src/lwipopts.h @@ -49,7 +49,9 @@ #define TCP_MSS (1500 /*mtu*/ - 20 /*iphdr*/ - 20 /*tcphhr*/) #define TCP_SND_BUF (2 * TCP_MSS) +#ifndef TCP_WND #define TCP_WND (TCP_MSS) +#endif #define ETHARP_SUPPORT_STATIC_ENTRIES 1 diff --git a/examples/dual/CMakeLists.txt b/examples/dual/CMakeLists.txt new file mode 100644 index 000000000..d2f9a42f0 --- /dev/null +++ b/examples/dual/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.5) + +include(${CMAKE_CURRENT_SOURCE_DIR}/../../hw/bsp/family_support.cmake) + +project(tinyusb_dual_examples) +family_initialize_project(tinyusb_dual_examples ${CMAKE_CURRENT_LIST_DIR}) +if (FAMILY STREQUAL "rp2040" AND NOT TARGET tinyusb_pico_pio_usb) + message("Skipping dual host/device mode examples as Pico-PIO-USB is not available") +else() + # family_add_subdirectory will filter what to actually add based on selected FAMILY + family_add_subdirectory(host_hid_to_device_cdc) +endif() diff --git a/examples/dual/host_hid_to_device_cdc/CMakeLists.txt b/examples/dual/host_hid_to_device_cdc/CMakeLists.txt index 24ebfdec3..ea4e087e3 100644 --- a/examples/dual/host_hid_to_device_cdc/CMakeLists.txt +++ b/examples/dual/host_hid_to_device_cdc/CMakeLists.txt @@ -25,6 +25,4 @@ target_include_directories(${PROJECT} PUBLIC # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. -family_configure_device_example(${PROJECT}) -family_configure_host_example(${PROJECT}) -family_configure_pico_pio_usb_example(${PROJECT}) +family_configure_dual_usb_example(${PROJECT}) diff --git a/examples/host/bare_api/CMakeLists.txt b/examples/host/bare_api/CMakeLists.txt index 607ef22eb..bc04b01a7 100644 --- a/examples/host/bare_api/CMakeLists.txt +++ b/examples/host/bare_api/CMakeLists.txt @@ -27,4 +27,4 @@ target_include_directories(${PROJECT} PUBLIC family_configure_host_example(${PROJECT}) # For rp2040, un-comment to enable pico-pio-usb -# family_configure_pico_pio_usb_example(${PROJECT}) +# family_add_pico_pio_usb(${PROJECT}) \ No newline at end of file diff --git a/examples/host/cdc_msc_hid/CMakeLists.txt b/examples/host/cdc_msc_hid/CMakeLists.txt index 214e9f2e7..c4a4d8e63 100644 --- a/examples/host/cdc_msc_hid/CMakeLists.txt +++ b/examples/host/cdc_msc_hid/CMakeLists.txt @@ -29,4 +29,4 @@ target_include_directories(${PROJECT} PUBLIC family_configure_host_example(${PROJECT}) # For rp2040, un-comment to enable pico-pio-usb -# family_configure_pico_pio_usb_example(${PROJECT}) +# family_add_pico_pio_usb(${PROJECT}) diff --git a/examples/host/hid_controller/CMakeLists.txt b/examples/host/hid_controller/CMakeLists.txt index 6227e0790..6153d399a 100644 --- a/examples/host/hid_controller/CMakeLists.txt +++ b/examples/host/hid_controller/CMakeLists.txt @@ -28,4 +28,4 @@ target_include_directories(${PROJECT} PUBLIC family_configure_host_example(${PROJECT}) # For rp2040, un-comment to enable pico-pio-usb -# family_configure_pico_pio_usb_example(${PROJECT}) +# family_add_pico_pio_usb(${PROJECT}) diff --git a/hw/bsp/rp2040/family.c b/hw/bsp/rp2040/family.c index dcf38b6ec..8de1c1aab 100644 --- a/hw/bsp/rp2040/family.c +++ b/hw/bsp/rp2040/family.c @@ -127,8 +127,10 @@ void board_init(void) #ifndef BUTTON_BOOTSEL #endif +#if CFG_TUH_RPI_PIO_USB || CFG_TUD_RPI_PIO_USB // Set the system clock to a multiple of 120mhz for bitbanging USB with pico-usb set_sys_clock_khz(120000, true); +#endif #if defined(UART_DEV) && defined(LIB_PICO_STDIO_UART) bi_decl(bi_2pins_with_func(UART_TX_PIN, UART_TX_PIN, GPIO_FUNC_UART)); diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index 17ae3de9b..df3a6a91e 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -23,7 +23,7 @@ if (NOT TARGET _rp2040_family_inclusion_marker) set(PICO_TINYUSB_PATH ${TOP}) endif() - #------------------------------------ + #------------------------------------ # Base config for both device and host; wrapped by SDK's tinyusb_common #------------------------------------ add_library(tinyusb_common_base INTERFACE) @@ -50,7 +50,7 @@ if (NOT TARGET _rp2040_family_inclusion_marker) if (CMAKE_BUILD_TYPE STREQUAL "Debug") message("Compiling TinyUSB with CFG_TUSB_DEBUG=1") set(TINYUSB_DEBUG_LEVEL 1) - endif () + endif() target_compile_definitions(tinyusb_common_base INTERFACE CFG_TUSB_MCU=OPT_MCU_RP2040 @@ -58,44 +58,13 @@ if (NOT TARGET _rp2040_family_inclusion_marker) CFG_TUSB_DEBUG=${TINYUSB_DEBUG_LEVEL} ) - #------------------------------------ - # PIO USB for both host and device - #------------------------------------ - add_library(pico_pio_usb INTERFACE) - - if (NOT DEFINED PICO_PIO_USB_PATH) - set(PICO_PIO_USB_PATH "${TOP}/hw/mcu/raspberry_pi/Pico-PIO-USB") - endif() - - target_sources(pico_pio_usb INTERFACE - ${PICO_PIO_USB_PATH}/src/pio_usb.c - ${PICO_PIO_USB_PATH}/src/pio_usb_host.c - ${PICO_PIO_USB_PATH}/src/pio_usb_device.c - ${PICO_PIO_USB_PATH}/src/usb_crc.c - ) - - target_include_directories(pico_pio_usb INTERFACE - ${PICO_PIO_USB_PATH}/src - ) - - target_link_libraries(pico_pio_usb INTERFACE - hardware_dma - hardware_pio - pico_multicore - ) - - target_compile_definitions(pico_pio_usb INTERFACE - PIO_USB_USE_TINYUSB - ) - - #------------------------------------ + #------------------------------------ # Base config for device mode; wrapped by SDK's tinyusb_device #------------------------------------ add_library(tinyusb_device_base INTERFACE) target_sources(tinyusb_device_base INTERFACE ${TOP}/src/portable/raspberrypi/rp2040/dcd_rp2040.c ${TOP}/src/portable/raspberrypi/rp2040/rp2040_usb.c - ${TOP}/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c ${TOP}/src/device/usbd.c ${TOP}/src/device/usbd_control.c ${TOP}/src/class/audio/audio_device.c @@ -119,7 +88,6 @@ if (NOT TARGET _rp2040_family_inclusion_marker) target_sources(tinyusb_host_base INTERFACE ${TOP}/src/portable/raspberrypi/rp2040/hcd_rp2040.c ${TOP}/src/portable/raspberrypi/rp2040/rp2040_usb.c - ${TOP}/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c ${TOP}/src/host/usbh.c ${TOP}/src/host/hub.c ${TOP}/src/class/cdc/cdc_host.c @@ -140,8 +108,8 @@ if (NOT TARGET _rp2040_family_inclusion_marker) target_sources(tinyusb_bsp INTERFACE ${TOP}/hw/bsp/rp2040/family.c ) -# target_include_directories(tinyusb_bsp INTERFACE -# ${TOP}/hw/bsp/rp2040) + # target_include_directories(tinyusb_bsp INTERFACE + # ${TOP}/hw/bsp/rp2040) # tinyusb_additions will hold our extra settings for examples add_library(tinyusb_additions INTERFACE) @@ -151,22 +119,22 @@ if (NOT TARGET _rp2040_family_inclusion_marker) ) if(DEFINED LOG) - target_compile_definitions(tinyusb_additions INTERFACE CFG_TUSB_DEBUG=${LOG} ) + target_compile_definitions(tinyusb_additions INTERFACE CFG_TUSB_DEBUG=${LOG}) endif() if(LOGGER STREQUAL "rtt") - target_compile_definitions(tinyusb_additions INTERFACE - LOGGER_RTT - SEGGER_RTT_MODE_DEFAULT=SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL - ) + target_compile_definitions(tinyusb_additions INTERFACE + LOGGER_RTT + SEGGER_RTT_MODE_DEFAULT=SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL + ) - target_sources(tinyusb_additions INTERFACE - ${TOP}/lib/SEGGER_RTT/RTT/SEGGER_RTT.c - ) + target_sources(tinyusb_additions INTERFACE + ${TOP}/lib/SEGGER_RTT/RTT/SEGGER_RTT.c + ) - target_include_directories(tinyusb_additions INTERFACE - ${TOP}/lib/SEGGER_RTT/RTT - ) + target_include_directories(tinyusb_additions INTERFACE + ${TOP}/lib/SEGGER_RTT/RTT + ) endif() #------------------------------------ @@ -189,41 +157,81 @@ if (NOT TARGET _rp2040_family_inclusion_marker) target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_host) endfunction() - function(family_configure_pico_pio_usb_example TARGET) - family_configure_target(${TARGET}) - target_link_libraries(${TARGET} PUBLIC pico_stdlib pico_pio_usb) - pico_generate_pio_header(tinyusb_common_base ${PICO_PIO_USB_PATH}/src/usb_tx.pio) - pico_generate_pio_header(tinyusb_common_base ${PICO_PIO_USB_PATH}/src/usb_rx.pio) + function(family_add_pico_pio_usb TARGET) + target_link_libraries(${TARGET} PUBLIC tinyusb_pico_pio_usb) endfunction() + function(family_configure_dual_usb_example TARGET) + family_configure_target(${TARGET}) + # require tinyusb_pico_pio_usb + target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_device tinyusb_host tinyusb_pico_pio_usb ) + endfunction() + + function(check_and_add_pico_pio_usb_support) + # check for pico_generate_pio_header (as depending on environment we may be called before SDK is + # initialized in which case it isn't available yet), and only do the initialization once + if (COMMAND pico_generate_pio_header AND NOT TARGET tinyusb_pico_pio_usb) + #------------------------------------ + # PIO USB for both host and device + #------------------------------------ + + if (NOT DEFINED PICO_PIO_USB_PATH) + set(PICO_PIO_USB_PATH "${TOP}/hw/mcu/raspberry_pi/Pico-PIO-USB") + endif() + + if (EXISTS ${PICO_PIO_USB_PATH}/src/pio_usb.c) + add_library(tinyusb_pico_pio_usb INTERFACE) + target_sources(tinyusb_device_base INTERFACE + ${TOP}/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c + ) + target_sources(tinyusb_host_base INTERFACE + ${TOP}/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c + ) + + target_sources(tinyusb_pico_pio_usb INTERFACE + ${PICO_PIO_USB_PATH}/src/pio_usb.c + ${PICO_PIO_USB_PATH}/src/pio_usb_host.c + ${PICO_PIO_USB_PATH}/src/pio_usb_device.c + ${PICO_PIO_USB_PATH}/src/usb_crc.c + ) + + target_include_directories(tinyusb_pico_pio_usb INTERFACE + ${PICO_PIO_USB_PATH}/src + ) + + target_link_libraries(tinyusb_pico_pio_usb INTERFACE + hardware_dma + hardware_pio + pico_multicore + ) + + target_compile_definitions(tinyusb_pico_pio_usb INTERFACE + PIO_USB_USE_TINYUSB + ) + + pico_generate_pio_header(tinyusb_pico_pio_usb ${PICO_PIO_USB_PATH}/src/usb_tx.pio) + pico_generate_pio_header(tinyusb_pico_pio_usb ${PICO_PIO_USB_PATH}/src/usb_rx.pio) + endif() + endif() + endfunction() + + # Try to add Pico-PIO_USB support now for the case where this file is included directly + # after Pico SDK initialization, but without using the family_ functions (as is the case + # when included by the SDK itself) + check_and_add_pico_pio_usb_support() + function(family_initialize_project PROJECT DIR) # call the original version of this function from family_common.cmake _family_initialize_project(${PROJECT} ${DIR}) enable_language(C CXX ASM) pico_sdk_init() + + # now re-check for adding Pico-PIO_USB support now SDK is definitely available + check_and_add_pico_pio_usb_support() endfunction() # This method must be called from the project scope to suppress known warnings in TinyUSB source files function(suppress_tinyusb_warnings) - set_source_files_properties( - ${PICO_TINYUSB_PATH}/src/tusb.c - PROPERTIES - COMPILE_FLAGS "-Wno-conversion") - set_source_files_properties( - ${PICO_TINYUSB_PATH}/src/common/tusb_fifo.c - PROPERTIES - COMPILE_FLAGS "-Wno-conversion -Wno-cast-qual") - set_source_files_properties( - ${PICO_TINYUSB_PATH}/src/device/usbd.c - PROPERTIES - COMPILE_FLAGS "-Wno-conversion -Wno-cast-qual -Wno-null-dereference") - set_source_files_properties( - ${PICO_TINYUSB_PATH}/src/device/usbd_control.c - PROPERTIES - COMPILE_FLAGS "-Wno-conversion") - set_source_files_properties( - ${PICO_TINYUSB_PATH}/src/class/cdc/cdc_device.c - PROPERTIES - COMPILE_FLAGS "-Wno-conversion") + # there are currently no warnings to suppress, however this function must still exist endfunction() endif() diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 5164035aa..54c27ffe3 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -537,7 +537,11 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet (void) rhport; // Copy data into setup packet buffer +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Warray-bounds" +#pragma GCC diagnostic ignored "-Wstringop-overflow" memcpy((void*)&usbh_dpram->setup_packet[0], setup_packet, 8); +#pragma GCC diagnostic pop // Configure EP0 struct with setup info for the trans complete struct hw_endpoint *ep = _hw_endpoint_allocate(0); diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index 9c3e5d011..c93199fd0 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -58,9 +58,9 @@ void rp2040_usb_init(void) unreset_block_wait(RESETS_RESET_USBCTRL_BITS); // Clear any previous state just in case - // TODO Suppress warning array-bounds with gcc11 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warray-bounds" +#pragma GCC diagnostic ignored "-Wstringop-overflow" memset(usb_hw, 0, sizeof(*usb_hw)); memset(usb_dpram, 0, sizeof(*usb_dpram)); #pragma GCC diagnostic pop From 16c0eb0d2f2e2afe551d7bd239cb8092df7b2128 Mon Sep 17 00:00:00 2001 From: Sven Date: Tue, 24 May 2022 21:45:35 +0200 Subject: [PATCH 342/504] fix links in docs changed markdown formatting to rst formatting --- docs/reference/index.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/reference/index.rst b/docs/reference/index.rst index fcff03590..292fb1a93 100644 --- a/docs/reference/index.rst +++ b/docs/reference/index.rst @@ -25,7 +25,7 @@ Supports multiple device configurations by dynamically changing usb descriptors. - Vendor-specific class support with generic In & Out endpoints. Can be used with MS OS 2.0 compatible descriptor to load winUSB driver without INF file. - `WebUSB `__ with vendor-specific class -If you have special need, `usbd_app_driver_get_cb()` can be used to write your own class driver without modifying the stack. Here is how RPi team add their reset interface [raspberrypi/pico-sdk#197](https://github.com/raspberrypi/pico-sdk/pull/197) +If you have special need, `usbd_app_driver_get_cb()` can be used to write your own class driver without modifying the stack. Here is how RPi team add their reset interface `raspberrypi/pico-sdk#197 `__ Host Stack ========== @@ -41,7 +41,7 @@ TinyUSB is completely thread-safe by pushing all ISR events into a central queue - **No OS** - **FreeRTOS** -- **Mynewt** Due to the newt package build system, Mynewt examples are better to be on its [own repo](https://github.com/hathach/mynewt-tinyusb-example) +- **Mynewt** Due to the newt package build system, Mynewt examples are better to be on its `own repo `__ License ======= From 15aa593790311d6e279f01ba764a1a96d282a78b Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 27 May 2022 12:27:31 +0700 Subject: [PATCH 343/504] wrap feedback and compute to its own struct/union --- src/class/audio/audio_device.c | 132 +++++++++++++++++---------------- src/class/audio/audio_device.h | 28 ++----- 2 files changed, 78 insertions(+), 82 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 1dce6a664..e967e8c3f 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -306,21 +306,29 @@ typedef struct #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP - uint32_t fb_val; // Feedback value for asynchronous mode (in 16.16 format). - uint8_t fb_n_frames; // Number of (micro)frames used to estimate feedback value - uint8_t fb_n_frames_shift; - uint8_t fb_compute_method; + struct { + uint32_t value; // Feedback value for asynchronous mode (in 16.16 format). + uint32_t min_value; // min value according to UAC2 FMT-2.0 section 2.3.1.1. + uint32_t max_value; // max value according to UAC2 FMT-2.0 section 2.3.1.1. - uint32_t fb_val_min; // Maximum allowed feedback value according to UAC2 FMT-2.0 section 2.3.1.1. - uint32_t fb_val_max; // Maximum allowed feedback value according to UAC2 FMT-2.0 section 2.3.1.1. + uint8_t frame_shift; // bInterval-1 in unit of frame (FS), micro-frame (HS) + uint8_t compute_method; - // should be union - uint8_t fb_power_of_two_val; + union { + uint8_t power_of_2; // pre-computed power of 2 shift + float float_const; // pre-computed float constant - float fb_float_val; + struct { + uint32_t sample_freq; + uint32_t mclk_freq; + }fixed; - uint32_t fb_sample_freq; - uint32_t fb_mclk_freq; +// struct { +// +// }fifo_count; + }compute; + + } feedback; #endif // CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT @@ -437,10 +445,6 @@ static inline uint8_t tu_desc_subtype(void const* desc) } #endif -#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); -#endif - bool tud_audio_n_mounted(uint8_t func_id) { TU_VERIFY(func_id < CFG_TUD_AUDIO); @@ -1059,7 +1063,7 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP static inline bool audiod_fb_send(uint8_t rhport, audiod_function_t *audio) { - return usbd_edpt_xfer(rhport, audio->ep_fb, (uint8_t *) &audio->fb_val, 4); + return usbd_edpt_xfer(rhport, audio->ep_fb, (uint8_t *) &audio->feedback.value, 4); } #endif @@ -1564,8 +1568,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP usbd_edpt_close(rhport, audio->ep_fb); audio->ep_fb = 0; - audio->fb_n_frames = 0; - + tu_memclr(&audio->feedback, sizeof(audio->feedback)); #endif } #endif @@ -1679,8 +1682,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && desc_ep->bmAttributes.usage == 1) // Check if usage is explicit data feedback { audio->ep_fb = ep_addr; - audio->fb_n_frames = 1U << (desc_ep->bInterval -1); // TODO correctly set USB frame interval for SOF (not micro-frame) - audio->fb_n_frames_shift = desc_ep->bInterval -1; + audio->feedback.frame_shift = desc_ep->bInterval -1; // Enable SOF interrupt if callback is implemented if (tud_audio_feedback_interval_isr) usbd_sof_enable(rhport, true); @@ -1708,18 +1710,26 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * // Prepare feedback computation if callback is available if (tud_audio_feedback_params_cb) { - uint32_t sample_freq = 0; - uint32_t mclk_freq = 0; - uint8_t fixed_point = 0; - tud_audio_feedback_params_cb(func_id, alt, &sample_freq, &mclk_freq, &fixed_point); + audio_feedback_params_t fb_param; - if ( sample_freq == 0 || mclk_freq == 0 ) + tud_audio_feedback_params_cb(func_id, alt, &fb_param); + audio->feedback.compute_method = fb_param.method; + + switch(fb_param.method) { - audio->fb_compute_method = AUDIO_FEEDBACK_METHOD_DISABLED; - }else - { - audio->fb_compute_method = fixed_point ? AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED : AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT; - set_fb_params(audio, sample_freq, mclk_freq); + case AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED: + case AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT: + case AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2: + set_fb_params_freq(audio, fb_param.frequency.sample_freq, fb_param.frequency.mclk_freq); + break; + + case AUDIO_FEEDBACK_METHOD_FIFO_COUNT_FIXED: + case AUDIO_FEEDBACK_METHOD_FIFO_COUNT_FLOAT: + // TODO feedback by fifo count + break; + + // nothing to do + default: break; } } #endif @@ -2035,23 +2045,18 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 } #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -uint8_t tud_audio_n_get_fb_n_frames(uint8_t func_id) -{ - return _audiod_fct[func_id].fb_n_frames; -} -#endif -#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP - -static bool set_fb_params(audiod_function_t* audio, uint32_t sample_freq, uint32_t mclk_freq) +static bool set_fb_params_freq(audiod_function_t* audio, uint32_t sample_freq, uint32_t mclk_freq) { // Check if frame interval is within sane limits - // The interval value audio->fb_n_frames was taken from the descriptors within audiod_set_interface() + // The interval value n_frames was taken from the descriptors within audiod_set_interface() // n_frames_min is ceil(2^10 * f_s / f_m) for full speed and ceil(2^13 * f_s / f_m) for high speed // this lower limit ensures the measures feedback value has sufficient precision uint32_t const k = (TUSB_SPEED_FULL == tud_speed_get()) ? 10 : 13; - if ( (((1UL << k) * sample_freq / mclk_freq) + 1) > audio->fb_n_frames ) + uint32_t const n_frame = (1UL << audio->feedback.frame_shift); + + if ( (((1UL << k) * sample_freq / mclk_freq) + 1) > n_frame ) { TU_LOG1(" UAC2 feedback interval too small\r\n"); TU_BREAKPOINT(); return false; } @@ -2059,21 +2064,23 @@ static bool set_fb_params(audiod_function_t* audio, uint32_t sample_freq, uint32 // Check if parameters really allow for a power of two division if ((mclk_freq % sample_freq) == 0 && tu_is_power_of_two(mclk_freq / sample_freq)) { - audio->fb_compute_method = AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2; - audio->fb_power_of_two_val = 16 - audio->fb_n_frames_shift - tu_log2(mclk_freq / sample_freq); - }else if ( audio->fb_compute_method == AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT) + audio->feedback.compute_method = AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2; + audio->feedback.compute.power_of_2 = 16 - audio->feedback.frame_shift - tu_log2(mclk_freq / sample_freq); + } + else if ( audio->feedback.compute_method == AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT) { - audio->fb_float_val = (float)sample_freq / mclk_freq * (1UL << (16 - audio->fb_n_frames_shift)); - }else + audio->feedback.compute.float_const = (float)sample_freq / mclk_freq * (1UL << (16 - audio->feedback.frame_shift)); + } + else { - audio->fb_sample_freq = sample_freq; - audio->fb_mclk_freq = mclk_freq; + audio->feedback.compute.fixed.sample_freq = sample_freq; + audio->feedback.compute.fixed.mclk_freq = mclk_freq; } // Minimal/Maximum value in 16.16 format for full speed (1ms per frame) or high speed (125 us per frame) - uint32_t const frame_div = (TUSB_SPEED_FULL == tud_speed_get()) ? 1000 : 8000; - audio->fb_val_min = (sample_freq/frame_div - 1) << 16; - audio->fb_val_max = (sample_freq/frame_div + 1) << 16; + uint32_t const frame_div = (TUSB_SPEED_FULL == tud_speed_get()) ? 1000 : 8000; + audio->feedback.min_value = (sample_freq/frame_div - 1) << 16; + audio->feedback.max_value = (sample_freq/frame_div + 1) << 16; return true; } @@ -2083,20 +2090,20 @@ uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles) audiod_function_t* audio = &_audiod_fct[func_id]; uint32_t feedback; - switch (audio->fb_compute_method) + switch (audio->feedback.compute_method) { case AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2: - feedback = (cycles << audio->fb_power_of_two_val); + feedback = (cycles << audio->feedback.compute.power_of_2); break; case AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT: - feedback = (uint32_t) ((float) cylces * audio->fb_float_val); + feedback = (uint32_t) ((float) cycles * audio->feedback.compute.float_const); break; case AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED: { - uint64_t fb64 = (((uint64_t) cycles) * audio->fb_sample_freq) << (16 - audio->fb_n_frames_shift); - feedback = (uint32_t) (fb64 / audio->fb_mclk_freq); + uint64_t fb64 = (((uint64_t) cycles) * audio->feedback.compute.fixed.sample_freq) << (16 - audio->feedback.frame_shift); + feedback = (uint32_t) (fb64 / audio->feedback.compute.fixed.mclk_freq); } break; @@ -2107,8 +2114,8 @@ uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles) // The size of isochronous packets created by the device must be within the limits specified in FMT-2.0 section 2.3.1.1. // This means that the deviation of actual packet size from nominal size must not exceed +/- one audio slot // (audio slot = channel count samples). - if ( feedback > audio->fb_val_max ) feedback = audio->fb_val_max; - if ( feedback < audio->fb_val_min ) feedback = audio->fb_val_min; + if ( feedback > audio->feedback.max_value ) feedback = audio->feedback.max_value; + if ( feedback < audio->feedback.min_value ) feedback = audio->feedback.min_value; tud_audio_n_fb_set(func_id, feedback); @@ -2135,11 +2142,12 @@ void audiod_sof_isr (uint8_t rhport, uint32_t frame_count) if (audio->ep_fb != 0) { - // TODO hs need to be adjusted to frame (SOF event is not generated for micro-frame) - uint32_t const interval = (1UL << audio->fb_n_frames_shift); + // HS shift need to be adjusted since SOF event is generated for frame only + uint8_t const hs_adjust = (TUSB_SPEED_HIGH == tud_speed_get()) ? 3 : 0; + uint32_t const interval = 1UL << (audio->feedback.frame_shift - hs_adjust); if ( 0 == (frame_count & (interval-1)) ) { - if(tud_audio_feedback_interval_isr) tud_audio_feedback_interval_isr(i, frame_count, audio->fb_n_frames_shift); + if(tud_audio_feedback_interval_isr) tud_audio_feedback_interval_isr(i, frame_count, audio->feedback.frame_shift); } } } @@ -2431,7 +2439,7 @@ bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION if ( TUSB_SPEED_FULL == tud_speed_get() ) { - uint8_t * fb = (uint8_t *) &_audiod_fct[func_id].fb_val; + uint8_t * fb = (uint8_t *) &_audiod_fct[func_id].feedback.value; // For FS format is 10.14 *(fb++) = (feedback >> 2) & 0xFF; @@ -2443,7 +2451,7 @@ bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) #else { // Send value as-is, caller will choose the appropriate format - _audiod_fct[func_id].fb_val = feedback; + _audiod_fct[func_id].feedback.value = feedback; } #endif diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index da4a45eee..09de8e9a8 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -487,11 +487,6 @@ TU_ATTR_WEAK void tud_audio_fb_done_cb(uint8_t func_id); bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); static inline bool tud_audio_fb_set(uint32_t feedback); -uint8_t tud_audio_n_get_fb_n_frames(uint8_t func_id); -static inline uint8_t tud_audio_get_fb_n_frames(); - -#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP - // Update feedback value with passed cycles since last time this update function is called. // Typically called within tud_audio_sof_isr(). Required tud_audio_feedback_params_cb() is implemented // This function will also call tud_audio_feedback_set() @@ -511,8 +506,8 @@ typedef struct { uint8_t method; union { struct { - uint32_t sample_freq; - uint32_t mclk_freq; + uint32_t sample_freq; // sample frequency in Hz + uint32_t mclk_freq; // Main clock frequency in Hz i.e. master clock to which sample clock is based on }frequency; struct { @@ -523,18 +518,16 @@ typedef struct { }; }audio_feedback_params_t; - -// TU_ATTR_WEAK void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedback_params_t* feedback_param); - -// mclk_freq : Main clock frequency in Hz i.e. master clock to which sample clock is locked -// sample_freq : sample frequency in Hz -// fixed_point : 0 float (default), 1 fixed point (for mcu without FPU) -TU_ATTR_WEAK void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, uint32_t* sample_freq, uint32_t* mclk_freq, uint8_t* fixed_point); +// Invoked when needed to set feedback parameters +TU_ATTR_WEAK void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedback_params_t* feedback_param); // Callback in ISR context, invoked periodically according to feedback endpoint bInterval. // Could be used to compute and update feedback value -TU_ATTR_WEAK void tud_audio_feedback_interval_isr(uint8_t func_id, uint32_t frame_number, uint8_t interval_log2); +// frame_number : current SOF count +// interval_shift: number of bit shift i.e log2(interval) from Feedback endpoint descriptor +TU_ATTR_WEAK void tud_audio_feedback_interval_isr(uint8_t func_id, uint32_t frame_number, uint8_t interval_shift); +#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN TU_ATTR_WEAK bool tud_audio_int_ctr_done_cb(uint8_t rhport, uint16_t n_bytes_copied); @@ -682,11 +675,6 @@ static inline bool tud_audio_fb_set(uint32_t feedback) return tud_audio_n_fb_set(0, feedback); } -static inline uint8_t tud_audio_get_fb_n_frames() -{ - return tud_audio_n_get_fb_n_frames(0); -} - #endif //--------------------------------------------------------------------+ From f76c7526c950eb7ddd8e8e6ad3f6c95f8785b267 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Fri, 27 May 2022 11:54:28 -0400 Subject: [PATCH 344/504] Remove lib/Pico-PIO-USB, which has moved to hw/mcu/raspberry_pi/Pico-PIO-USB. --- lib/Pico-PIO-USB | 1 - 1 file changed, 1 deletion(-) delete mode 160000 lib/Pico-PIO-USB diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB deleted file mode 160000 index 53ec09168..000000000 --- a/lib/Pico-PIO-USB +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 53ec09168c5a3cd30d8dcb577fa97dc328d769d4 From dce2ad4ffb33fe884429e0c241b1957b3cd6c453 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 27 May 2022 23:11:25 +0700 Subject: [PATCH 345/504] adding feedback fifo count (WIP) --- src/class/audio/audio_device.c | 47 +++++++++++++++++++--------------- src/class/audio/audio_device.h | 9 +++---- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index e967e8c3f..31851e00c 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -323,9 +323,10 @@ typedef struct uint32_t mclk_freq; }fixed; -// struct { -// -// }fifo_count; + struct { + uint32_t nominal_value; + uint32_t threshold_bytes; + }fifo_count; }compute; } feedback; @@ -1715,17 +1716,28 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * tud_audio_feedback_params_cb(func_id, alt, &fb_param); audio->feedback.compute_method = fb_param.method; + // Minimal/Maximum value in 16.16 format for full speed (1ms per frame) or high speed (125 us per frame) + uint32_t const frame_div = (TUSB_SPEED_FULL == tud_speed_get()) ? 1000 : 8000; + audio->feedback.min_value = (fb_param.sample_freq/frame_div - 1) << 16; + audio->feedback.max_value = (fb_param.sample_freq/frame_div + 1) << 16; + switch(fb_param.method) { case AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED: case AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT: case AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2: - set_fb_params_freq(audio, fb_param.frequency.sample_freq, fb_param.frequency.mclk_freq); + set_fb_params_freq(audio, fb_param.sample_freq, fb_param.frequency.mclk_freq); break; case AUDIO_FEEDBACK_METHOD_FIFO_COUNT_FIXED: case AUDIO_FEEDBACK_METHOD_FIFO_COUNT_FLOAT: - // TODO feedback by fifo count + { + uint64_t fb64 = ((uint64_t) fb_param.sample_freq) << 16; + audio->feedback.compute.fifo_count.nominal_value = (uint32_t) (fb64 / frame_div); + audio->feedback.compute.fifo_count.threshold_bytes = fb_param.fifo_count.threshold_bytes; + + tud_audio_fb_set(audio->feedback.compute.fifo_count.nominal_value); + } break; // nothing to do @@ -1972,14 +1984,14 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 (void) xferred_bytes; // Search for interface belonging to given end point address and proceed as required - uint8_t func_id; - for (func_id = 0; func_id < CFG_TUD_AUDIO; func_id++) + for (uint8_t func_id = 0; func_id < CFG_TUD_AUDIO; func_id++) { + audiod_function_t* audio = &_audiod_fct[func_id]; #if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN // Data transmission of control interrupt finished - if (_audiod_fct[func_id].ep_int_ctr == ep_addr) + if (audio->ep_int_ctr == ep_addr) { // According to USB2 specification, maximum payload of interrupt EP is 8 bytes on low speed, 64 bytes on full speed, and 1024 bytes on high speed (but only if an alternate interface other than 0 is used - see specification p. 49) // In case there is nothing to send we have to return a NAK - this is taken care of by PHY ??? @@ -1996,7 +2008,7 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 #if CFG_TUD_AUDIO_ENABLE_EP_IN // Data transmission of audio packet finished - if (_audiod_fct[func_id].ep_in == ep_addr && _audiod_fct[func_id].alt_setting != 0) + if (audio->ep_in == ep_addr && audio->alt_setting != 0) { // USB 2.0, section 5.6.4, third paragraph, states "An isochronous endpoint must specify its required bus access period. However, an isochronous endpoint must be prepared to handle poll rates faster than the one specified." // That paragraph goes on to say "An isochronous IN endpoint must return a zero-length packet whenever data is requested at a faster interval than the specified interval and data is not available." @@ -2007,7 +2019,7 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 // This is the only place where we can fill something into the EPs buffer! // Load new data - TU_VERIFY(audiod_tx_done_cb(rhport, &_audiod_fct[func_id])); + TU_VERIFY(audiod_tx_done_cb(rhport, audio)); // Transmission of ZLP is done by audiod_tx_done_cb() return true; @@ -2017,24 +2029,24 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 #if CFG_TUD_AUDIO_ENABLE_EP_OUT // New audio packet received - if (_audiod_fct[func_id].ep_out == ep_addr) + if (audio->ep_out == ep_addr) { - TU_VERIFY(audiod_rx_done_cb(rhport, &_audiod_fct[func_id], (uint16_t) xferred_bytes)); + TU_VERIFY(audiod_rx_done_cb(rhport, audio, (uint16_t) xferred_bytes)); return true; } #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // Transmission of feedback EP finished - if (_audiod_fct[func_id].ep_fb == ep_addr) + if (audio->ep_fb == ep_addr) { if (tud_audio_fb_done_cb) tud_audio_fb_done_cb(func_id); // Schedule a transmit with the new value if EP is not busy - if (!usbd_edpt_busy(rhport, _audiod_fct[func_id].ep_fb)) + if (!usbd_edpt_busy(rhport, audio->ep_fb)) { // Schedule next transmission - value is changed bytud_audio_n_fb_set() in the meantime or the old value gets sent - return audiod_fb_send(rhport, &_audiod_fct[func_id]); + return audiod_fb_send(rhport, audio); } } #endif @@ -2077,11 +2089,6 @@ static bool set_fb_params_freq(audiod_function_t* audio, uint32_t sample_freq, u audio->feedback.compute.fixed.mclk_freq = mclk_freq; } - // Minimal/Maximum value in 16.16 format for full speed (1ms per frame) or high speed (125 us per frame) - uint32_t const frame_div = (TUSB_SPEED_FULL == tud_speed_get()) ? 1000 : 8000; - audio->feedback.min_value = (sample_freq/frame_div - 1) << 16; - audio->feedback.max_value = (sample_freq/frame_div + 1) << 16; - return true; } diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index 09de8e9a8..c44b4cc30 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -504,16 +504,15 @@ enum { typedef struct { uint8_t method; + uint32_t sample_freq; // sample frequency in Hz + union { struct { - uint32_t sample_freq; // sample frequency in Hz - uint32_t mclk_freq; // Main clock frequency in Hz i.e. master clock to which sample clock is based on + uint32_t mclk_freq; // Main clock frequency in Hz i.e. master clock to which sample clock is based on }frequency; struct { - uint32_t nominal; - uint32_t threshold; - // variation etc .. + uint32_t threshold_bytes; // minimum number of bytes received to be considered as filled/ready }fifo_count; }; }audio_feedback_params_t; From a87ccee74392922761a0d6379b91ef50098aab01 Mon Sep 17 00:00:00 2001 From: Leon Loeser Date: Sat, 28 May 2022 19:48:20 +0200 Subject: [PATCH 346/504] Fix printf long int compiler error --- examples/device/uac2_headset/src/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/device/uac2_headset/src/main.c b/examples/device/uac2_headset/src/main.c index 67e287d3e..bbaacd975 100644 --- a/examples/device/uac2_headset/src/main.c +++ b/examples/device/uac2_headset/src/main.c @@ -156,7 +156,7 @@ static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t { if (request->bRequest == AUDIO_CS_REQ_CUR) { - TU_LOG1("Clock get current freq %u\r\n", current_sample_rate); + TU_LOG1("Clock get current freq %lu\r\n", current_sample_rate); audio_control_cur_4_t curf = { tu_htole32(current_sample_rate) }; return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &curf, sizeof(curf)); @@ -205,7 +205,7 @@ static bool tud_audio_clock_set_request(uint8_t rhport, audio_control_request_t current_sample_rate = ((audio_control_cur_4_t const *)buf)->bCur; - TU_LOG1("Clock set current freq: %d\r\n", current_sample_rate); + TU_LOG1("Clock set current freq: %ld\r\n", current_sample_rate); return true; } From 688a3a0cc2ba23c671df453257fdf3e601934588 Mon Sep 17 00:00:00 2001 From: Ryzee119 Date: Sun, 29 May 2022 13:58:10 +0930 Subject: [PATCH 347/504] Fix non-trivial designated initializers compile error --- src/host/hcd.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/host/hcd.h b/src/host/hcd.h index 036394c72..5d61dcd88 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -204,13 +204,11 @@ void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, uint32_t xferred .rhport = 0, // TODO correct rhport .event_id = HCD_EVENT_XFER_COMPLETE, .dev_addr = dev_addr, - .xfer_complete = - { - .ep_addr = ep_addr, - .result = result, - .len = xferred_bytes - } }; + event.xfer_complete.ep_addr = ep_addr; + event.xfer_complete.result = result; + event.xfer_complete.len = xferred_bytes; + hcd_event_handler(&event, in_isr); } From 9e30ec4f160e4816e3c43a0590e6c58832a66cac Mon Sep 17 00:00:00 2001 From: Ryzee119 Date: Sun, 29 May 2022 13:58:50 +0930 Subject: [PATCH 348/504] Hub: Retry port status transfer if failed --- src/host/hub.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/host/hub.c b/src/host/hub.c index 9e546f6f7..5c0fd9166 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -169,7 +169,7 @@ bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, }; TU_LOG2("HUB Get Port Status: addr = %u port = %u\r\n", hub_addr, hub_port); - TU_ASSERT( tuh_control_xfer(&xfer) ); + TU_VERIFY( tuh_control_xfer(&xfer) ); return true; } @@ -332,7 +332,11 @@ bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32 { if ( tu_bit_test(p_hub->status_change, port) ) { - hub_port_get_status(dev_addr, port, &p_hub->port_status, connection_get_status_complete, 0); + if (hub_port_get_status(dev_addr, port, &p_hub->port_status, connection_get_status_complete, 0) == false) + { + //Hub status control transfer failed, retry + hub_edpt_status_xfer(dev_addr); + } break; } } From b7c8cb3c41ba0fc7f9c0db9379d5c65871f6374d Mon Sep 17 00:00:00 2001 From: Ryzee119 Date: Sun, 29 May 2022 14:00:36 +0930 Subject: [PATCH 349/504] Hub: Unplug downstream devices on non-root hub disconnect --- src/host/usbh.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/host/usbh.c b/src/host/usbh.c index e0e41a8d1..af2ad0575 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -1107,6 +1107,12 @@ static void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t h { TU_LOG2(" Address = %u\r\n", dev_addr); + // If the device itself is a usb hub, unplug downstream devices. + if (dev_addr > CFG_TUH_DEVICE_MAX) + { + process_device_unplugged(rhport, dev_addr, 0); + } + // Invoke callback before close driver if (tuh_umount_cb) tuh_umount_cb(dev_addr); From 731ac3d3d60daf4831f2e9491a45d30cc2492d5b Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Mon, 30 May 2022 14:01:57 -0400 Subject: [PATCH 350/504] msp430x5xx: Add fix for possible bug in msp430-elf-gcc 9.3.0. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index c3b3b2403..f1d350dcc 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -623,7 +623,18 @@ void dcd_int_handler(uint8_t rhport) handle_setup_packet(); } - uint16_t curr_vector = USBVECINT; + // Workaround possible bug in MSP430 GCC 9.3.0 where volatile variable + // USBVECINT is read from twice when only once is intended. The second + // (garbage) read seems to be triggered by certain switch statement + // configurations. + uint16_t curr_vector; + #if __GNUC__ > 9 || (__GNUC__ == 9 && __GNUC_MINOR__ > 2) + asm volatile ("mov %1, %0" + : "=r" (curr_vector) + : "m" (USBVECINT)); + #else + curr_vector = USBVECINT; + #endif switch(curr_vector) { From f2926670cc4e495e025b0838fed5b44d27e4cd43 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 31 May 2022 20:26:37 +0700 Subject: [PATCH 351/504] comment out fifo count method for now --- src/class/audio/audio_device.c | 18 ++++++++++-------- src/class/audio/audio_device.h | 7 +++++-- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 31851e00c..01a42f34f 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -305,13 +305,12 @@ typedef struct #endif #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP - struct { - uint32_t value; // Feedback value for asynchronous mode (in 16.16 format). - uint32_t min_value; // min value according to UAC2 FMT-2.0 section 2.3.1.1. - uint32_t max_value; // max value according to UAC2 FMT-2.0 section 2.3.1.1. + uint32_t value; // Feedback value for asynchronous mode (in 16.16 format). + uint32_t min_value; // min value according to UAC2 FMT-2.0 section 2.3.1.1. + uint32_t max_value; // max value according to UAC2 FMT-2.0 section 2.3.1.1. - uint8_t frame_shift; // bInterval-1 in unit of frame (FS), micro-frame (HS) + uint8_t frame_shift; // bInterval-1 in unit of frame (FS), micro-frame (HS) uint8_t compute_method; union { @@ -323,15 +322,17 @@ typedef struct uint32_t mclk_freq; }fixed; +#if 0 // implement later struct { uint32_t nominal_value; uint32_t threshold_bytes; }fifo_count; +#endif }compute; } feedback; - #endif // CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP + #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT #if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING @@ -1729,8 +1730,8 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * set_fb_params_freq(audio, fb_param.sample_freq, fb_param.frequency.mclk_freq); break; - case AUDIO_FEEDBACK_METHOD_FIFO_COUNT_FIXED: - case AUDIO_FEEDBACK_METHOD_FIFO_COUNT_FLOAT: + #if 0 // implement later + case AUDIO_FEEDBACK_METHOD_FIFO_COUNT: { uint64_t fb64 = ((uint64_t) fb_param.sample_freq) << 16; audio->feedback.compute.fifo_count.nominal_value = (uint32_t) (fb64 / frame_div); @@ -1739,6 +1740,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * tud_audio_fb_set(audio->feedback.compute.fifo_count.nominal_value); } break; + #endif // nothing to do default: break; diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index c44b4cc30..13f24fb62 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -498,8 +498,9 @@ enum { AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED, AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT, AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2, - AUDIO_FEEDBACK_METHOD_FIFO_COUNT_FIXED, - AUDIO_FEEDBACK_METHOD_FIFO_COUNT_FLOAT + + // impelemnt later + // AUDIO_FEEDBACK_METHOD_FIFO_COUNT }; typedef struct { @@ -511,9 +512,11 @@ typedef struct { uint32_t mclk_freq; // Main clock frequency in Hz i.e. master clock to which sample clock is based on }frequency; +#if 0 // implement later struct { uint32_t threshold_bytes; // minimum number of bytes received to be considered as filled/ready }fifo_count; +#endif }; }audio_feedback_params_t; From e384d16d576089daa3a5c993ead06cffb7a50cbe Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 31 May 2022 21:52:54 +0700 Subject: [PATCH 352/504] clean up tud_audio_set_itf_cb() invocation --- src/class/audio/audio_device.c | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 01a42f34f..a2801e299 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -1629,8 +1629,6 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * #endif #endif - // Invoke callback - can be used to trigger data sampling if not already running - // if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); // Schedule first transmit if alternate interface is not zero i.e. streaming is disabled - in case no sample data is available a ZLP is loaded // It is necessary to trigger this here since the refill is done with an RX FIFO empty interrupt which can only trigger if something was in there @@ -1662,16 +1660,6 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * #endif #endif -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP - // In case of asynchronous EP, call Cb after ep_fb is set - // if ( !(desc_ep->bmAttributes.sync == 0x01 && audio->ep_fb == 0) ) - // { - // if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); - // } -#else - // Invoke callback - if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); -#endif // Prepare for incoming data #if USE_LINEAR_BUFFER_RX TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_out, audio->lin_buf_out, audio->ep_out_sz), false); @@ -1688,12 +1676,6 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * // Enable SOF interrupt if callback is implemented if (tud_audio_feedback_interval_isr) usbd_sof_enable(rhport, true); - - // // Invoke callback after ep_out is set - // if (audio->ep_out != 0) - // { - // if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); - // } } #endif #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT @@ -1705,10 +1687,10 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * TU_VERIFY(foundEPs == nEps); -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // Invoke one callback for a final set interface if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // Prepare feedback computation if callback is available if (tud_audio_feedback_params_cb) { From 6e7cd220dc60b176e0096f4a5818376ea84a7e15 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 1 Jun 2022 13:18:24 +0700 Subject: [PATCH 353/504] grstctl set fifo + flush in one assign --- src/portable/synopsys/dwc2/dcd_dwc2.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 01b74d05e..556bcaf65 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -796,8 +796,7 @@ static void dcd_edpt_disable (uint8_t rhport, uint8_t ep_addr, bool stall) } // Flush the FIFO, and wait until we have confirmed it cleared. - dwc2->grstctl = (epnum << GRSTCTL_TXFNUM_Pos); - dwc2->grstctl |= GRSTCTL_TXFFLSH; + dwc2->grstctl = ((epnum << GRSTCTL_TXFNUM_Pos) | GRSTCTL_TXFFLSH); while ( (dwc2->grstctl & GRSTCTL_TXFFLSH_Msk) != 0 ) {} } else From ea8a9e024983441c4b2cb5ee27acf7953a2b607e Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 1 Jun 2022 15:10:05 +0700 Subject: [PATCH 354/504] remove cmake compile macro for net example (use lwipopts.h instead) --- examples/device/net_lwip_webserver/CMakeLists.txt | 6 ------ examples/device/net_lwip_webserver/src/lwipopts.h | 2 -- 2 files changed, 8 deletions(-) diff --git a/examples/device/net_lwip_webserver/CMakeLists.txt b/examples/device/net_lwip_webserver/CMakeLists.txt index 7500f6e9e..8e3f0f5a8 100644 --- a/examples/device/net_lwip_webserver/CMakeLists.txt +++ b/examples/device/net_lwip_webserver/CMakeLists.txt @@ -69,12 +69,6 @@ if (EXISTS ${TOP}/lib/lwip/src) ${TOP}/lib/networking/rndis_reports.c ) - target_compile_definitions(${PROJECT} PUBLIC - PBUF_POOL_SIZE=2 - TCP_WND=2*TCP_MSS - HTTPD_USE_CUSTOM_FSDATA=0 - ) - # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) diff --git a/examples/device/net_lwip_webserver/src/lwipopts.h b/examples/device/net_lwip_webserver/src/lwipopts.h index 639619f63..a215017c7 100644 --- a/examples/device/net_lwip_webserver/src/lwipopts.h +++ b/examples/device/net_lwip_webserver/src/lwipopts.h @@ -49,9 +49,7 @@ #define TCP_MSS (1500 /*mtu*/ - 20 /*iphdr*/ - 20 /*tcphhr*/) #define TCP_SND_BUF (2 * TCP_MSS) -#ifndef TCP_WND #define TCP_WND (TCP_MSS) -#endif #define ETHARP_SUPPORT_STATIC_ENTRIES 1 From 54d7790e8b9efd95bb0affb243b23a189ea06684 Mon Sep 17 00:00:00 2001 From: tfx2001 Date: Wed, 1 Jun 2022 21:25:36 +0800 Subject: [PATCH 355/504] fix compile error --- src/osal/osal_rtthread.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/osal/osal_rtthread.h b/src/osal/osal_rtthread.h index a790a5e27..f8452bfb2 100644 --- a/src/osal/osal_rtthread.h +++ b/src/osal/osal_rtthread.h @@ -49,7 +49,7 @@ typedef rt_sem_t osal_semaphore_t; TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t *semdef) { - rt_sem_init(semdef, "tusb", 0, RT_IPC_FLAG_FIFO); + rt_sem_init(semdef, "tusb", 0, RT_IPC_FLAG_PRIO); return semdef; } @@ -59,7 +59,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t se } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { - return rt_sem_take(sem_hdl, rt_tick_from_millisecond(msec)) == RT_EOK; + return rt_sem_take(sem_hdl, rt_tick_from_millisecond((rt_int32_t) msec)) == RT_EOK; } TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) { @@ -73,12 +73,12 @@ typedef struct rt_mutex osal_mutex_def_t; typedef rt_mutex_t osal_mutex_t; TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t *mdef) { - rt_mutex_init(mdef, "tusb", RT_IPC_FLAG_FIFO); + rt_mutex_init(mdef, "tusb", RT_IPC_FLAG_PRIO); return mdef; } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) { - return rt_mutex_take(mutex_hdl, rt_tick_from_millisecond(msec)) == RT_EOK; + return rt_mutex_take(mutex_hdl, rt_tick_from_millisecond((rt_int32_t) msec)) == RT_EOK; } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { @@ -106,13 +106,13 @@ typedef rt_mq_t osal_queue_t; TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t *qdef) { rt_mq_init(&(qdef->sq), "tusb", qdef->buf, qdef->item_sz, - qdef->item_sz * qdef->depth, RT_IPC_FLAG_FIFO); + qdef->item_sz * qdef->depth, RT_IPC_FLAG_PRIO); return &(qdef->sq); } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void *data, uint32_t msec) { - rt_tick_t tick = rt_tick_from_millisecond((rt_int32_t) msec)); + rt_tick_t tick = rt_tick_from_millisecond((rt_int32_t) msec); return rt_mq_recv(qhdl, data, qhdl->msg_size, tick) == RT_EOK; } From 99c1585ed215cb5ee2e27a41c54310d144e0ee6c Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 1 Jun 2022 23:53:40 +0700 Subject: [PATCH 356/504] rename board specific macro for example - BOARD_DEVICE/HOST_RHPORT_NUM to BOARD_TUD/H_RHPORT - BOARD_DEVICE/HOST_RHPORT_SPEED to BOARD_TUD/H_MAX_SPEED --- .../device/cdc_dual_ports/src/tusb_config.h | 16 +++--- examples/device/cdc_msc/src/tusb_config.h | 54 ++++++++++++------- .../device/cdc_msc_freertos/src/tusb_config.h | 18 +++---- examples/device/dfu/src/tusb_config.h | 16 +++--- examples/device/dfu_runtime/src/tusb_config.h | 16 +++--- .../dynamic_configuration/src/tusb_config.h | 16 +++--- .../hid_boot_interface/src/tusb_config.h | 18 +++---- .../device/hid_composite/src/tusb_config.h | 16 +++--- .../hid_composite_freertos/src/tusb_config.h | 16 +++--- .../hid_generic_inout/src/tusb_config.h | 16 +++--- .../hid_multiple_interface/src/tusb_config.h | 16 +++--- examples/device/midi_test/src/tusb_config.h | 16 +++--- .../device/msc_dual_lun/src/tusb_config.h | 16 +++--- .../net_lwip_webserver/src/tusb_config.h | 16 +++--- examples/device/usbtmc/src/tusb_config.h | 16 +++--- .../device/video_capture/src/tusb_config.h | 16 +++--- .../device/webusb_serial/src/tusb_config.h | 16 +++--- .../host_hid_to_device_cdc/src/tusb_config.h | 36 ++++++------- hw/bsp/imxrt/boards/mimxrt1060_evk/board.mk | 4 +- hw/bsp/imxrt/boards/mimxrt1064_evk/board.mk | 4 +- hw/bsp/imxrt/family.mk | 8 +-- hw/bsp/lpc54/family.mk | 2 +- hw/bsp/lpc55/family.mk | 4 +- hw/bsp/stm32f7/family.c | 4 +- hw/bsp/stm32f7/family.mk | 6 +-- hw/bsp/stm32h7/family.c | 4 +- hw/bsp/stm32h7/family.mk | 6 +-- src/portable/bridgetek/ft9xx/dcd_ft9xx.c | 42 +++++++-------- src/tusb_option.h | 2 + 29 files changed, 226 insertions(+), 210 deletions(-) diff --git a/examples/device/cdc_dual_ports/src/tusb_config.h b/examples/device/cdc_dual_ports/src/tusb_config.h index f93606092..037fc8290 100644 --- a/examples/device/cdc_dual_ports/src/tusb_config.h +++ b/examples/device/cdc_dual_ports/src/tusb_config.h @@ -40,21 +40,21 @@ #endif // RHPort number used for device can be defined by board.mk, default to port 0 -#ifndef BOARD_DEVICE_RHPORT_NUM - #define BOARD_DEVICE_RHPORT_NUM 0 +#ifndef BOARD_TUD_RHPORT + #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk // Default to max (auto) speed for MCU with internal HighSpeed PHY -#ifndef BOARD_DEVICE_RHPORT_SPEED - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED +#ifndef BOARD_TUD_MAX_SPEED + #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk -#if BOARD_DEVICE_RHPORT_NUM == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) -#elif BOARD_DEVICE_RHPORT_NUM == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#if BOARD_TUD_RHPORT == 0 + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) +#elif BOARD_TUD_RHPORT == 1 + #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) #else #error "Incorrect RHPort configuration" #endif diff --git a/examples/device/cdc_msc/src/tusb_config.h b/examples/device/cdc_msc/src/tusb_config.h index 6507cef19..3849ad4d0 100644 --- a/examples/device/cdc_msc/src/tusb_config.h +++ b/examples/device/cdc_msc/src/tusb_config.h @@ -39,31 +39,45 @@ #error CFG_TUSB_MCU must be defined #endif -// RHPort number used for device can be defined by board.mk, default to port 0 -#ifndef BOARD_DEVICE_RHPORT_NUM - #define BOARD_DEVICE_RHPORT_NUM 0 -#endif - -// RHPort max operational speed can defined by board.mk -// Default to max (auto) speed for MCU with internal HighSpeed PHY -#ifndef BOARD_DEVICE_RHPORT_SPEED - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED -#endif - -// Device mode with rhport and speed defined by board.mk -#if BOARD_DEVICE_RHPORT_NUM == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) -#elif BOARD_DEVICE_RHPORT_NUM == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) -#else - #error "Incorrect RHPort configuration" -#endif - // This example doesn't use an RTOS #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif +// Enable Device stack +#define CFG_TUD_ENABLED 1 + +// 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 +// Default to max (auto) speed for MCU with internal HighSpeed PHY +#ifndef BOARD_TUD_MAX_SPEED + #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED +#endif + +// Device mode with rhport and speed defined by board.mk +#if BOARD_TUD_RHPORT == 0 + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) +#elif BOARD_TUD_RHPORT == 1 + #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) +#else + #error "Incorrect RHPort configuration" +#endif + + + +// Device max speed, default is max speed that hardware controller could support without external PHY +// BOARD_TUD_MAX_SPEED can be used to change value (e.g for board features external PHY). +#ifdef BOARD_TUD_MAX_SPEED + #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED +#else + #define CFG_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED +#endif + + // CFG_TUSB_DEBUG is defined by compiler in DEBUG build // #define CFG_TUSB_DEBUG 0 diff --git a/examples/device/cdc_msc_freertos/src/tusb_config.h b/examples/device/cdc_msc_freertos/src/tusb_config.h index 55e84c62d..d8eeda07d 100644 --- a/examples/device/cdc_msc_freertos/src/tusb_config.h +++ b/examples/device/cdc_msc_freertos/src/tusb_config.h @@ -40,26 +40,26 @@ #endif // RHPort number used for device can be defined by board.mk, default to port 0 -#ifndef BOARD_DEVICE_RHPORT_NUM - #define BOARD_DEVICE_RHPORT_NUM 0 +#ifndef BOARD_TUD_RHPORT + #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk // Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed -#ifndef BOARD_DEVICE_RHPORT_SPEED +#ifndef BOARD_TUD_MAX_SPEED #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56) - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED + #define BOARD_TUD_MAX_SPEED OPT_MODE_HIGH_SPEED #else - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED + #define BOARD_TUD_MAX_SPEED OPT_MODE_FULL_SPEED #endif #endif // Device mode with rhport and speed defined by board.mk -#if BOARD_DEVICE_RHPORT_NUM == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) -#elif BOARD_DEVICE_RHPORT_NUM == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#if BOARD_TUD_RHPORT == 0 + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) +#elif BOARD_TUD_RHPORT == 1 + #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) #else #error "Incorrect RHPort configuration" #endif diff --git a/examples/device/dfu/src/tusb_config.h b/examples/device/dfu/src/tusb_config.h index d4779b2e1..924ede47a 100644 --- a/examples/device/dfu/src/tusb_config.h +++ b/examples/device/dfu/src/tusb_config.h @@ -22,21 +22,21 @@ #endif // RHPort number used for device can be defined by board.mk, default to port 0 -#ifndef BOARD_DEVICE_RHPORT_NUM - #define BOARD_DEVICE_RHPORT_NUM 0 +#ifndef BOARD_TUD_RHPORT + #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk // Default to max (auto) speed for MCU with internal HighSpeed PHY -#ifndef BOARD_DEVICE_RHPORT_SPEED - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED +#ifndef BOARD_TUD_MAX_SPEED + #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk -#if BOARD_DEVICE_RHPORT_NUM == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) -#elif BOARD_DEVICE_RHPORT_NUM == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#if BOARD_TUD_RHPORT == 0 + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) +#elif BOARD_TUD_RHPORT == 1 + #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) #else #error "Incorrect RHPort configuration" #endif diff --git a/examples/device/dfu_runtime/src/tusb_config.h b/examples/device/dfu_runtime/src/tusb_config.h index e15ae7997..f31c9c970 100644 --- a/examples/device/dfu_runtime/src/tusb_config.h +++ b/examples/device/dfu_runtime/src/tusb_config.h @@ -22,21 +22,21 @@ #endif // RHPort number used for device can be defined by board.mk, default to port 0 -#ifndef BOARD_DEVICE_RHPORT_NUM - #define BOARD_DEVICE_RHPORT_NUM 0 +#ifndef BOARD_TUD_RHPORT + #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk // Default to max (auto) speed for MCU with internal HighSpeed PHY -#ifndef BOARD_DEVICE_RHPORT_SPEED - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED +#ifndef BOARD_TUD_MAX_SPEED + #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk -#if BOARD_DEVICE_RHPORT_NUM == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) -#elif BOARD_DEVICE_RHPORT_NUM == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#if BOARD_TUD_RHPORT == 0 + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) +#elif BOARD_TUD_RHPORT == 1 + #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) #else #error "Incorrect RHPort configuration" #endif diff --git a/examples/device/dynamic_configuration/src/tusb_config.h b/examples/device/dynamic_configuration/src/tusb_config.h index ddc295dcc..333b62e03 100644 --- a/examples/device/dynamic_configuration/src/tusb_config.h +++ b/examples/device/dynamic_configuration/src/tusb_config.h @@ -40,21 +40,21 @@ #endif // RHPort number used for device can be defined by board.mk, default to port 0 -#ifndef BOARD_DEVICE_RHPORT_NUM - #define BOARD_DEVICE_RHPORT_NUM 0 +#ifndef BOARD_TUD_RHPORT + #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk // Default to max (auto) speed for MCU with internal HighSpeed PHY -#ifndef BOARD_DEVICE_RHPORT_SPEED - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED +#ifndef BOARD_TUD_MAX_SPEED + #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk -#if BOARD_DEVICE_RHPORT_NUM == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) -#elif BOARD_DEVICE_RHPORT_NUM == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#if BOARD_TUD_RHPORT == 0 + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) +#elif BOARD_TUD_RHPORT == 1 + #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) #else #error "Incorrect RHPort configuration" #endif diff --git a/examples/device/hid_boot_interface/src/tusb_config.h b/examples/device/hid_boot_interface/src/tusb_config.h index 8bc85b722..e3c50aa3f 100644 --- a/examples/device/hid_boot_interface/src/tusb_config.h +++ b/examples/device/hid_boot_interface/src/tusb_config.h @@ -41,24 +41,24 @@ // Use raspberry pio-usb for device // #define CFG_TUD_RPI_PIO_USB 1 -// #define BOARD_DEVICE_RHPORT_NUM 1 +// #define BOARD_TUD_RHPORT 1 // RHPort number used for device can be defined by board.mk, default to port 0 -#ifndef BOARD_DEVICE_RHPORT_NUM - #define BOARD_DEVICE_RHPORT_NUM 0 +#ifndef BOARD_TUD_RHPORT + #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk // Default to max (auto) speed for MCU with internal HighSpeed PHY -#ifndef BOARD_DEVICE_RHPORT_SPEED - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED +#ifndef BOARD_TUD_MAX_SPEED + #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk -#if BOARD_DEVICE_RHPORT_NUM == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) -#elif BOARD_DEVICE_RHPORT_NUM == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#if BOARD_TUD_RHPORT == 0 + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) +#elif BOARD_TUD_RHPORT == 1 + #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) #else #error "Incorrect RHPort configuration" #endif diff --git a/examples/device/hid_composite/src/tusb_config.h b/examples/device/hid_composite/src/tusb_config.h index d0f2b513f..1a9223f5b 100644 --- a/examples/device/hid_composite/src/tusb_config.h +++ b/examples/device/hid_composite/src/tusb_config.h @@ -40,21 +40,21 @@ #endif // RHPort number used for device can be defined by board.mk, default to port 0 -#ifndef BOARD_DEVICE_RHPORT_NUM - #define BOARD_DEVICE_RHPORT_NUM 0 +#ifndef BOARD_TUD_RHPORT + #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk // Default to max (auto) speed for MCU with internal HighSpeed PHY -#ifndef BOARD_DEVICE_RHPORT_SPEED - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED +#ifndef BOARD_TUD_MAX_SPEED + #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk -#if BOARD_DEVICE_RHPORT_NUM == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) -#elif BOARD_DEVICE_RHPORT_NUM == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#if BOARD_TUD_RHPORT == 0 + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) +#elif BOARD_TUD_RHPORT == 1 + #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) #else #error "Incorrect RHPort configuration" #endif diff --git a/examples/device/hid_composite_freertos/src/tusb_config.h b/examples/device/hid_composite_freertos/src/tusb_config.h index 7522bd714..8fd6498e6 100644 --- a/examples/device/hid_composite_freertos/src/tusb_config.h +++ b/examples/device/hid_composite_freertos/src/tusb_config.h @@ -40,21 +40,21 @@ #endif // RHPort number used for device can be defined by board.mk, default to port 0 -#ifndef BOARD_DEVICE_RHPORT_NUM - #define BOARD_DEVICE_RHPORT_NUM 0 +#ifndef BOARD_TUD_RHPORT + #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk // Default to max (auto) speed for MCU with internal HighSpeed PHY -#ifndef BOARD_DEVICE_RHPORT_SPEED - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED +#ifndef BOARD_TUD_MAX_SPEED + #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk -#if BOARD_DEVICE_RHPORT_NUM == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) -#elif BOARD_DEVICE_RHPORT_NUM == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#if BOARD_TUD_RHPORT == 0 + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) +#elif BOARD_TUD_RHPORT == 1 + #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) #else #error "Incorrect RHPort configuration" #endif diff --git a/examples/device/hid_generic_inout/src/tusb_config.h b/examples/device/hid_generic_inout/src/tusb_config.h index 9db50269c..e5ae4b0cc 100644 --- a/examples/device/hid_generic_inout/src/tusb_config.h +++ b/examples/device/hid_generic_inout/src/tusb_config.h @@ -40,21 +40,21 @@ #endif // RHPort number used for device can be defined by board.mk, default to port 0 -#ifndef BOARD_DEVICE_RHPORT_NUM - #define BOARD_DEVICE_RHPORT_NUM 0 +#ifndef BOARD_TUD_RHPORT + #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk // Default to max (auto) speed for MCU with internal HighSpeed PHY -#ifndef BOARD_DEVICE_RHPORT_SPEED - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED +#ifndef BOARD_TUD_MAX_SPEED + #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk -#if BOARD_DEVICE_RHPORT_NUM == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) -#elif BOARD_DEVICE_RHPORT_NUM == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#if BOARD_TUD_RHPORT == 0 + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) +#elif BOARD_TUD_RHPORT == 1 + #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) #else #error "Incorrect RHPort configuration" #endif diff --git a/examples/device/hid_multiple_interface/src/tusb_config.h b/examples/device/hid_multiple_interface/src/tusb_config.h index 32e8c2843..766b8e518 100644 --- a/examples/device/hid_multiple_interface/src/tusb_config.h +++ b/examples/device/hid_multiple_interface/src/tusb_config.h @@ -40,21 +40,21 @@ #endif // RHPort number used for device can be defined by board.mk, default to port 0 -#ifndef BOARD_DEVICE_RHPORT_NUM - #define BOARD_DEVICE_RHPORT_NUM 0 +#ifndef BOARD_TUD_RHPORT + #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk // Default to max (auto) speed for MCU with internal HighSpeed PHY -#ifndef BOARD_DEVICE_RHPORT_SPEED - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED +#ifndef BOARD_TUD_MAX_SPEED + #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk -#if BOARD_DEVICE_RHPORT_NUM == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) -#elif BOARD_DEVICE_RHPORT_NUM == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#if BOARD_TUD_RHPORT == 0 + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) +#elif BOARD_TUD_RHPORT == 1 + #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) #else #error "Incorrect RHPort configuration" #endif diff --git a/examples/device/midi_test/src/tusb_config.h b/examples/device/midi_test/src/tusb_config.h index 967c71403..a7673245e 100644 --- a/examples/device/midi_test/src/tusb_config.h +++ b/examples/device/midi_test/src/tusb_config.h @@ -40,21 +40,21 @@ #endif // RHPort number used for device can be defined by board.mk, default to port 0 -#ifndef BOARD_DEVICE_RHPORT_NUM - #define BOARD_DEVICE_RHPORT_NUM 0 +#ifndef BOARD_TUD_RHPORT + #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk // Default to max (auto) speed for MCU with internal HighSpeed PHY -#ifndef BOARD_DEVICE_RHPORT_SPEED - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED +#ifndef BOARD_TUD_MAX_SPEED + #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk -#if BOARD_DEVICE_RHPORT_NUM == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) -#elif BOARD_DEVICE_RHPORT_NUM == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#if BOARD_TUD_RHPORT == 0 + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) +#elif BOARD_TUD_RHPORT == 1 + #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) #else #error "Incorrect RHPort configuration" #endif diff --git a/examples/device/msc_dual_lun/src/tusb_config.h b/examples/device/msc_dual_lun/src/tusb_config.h index f617f5a4c..2778e61b0 100644 --- a/examples/device/msc_dual_lun/src/tusb_config.h +++ b/examples/device/msc_dual_lun/src/tusb_config.h @@ -40,21 +40,21 @@ #endif // RHPort number used for device can be defined by board.mk, default to port 0 -#ifndef BOARD_DEVICE_RHPORT_NUM - #define BOARD_DEVICE_RHPORT_NUM 0 +#ifndef BOARD_TUD_RHPORT + #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk // Default to max (auto) speed for MCU with internal HighSpeed PHY -#ifndef BOARD_DEVICE_RHPORT_SPEED - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED +#ifndef BOARD_TUD_MAX_SPEED + #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk -#if BOARD_DEVICE_RHPORT_NUM == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) -#elif BOARD_DEVICE_RHPORT_NUM == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#if BOARD_TUD_RHPORT == 0 + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) +#elif BOARD_TUD_RHPORT == 1 + #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) #else #error "Incorrect RHPort configuration" #endif diff --git a/examples/device/net_lwip_webserver/src/tusb_config.h b/examples/device/net_lwip_webserver/src/tusb_config.h index b1b48598b..5042c0e5d 100644 --- a/examples/device/net_lwip_webserver/src/tusb_config.h +++ b/examples/device/net_lwip_webserver/src/tusb_config.h @@ -40,21 +40,21 @@ #endif // RHPort number used for device can be defined by board.mk, default to port 0 -#ifndef BOARD_DEVICE_RHPORT_NUM - #define BOARD_DEVICE_RHPORT_NUM 0 +#ifndef BOARD_TUD_RHPORT + #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk // Default to max (auto) speed for MCU with internal HighSpeed PHY -#ifndef BOARD_DEVICE_RHPORT_SPEED - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED +#ifndef BOARD_TUD_MAX_SPEED + #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk -#if BOARD_DEVICE_RHPORT_NUM == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) -#elif BOARD_DEVICE_RHPORT_NUM == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#if BOARD_TUD_RHPORT == 0 + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) +#elif BOARD_TUD_RHPORT == 1 + #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) #else #error "Incorrect RHPort configuration" #endif diff --git a/examples/device/usbtmc/src/tusb_config.h b/examples/device/usbtmc/src/tusb_config.h index 5b2215be5..0b2df291a 100644 --- a/examples/device/usbtmc/src/tusb_config.h +++ b/examples/device/usbtmc/src/tusb_config.h @@ -22,21 +22,21 @@ #endif // RHPort number used for device can be defined by board.mk, default to port 0 -#ifndef BOARD_DEVICE_RHPORT_NUM - #define BOARD_DEVICE_RHPORT_NUM 0 +#ifndef BOARD_TUD_RHPORT + #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk // Default to max (auto) speed for MCU with internal HighSpeed PHY -#ifndef BOARD_DEVICE_RHPORT_SPEED - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED +#ifndef BOARD_TUD_MAX_SPEED + #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk -#if BOARD_DEVICE_RHPORT_NUM == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) -#elif BOARD_DEVICE_RHPORT_NUM == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#if BOARD_TUD_RHPORT == 0 + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) +#elif BOARD_TUD_RHPORT == 1 + #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) #else #error "Incorrect RHPort configuration" #endif diff --git a/examples/device/video_capture/src/tusb_config.h b/examples/device/video_capture/src/tusb_config.h index 3a079e66b..85bf80a64 100644 --- a/examples/device/video_capture/src/tusb_config.h +++ b/examples/device/video_capture/src/tusb_config.h @@ -35,21 +35,21 @@ //-------------------------------------------------------------------- // RHPort number used for device can be defined by board.mk, default to port 0 -#ifndef BOARD_DEVICE_RHPORT_NUM - #define BOARD_DEVICE_RHPORT_NUM 0 +#ifndef BOARD_TUD_RHPORT + #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk // Default to max (auto) speed for MCU with internal HighSpeed PHY -#ifndef BOARD_DEVICE_RHPORT_SPEED - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED +#ifndef BOARD_TUD_MAX_SPEED + #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk -#if BOARD_DEVICE_RHPORT_NUM == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) -#elif BOARD_DEVICE_RHPORT_NUM == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#if BOARD_TUD_RHPORT == 0 + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) +#elif BOARD_TUD_RHPORT == 1 + #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) #else #error "Incorrect RHPort configuration" #endif diff --git a/examples/device/webusb_serial/src/tusb_config.h b/examples/device/webusb_serial/src/tusb_config.h index f5e4694e3..eab1d6387 100644 --- a/examples/device/webusb_serial/src/tusb_config.h +++ b/examples/device/webusb_serial/src/tusb_config.h @@ -40,21 +40,21 @@ #endif // RHPort number used for device can be defined by board.mk, default to port 0 -#ifndef BOARD_DEVICE_RHPORT_NUM - #define BOARD_DEVICE_RHPORT_NUM 0 +#ifndef BOARD_TUD_RHPORT + #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk // Default to max (auto) speed for MCU with internal HighSpeed PHY -#ifndef BOARD_DEVICE_RHPORT_SPEED - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_DEFAULT_SPEED +#ifndef BOARD_TUD_MAX_SPEED + #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif // Device mode with rhport and speed defined by board.mk -#if BOARD_DEVICE_RHPORT_NUM == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) -#elif BOARD_DEVICE_RHPORT_NUM == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#if BOARD_TUD_RHPORT == 0 + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) +#elif BOARD_TUD_RHPORT == 1 + #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) #else #error "Incorrect RHPort configuration" #endif diff --git a/examples/dual/host_hid_to_device_cdc/src/tusb_config.h b/examples/dual/host_hid_to_device_cdc/src/tusb_config.h index 0fa4899a9..9a8f31da0 100644 --- a/examples/dual/host_hid_to_device_cdc/src/tusb_config.h +++ b/examples/dual/host_hid_to_device_cdc/src/tusb_config.h @@ -40,13 +40,13 @@ #endif // RHPort number used for device can be defined by board.mk, default to port 0 -#ifndef BOARD_DEVICE_RHPORT_NUM - #define BOARD_DEVICE_RHPORT_NUM 0 +#ifndef BOARD_TUD_RHPORT + #define BOARD_TUD_RHPORT 0 #endif // RHPort number used for device can be defined by board.mk, default to port 1 -#ifndef BOARD_HOST_RHPORT_NUM - #define BOARD_HOST_RHPORT_NUM 1 +#ifndef BOARD_TUH_RHPORT + #define BOARD_TUH_RHPORT 1 #endif // Use raspberry pio-usb for host @@ -54,42 +54,42 @@ // RHPort max operational speed can defined by board.mk // Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed -#ifndef BOARD_DEVICE_RHPORT_SPEED +#ifndef BOARD_TUD_MAX_SPEED #if TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX, OPT_MCU_MIMXRT10XX, OPT_MCU_NUC505) ||\ TU_CHECK_MCU(OPT_MCU_CXD56, OPT_MCU_SAMX7X, OPT_MCU_BCM2711) ||\ TU_CHECK_MCU(OPT_MCU_FT90X, OPT_MCU_FT93X) - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED + #define BOARD_TUD_MAX_SPEED OPT_MODE_HIGH_SPEED #else - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED + #define BOARD_TUD_MAX_SPEED OPT_MODE_FULL_SPEED #endif #endif // RHPort max operational speed can defined by board.mk // Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed -#ifndef BOARD_HOST_RHPORT_SPEED +#ifndef BOARD_TUH_MAX_SPEED #if TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX, OPT_MCU_MIMXRT10XX, OPT_MCU_NUC505) ||\ TU_CHECK_MCU(OPT_MCU_CXD56, OPT_MCU_SAMX7X, OPT_MCU_BCM2711) ||\ TU_CHECK_MCU(OPT_MCU_FT90X, OPT_MCU_FT93X) - #define BOARD_HOST_RHPORT_SPEED OPT_MODE_HIGH_SPEED + #define BOARD_TUH_MAX_SPEED OPT_MODE_HIGH_SPEED #else - #define BOARD_HOST_RHPORT_SPEED OPT_MODE_FULL_SPEED + #define BOARD_TUH_MAX_SPEED OPT_MODE_FULL_SPEED #endif #endif // Device mode with rhport and speed defined by board.mk -#if BOARD_DEVICE_RHPORT_NUM == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) -#elif BOARD_DEVICE_RHPORT_NUM == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#if BOARD_TUD_RHPORT == 0 + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) +#elif BOARD_TUD_RHPORT == 1 + #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) #else #error "Incorrect RHPort configuration" #endif // Device mode with rhport and speed defined by board.mk -#if BOARD_HOST_RHPORT_NUM == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | BOARD_HOST_RHPORT_SPEED) -#elif BOARD_HOST_RHPORT_NUM == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_HOST | BOARD_HOST_RHPORT_SPEED) +#if BOARD_TUH_RHPORT == 0 + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | BOARD_TUH_MAX_SPEED) +#elif BOARD_TUH_RHPORT == 1 + #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_HOST | BOARD_TUH_MAX_SPEED) #else #error "Incorrect RHPort configuration" #endif diff --git a/hw/bsp/imxrt/boards/mimxrt1060_evk/board.mk b/hw/bsp/imxrt/boards/mimxrt1060_evk/board.mk index b14b2a6b9..d21063c99 100644 --- a/hw/bsp/imxrt/boards/mimxrt1060_evk/board.mk +++ b/hw/bsp/imxrt/boards/mimxrt1060_evk/board.mk @@ -7,8 +7,8 @@ JLINK_DEVICE = MIMXRT1062xxx6A # For flash-pyocd target PYOCD_TARGET = mimxrt1060 -BOARD_DEVICE_RHPORT_NUM = 1 -BOARD_HOST_RHPORT_NUM = 0 +BOARD_TUD_RHPORT = 1 +BOARD_TUH_RHPORT = 0 # flash using pyocd flash: flash-pyocd diff --git a/hw/bsp/imxrt/boards/mimxrt1064_evk/board.mk b/hw/bsp/imxrt/boards/mimxrt1064_evk/board.mk index 2b479719f..00b574c52 100644 --- a/hw/bsp/imxrt/boards/mimxrt1064_evk/board.mk +++ b/hw/bsp/imxrt/boards/mimxrt1064_evk/board.mk @@ -7,8 +7,8 @@ JLINK_DEVICE = MIMXRT1064xxx6A # For flash-pyocd target PYOCD_TARGET = mimxrt1064 -BOARD_DEVICE_RHPORT_NUM = 1 -BOARD_HOST_RHPORT_NUM = 0 +BOARD_TUD_RHPORT = 1 +BOARD_TUH_RHPORT = 0 # flash using pyocd flash: flash-pyocd diff --git a/hw/bsp/imxrt/family.mk b/hw/bsp/imxrt/family.mk index 0bf4a0d15..c81e67eb6 100644 --- a/hw/bsp/imxrt/family.mk +++ b/hw/bsp/imxrt/family.mk @@ -15,11 +15,11 @@ CFLAGS += \ -DXIP_BOOT_HEADER_ENABLE=1 \ -DCFG_TUSB_MCU=OPT_MCU_MIMXRT10XX -ifdef BOARD_DEVICE_RHPORT_NUM -CFLAGS += -DBOARD_DEVICE_RHPORT_NUM=$(BOARD_DEVICE_RHPORT_NUM) +ifdef BOARD_TUD_RHPORT +CFLAGS += -DBOARD_TUD_RHPORT=$(BOARD_TUD_RHPORT) endif -ifdef BOARD_HOST_RHPORT_NUM -CFLAGS += -DBOARD_HOST_RHPORT_NUM=$(BOARD_HOST_RHPORT_NUM) +ifdef BOARD_TUH_RHPORT +CFLAGS += -DBOARD_TUH_RHPORT=$(BOARD_TUH_RHPORT) endif # mcu driver cause following warnings diff --git a/hw/bsp/lpc54/family.mk b/hw/bsp/lpc54/family.mk index 600df6fd0..39111d1ad 100644 --- a/hw/bsp/lpc54/family.mk +++ b/hw/bsp/lpc54/family.mk @@ -15,7 +15,7 @@ CFLAGS += \ ifeq ($(PORT), 1) $(info "PORT1 High Speed") - CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED + CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED # LPC55 Highspeed Port1 can only write to USB_SRAM region CFLAGS += -DCFG_TUSB_MEM_SECTION='__attribute__((section("m_usb_global")))' diff --git a/hw/bsp/lpc55/family.mk b/hw/bsp/lpc55/family.mk index 4e8d65ce9..1af1d076e 100644 --- a/hw/bsp/lpc55/family.mk +++ b/hw/bsp/lpc55/family.mk @@ -16,11 +16,11 @@ CFLAGS += \ -mfpu=fpv5-sp-d16 \ -DCFG_TUSB_MCU=OPT_MCU_LPC55XX \ -DCFG_TUSB_MEM_ALIGN='__attribute__((aligned(64)))' \ - -DBOARD_DEVICE_RHPORT_NUM=$(PORT) + -DBOARD_TUD_RHPORT=$(PORT) ifeq ($(PORT), 1) $(info "PORT1 High Speed") - CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED + CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED # LPC55 Highspeed Port1 can only write to USB_SRAM region CFLAGS += -DCFG_TUSB_MEM_SECTION='__attribute__((section("m_usb_global")))' diff --git a/hw/bsp/stm32f7/family.c b/hw/bsp/stm32f7/family.c index 14e3b2fd9..425e6e1bc 100644 --- a/hw/bsp/stm32f7/family.c +++ b/hw/bsp/stm32f7/family.c @@ -125,7 +125,7 @@ void board_init(void) UartHandle.Init.OverSampling = UART_OVERSAMPLING_16; HAL_UART_Init(&UartHandle); -#if BOARD_DEVICE_RHPORT_NUM == 0 +#if BOARD_TUD_RHPORT == 0 // OTG_FS /* Configure DM DP Pins */ @@ -258,7 +258,7 @@ void board_init(void) USB_OTG_HS->GUSBCFG &= ~USB_OTG_GUSBCFG_FHMOD; USB_OTG_HS->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD; -#endif // BOARD_DEVICE_RHPORT_NUM +#endif // BOARD_TUD_RHPORT } diff --git a/hw/bsp/stm32f7/family.mk b/hw/bsp/stm32f7/family.mk index 8482e6dd2..b8a5d7ead 100644 --- a/hw/bsp/stm32f7/family.mk +++ b/hw/bsp/stm32f7/family.mk @@ -16,14 +16,14 @@ CFLAGS += \ -mfpu=fpv5-d16 \ -nostdlib -nostartfiles \ -DCFG_TUSB_MCU=OPT_MCU_STM32F7 \ - -DBOARD_DEVICE_RHPORT_NUM=$(PORT) + -DBOARD_TUD_RHPORT=$(PORT) ifeq ($(PORT), 1) ifeq ($(SPEED), high) - CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED + CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED $(info "Using OTG_HS in HighSpeed mode") else - CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_FULL_SPEED + CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED $(info "Using OTG_HS in FullSpeed mode") endif else diff --git a/hw/bsp/stm32h7/family.c b/hw/bsp/stm32h7/family.c index 84976b4e4..3964f427a 100644 --- a/hw/bsp/stm32h7/family.c +++ b/hw/bsp/stm32h7/family.c @@ -122,7 +122,7 @@ void board_init(void) UartHandle.Init.OverSampling = UART_OVERSAMPLING_16; HAL_UART_Init(&UartHandle); -#if BOARD_DEVICE_RHPORT_NUM == 0 +#if BOARD_TUD_RHPORT == 0 // Despite being call USB2_OTG // OTG_FS is marked as RHPort0 by TinyUSB to be consistent across stm32 port // PA9 VUSB, PA10 ID, PA11 DM, PA12 DP @@ -166,7 +166,7 @@ void board_init(void) USB_OTG_FS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL; #endif // vbus sense -#elif BOARD_DEVICE_RHPORT_NUM == 1 +#elif BOARD_TUD_RHPORT == 1 // Despite being call USB2_OTG // OTG_HS is marked as RHPort1 by TinyUSB to be consistent across stm32 port diff --git a/hw/bsp/stm32h7/family.mk b/hw/bsp/stm32h7/family.mk index 096d04d0c..a1cd93b27 100644 --- a/hw/bsp/stm32h7/family.mk +++ b/hw/bsp/stm32h7/family.mk @@ -16,14 +16,14 @@ CFLAGS += \ -mfpu=fpv5-d16 \ -nostdlib -nostartfiles \ -DCFG_TUSB_MCU=OPT_MCU_STM32H7 \ - -DBOARD_DEVICE_RHPORT_NUM=$(PORT) + -DBOARD_TUD_RHPORT=$(PORT) ifeq ($(PORT), 1) ifeq ($(SPEED), high) - CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED + CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED $(info "Using OTG_HS in HighSpeed mode") else - CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_FULL_SPEED + CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED $(info "Using OTG_HS in FullSpeed mode") endif else diff --git a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c index 3c3cb63b8..7a65cf5d0 100644 --- a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c +++ b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c @@ -239,12 +239,12 @@ static void _dcd_ft90x_attach(void) CRITICAL_SECTION_BEGIN // Turn off the device enable bit. -#if BOARD_DEVICE_RHPORT_SPEED == OPT_MODE_HIGH_SPEED +#if BOARD_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED USBD_REG(fctrl) = 0; -#else // BOARD_DEVICE_RHPORT_SPEED == OPT_MODE_FULL_SPEED +#else // BOARD_TUD_MAX_SPEED == OPT_MODE_FULL_SPEED //Set the full speed only bit if required. USBD_REG(fctrl) = MASK_USBD_FCTRL_MODE_FS_ONLY; -#endif // BOARD_DEVICE_RHPORT_SPEED +#endif // BOARD_TUD_MAX_SPEED // Clear first reset and suspend interrupts. do @@ -291,7 +291,7 @@ static void _dcd_ft90x_detach(void) delayms(1); // Disable USB PHY - dcd_disconnect(BOARD_DEVICE_RHPORT_NUM); + dcd_disconnect(BOARD_TUD_RHPORT); delayms(1); // Disable Chip USB device clock/PM configuration. @@ -323,7 +323,7 @@ static void _ft90x_usb_speed(void) delayus(200); } -#if BOARD_DEVICE_RHPORT_SPEED == OPT_MODE_HIGH_SPEED +#if BOARD_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED /* Detect high or full speed */ fctrl_val = MASK_USBD_FCTRL_USB_DEV_EN; @@ -347,11 +347,11 @@ static void _ft90x_usb_speed(void) delayus(125 + 5); _speed = (USBD_REG(cmif) & MASK_USBD_CMIF_SOFIRQ) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL; - dcd_event_bus_reset(BOARD_DEVICE_RHPORT_NUM, _speed, true); + dcd_event_bus_reset(BOARD_TUD_RHPORT, _speed, true); #endif /* !__FT930__ */ -#else // BOARD_DEVICE_RHPORT_SPEED == OPT_MODE_FULL_SPEED +#else // BOARD_TUD_MAX_SPEED == OPT_MODE_FULL_SPEED /* User force set to full speed */ _speed = TUSB_SPEED_FULL; @@ -364,10 +364,10 @@ static void _ft90x_usb_speed(void) } #endif USBD_REG(fctrl) = fctrl_val; - dcd_event_bus_reset(BOARD_DEVICE_RHPORT_NUM, _speed, true); + dcd_event_bus_reset(BOARD_TUD_RHPORT, _speed, true); return; -#endif // BOARD_DEVICE_RHPORT_SPEED +#endif // BOARD_TUD_MAX_SPEED } // Send a buffer to the USB IN FIFO. @@ -899,7 +899,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) void _ft90x_usbd_ISR(void) { - tud_int_handler(BOARD_DEVICE_RHPORT_NUM); // Resolves to dcd_int_handler(). + tud_int_handler(BOARD_TUD_RHPORT); // Resolves to dcd_int_handler(). } void dcd_int_handler(uint8_t rhport) @@ -937,19 +937,19 @@ void dcd_int_handler(uint8_t rhport) { // Reset endpoints to default state. _ft90x_reset_edpts(); - dcd_event_bus_reset(BOARD_DEVICE_RHPORT_NUM, _speed, true); + dcd_event_bus_reset(BOARD_TUD_RHPORT, _speed, true); } if (cmif & MASK_USBD_CMIF_SUSIRQ) //Handle Suspend interrupt { - dcd_event_bus_signal(BOARD_DEVICE_RHPORT_NUM, DCD_EVENT_SUSPEND, true); + dcd_event_bus_signal(BOARD_TUD_RHPORT, DCD_EVENT_SUSPEND, true); } if (cmif & MASK_USBD_CMIF_RESIRQ) //Handle Resume interrupt { - dcd_event_bus_signal(BOARD_DEVICE_RHPORT_NUM, DCD_EVENT_RESUME, true); + dcd_event_bus_signal(BOARD_TUD_RHPORT, DCD_EVENT_RESUME, true); } if (cmif & MASK_USBD_CMIF_SOFIRQ) //Handle SOF interrupt { - dcd_event_bus_signal(BOARD_DEVICE_RHPORT_NUM, DCD_EVENT_SOF, true); + dcd_event_bus_signal(BOARD_TUD_RHPORT, DCD_EVENT_SOF, true); } } // Handle endpoint interrupts. @@ -980,7 +980,7 @@ void dcd_int_handler(uint8_t rhport) _ft90x_dusb_out(USBD_EP_0, (uint8_t *)_ft90x_setup_packet, sizeof(USB_device_request)); // Send the packet to tinyusb. - dcd_event_setup_received(BOARD_DEVICE_RHPORT_NUM, _ft90x_setup_packet, true); + dcd_event_setup_received(BOARD_TUD_RHPORT, _ft90x_setup_packet, true); // Clear the interrupt that signals a SETUP packet is received. USBD_EP_SR_REG(USBD_EP_0) = (MASK_USBD_EP0SR_SETUP); @@ -1002,7 +1002,7 @@ void dcd_int_handler(uint8_t rhport) xfer_bytes = _ft90x_edpt_xfer_out(USBD_EP_0, (uint8_t *)ep_xfer[USBD_EP_0].buff_ptr, xfer_bytes); } // Now signal completion of data packet. - dcd_event_xfer_complete(BOARD_DEVICE_RHPORT_NUM, (ep_xfer[USBD_EP_0].dir ? TUSB_DIR_IN_MASK : 0), xfer_bytes, XFER_RESULT_SUCCESS, true); + dcd_event_xfer_complete(BOARD_TUD_RHPORT, (ep_xfer[USBD_EP_0].dir ? TUSB_DIR_IN_MASK : 0), xfer_bytes, XFER_RESULT_SUCCESS, true); // Allow new transfers on the control endpoint. ep_xfer[USBD_EP_0].valid = 0; @@ -1059,7 +1059,7 @@ void dcd_int_handler(uint8_t rhport) if (ep_xfer[ep_number].remain_size == 0) { // Signal tinyUSB. - dcd_event_xfer_complete(BOARD_DEVICE_RHPORT_NUM, ep_number | ep_dirmask, ep_xfer[ep_number].total_size, XFER_RESULT_SUCCESS, true); + dcd_event_xfer_complete(BOARD_TUD_RHPORT, ep_number | ep_dirmask, ep_xfer[ep_number].total_size, XFER_RESULT_SUCCESS, true); // Allow new transfers on this endpoint. ep_xfer[ep_number].valid = 0; @@ -1084,21 +1084,21 @@ void ft90x_usbd_pm_ISR(void) { // Signal connection interrupt SYS->PMCFG_H = MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND; - dcd_event_bus_signal(BOARD_DEVICE_RHPORT_NUM, DCD_EVENT_RESUME, true); + dcd_event_bus_signal(BOARD_TUD_RHPORT, DCD_EVENT_RESUME, true); } if (pmcfg & MASK_SYS_PMCFG_DEV_DIS_DEV) { // Signal disconnection interrupt SYS->PMCFG_H = MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND; - dcd_event_bus_signal(BOARD_DEVICE_RHPORT_NUM, DCD_EVENT_UNPLUGGED, true); + dcd_event_bus_signal(BOARD_TUD_RHPORT, DCD_EVENT_UNPLUGGED, true); } if (pmcfg & MASK_SYS_PMCFG_HOST_RST_DEV) { // Signal Host Reset interrupt SYS->PMCFG_H = MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND; - dcd_event_bus_signal(BOARD_DEVICE_RHPORT_NUM, DCD_EVENT_BUS_RESET, true); + dcd_event_bus_signal(BOARD_TUD_RHPORT, DCD_EVENT_BUS_RESET, true); } if (pmcfg & MASK_SYS_PMCFG_HOST_RESUME_DEV) @@ -1109,7 +1109,7 @@ void ft90x_usbd_pm_ISR(void) { // If we are driving K-state on Device USB port; // We must maintain the 1ms requirement before resuming the phy - dcd_event_bus_signal(BOARD_DEVICE_RHPORT_NUM, DCD_EVENT_RESUME, true); + dcd_event_bus_signal(BOARD_TUD_RHPORT, DCD_EVENT_RESUME, true); } } } diff --git a/src/tusb_option.h b/src/tusb_option.h index 3b054fc78..ce22a8a6a 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -221,7 +221,9 @@ typedef int make_iso_compilers_happy ; #define TUD_OPT_RHPORT -1 #endif +#ifndef CFG_TUD_ENABLED #define CFG_TUD_ENABLED (TUD_RHPORT_MODE & OPT_MODE_DEVICE) +#endif #if CFG_TUD_ENABLED #define TUD_OPT_HIGH_SPEED ((TUD_RHPORT_MODE & OPT_MODE_SPEED_MASK) ? (TUD_RHPORT_MODE & OPT_MODE_HIGH_SPEED) : (TUP_RHPORT_HIGHSPEED & (1 << TUD_OPT_RHPORT))) From 8b9cf152a0dedda573fb3374d8c873dce4b883d1 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 2 Jun 2022 16:51:17 +0700 Subject: [PATCH 357/504] rhport argument in usbd_ API() is not used (always use the initialized port) remove the usage of TUD_OPT_RHPORT in class driver --- examples/device/cdc_msc/src/tusb_config.h | 31 ++++----------- hw/bsp/lpc18/family.c | 35 +++++++++++------ src/class/bth/bth_device.c | 8 ++-- src/class/cdc/cdc_device.c | 4 +- src/class/hid/hid_device.c | 7 ++-- src/class/midi/midi_device.c | 4 +- src/class/net/ecm_rndis_device.c | 10 +++-- src/class/net/ncm_device.c | 9 +++-- src/class/vendor/vendor_device.c | 12 ++++-- src/common/tusb_mcu.h | 29 ++++++-------- src/device/usbd.c | 14 ++++++- src/device/usbd_pvt.h | 1 + src/tusb_option.h | 48 ++++++++++++----------- 13 files changed, 116 insertions(+), 96 deletions(-) diff --git a/examples/device/cdc_msc/src/tusb_config.h b/examples/device/cdc_msc/src/tusb_config.h index 3849ad4d0..363da88d7 100644 --- a/examples/device/cdc_msc/src/tusb_config.h +++ b/examples/device/cdc_msc/src/tusb_config.h @@ -41,7 +41,12 @@ // This example doesn't use an RTOS #ifndef CFG_TUSB_OS -#define CFG_TUSB_OS OPT_OS_NONE + #define CFG_TUSB_OS OPT_OS_NONE +#endif + +// CFG_TUSB_DEBUG is defined by compiler in DEBUG build +#ifndef CFG_TUSB_DEBUG + #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack @@ -53,34 +58,14 @@ #endif // RHPort max operational speed can defined by board.mk -// Default to max (auto) speed for MCU with internal HighSpeed PHY #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif -// Device mode with rhport and speed defined by board.mk -#if BOARD_TUD_RHPORT == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#elif BOARD_TUD_RHPORT == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#else - #error "Incorrect RHPort configuration" -#endif +// Default is max speed that hardware controller could support with on-chip PHY +#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED - -// Device max speed, default is max speed that hardware controller could support without external PHY -// BOARD_TUD_MAX_SPEED can be used to change value (e.g for board features external PHY). -#ifdef BOARD_TUD_MAX_SPEED - #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED -#else - #define CFG_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED -#endif - - -// CFG_TUSB_DEBUG is defined by compiler in DEBUG build -// #define CFG_TUSB_DEBUG 0 - /* 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. diff --git a/hw/bsp/lpc18/family.c b/hw/bsp/lpc18/family.c index d74ebcd33..a59b6e89d 100644 --- a/hw/bsp/lpc18/family.c +++ b/hw/bsp/lpc18/family.c @@ -28,28 +28,40 @@ #include "bsp/board.h" #include "board.h" +#ifdef BOARD_TUD_RHPORT + #define PORT_SUPPORT_DEVICE(_n) (BOARD_TUD_RHPORT == _n) +#else + #define PORT_SUPPORT_DEVICE(_n) 0 +#endif + +#ifdef BOARD_TUH_RHPORT + #define PORT_SUPPORT_HOST(_n) (BOARD_TUH_RHPORT == _n) +#else + #define PORT_SUPPORT_HOST(_n) 0 +#endif + //--------------------------------------------------------------------+ // USB Interrupt Handler //--------------------------------------------------------------------+ void USB0_IRQHandler(void) { - #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST - tuh_int_handler(0); + #if PORT_SUPPORT_DEVICE(0) + tud_int_handler(0); #endif - #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE - tud_int_handler(0); + #if PORT_SUPPORT_HOST(0) + tuh_int_handler(0); #endif } void USB1_IRQHandler(void) { - #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST - tuh_int_handler(1); + #if PORT_SUPPORT_DEVICE(1) + tud_int_handler(1); #endif - #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE - tud_int_handler(1); + #if PORT_SUPPORT_HOST(1) + tuh_int_handler(1); #endif } @@ -84,7 +96,8 @@ void board_init(void) SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) - //NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + NVIC_SetPriority(USB1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #endif Chip_GPIO_Init(LPC_GPIO_PORT); @@ -102,11 +115,11 @@ void board_init(void) Chip_UART_TXEnable(UART_DEV); //------------- USB -------------// -#if CFG_TUSB_RHPORT0_MODE +#if PORT_SUPPORT_DEVICE(0) || PORT_SUPPORT_HOST(0) Chip_USB0_Init(); #endif -#if CFG_TUSB_RHPORT1_MODE +#if PORT_SUPPORT_DEVICE(1) || PORT_SUPPORT_HOST(1) Chip_USB1_Init(); #endif } diff --git a/src/class/bth/bth_device.c b/src/class/bth/bth_device.c index f40bfbd0d..f96bb3552 100755 --- a/src/class/bth/bth_device.c +++ b/src/class/bth/bth_device.c @@ -59,10 +59,12 @@ CFG_TUSB_MEM_SECTION btd_interface_t _btd_itf; static bool bt_tx_data(uint8_t ep, void *data, uint16_t len) { - // skip if previous transfer not complete - TU_VERIFY(!usbd_edpt_busy(TUD_OPT_RHPORT, ep)); + uint8_t const rhport = 0; - TU_ASSERT(usbd_edpt_xfer(TUD_OPT_RHPORT, ep, data, len)); + // skip if previous transfer not complete + TU_VERIFY(!usbd_edpt_busy(rhport, ep)); + + TU_ASSERT(usbd_edpt_xfer(rhport, ep, data, len)); return true; } diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 2b9b84e7a..7aa7a4860 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -82,7 +82,7 @@ CFG_TUSB_MEM_SECTION static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; static bool _prep_out_transaction (cdcd_interface_t* p_cdc) { - uint8_t const rhport = TUD_OPT_RHPORT; + uint8_t const rhport = 0; uint16_t available = tu_fifo_remaining(&p_cdc->rx_ff); // Prepare for incoming data but only allow what we can store in the ring buffer. @@ -189,7 +189,7 @@ uint32_t tud_cdc_n_write_flush (uint8_t itf) // No data to send if ( !tu_fifo_count(&p_cdc->tx_ff) ) return 0; - uint8_t const rhport = TUD_OPT_RHPORT; + uint8_t const rhport = 0; // Claim the endpoint TU_VERIFY( usbd_edpt_claim(rhport, p_cdc->ep_in), 0 ); diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 562ca7f36..cdf155e1c 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -76,8 +76,9 @@ static inline uint8_t get_index_by_itfnum(uint8_t itf_num) //--------------------------------------------------------------------+ bool tud_hid_n_ready(uint8_t instance) { + uint8_t const rhport = 0; uint8_t const ep_in = _hidd_itf[instance].ep_in; - return tud_ready() && (ep_in != 0) && !usbd_edpt_busy(TUD_OPT_RHPORT, ep_in); + return tud_ready() && (ep_in != 0) && !usbd_edpt_busy(rhport, ep_in); } bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, uint8_t len) @@ -103,7 +104,7 @@ bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, u memcpy(p_hid->epin_buf, report, len); } - return usbd_edpt_xfer(TUD_OPT_RHPORT, p_hid->ep_in, p_hid->epin_buf, len); + return usbd_edpt_xfer(rhport, p_hid->ep_in, p_hid->epin_buf, len); } uint8_t tud_hid_n_interface_protocol(uint8_t instance) @@ -172,7 +173,7 @@ bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, //--------------------------------------------------------------------+ void hidd_init(void) { - hidd_reset(TUD_OPT_RHPORT); + hidd_reset(0); } void hidd_reset(uint8_t rhport) diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index 2ce1376bd..28e6a92d2 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -92,7 +92,7 @@ bool tud_midi_n_mounted (uint8_t itf) static void _prep_out_transaction (midid_interface_t* p_midi) { - uint8_t const rhport = TUD_OPT_RHPORT; + uint8_t const rhport = 0; uint16_t available = tu_fifo_remaining(&p_midi->rx_ff); // Prepare for incoming data but only allow what we can store in the ring buffer. @@ -219,7 +219,7 @@ static uint32_t write_flush(midid_interface_t* midi) // No data to send if ( !tu_fifo_count(&midi->tx_ff) ) return 0; - uint8_t const rhport = TUD_OPT_RHPORT; + uint8_t const rhport = 0; // skip if previous transfer not complete TU_VERIFY( usbd_edpt_claim(rhport, midi->ep_in), 0 ); diff --git a/src/class/net/ecm_rndis_device.c b/src/class/net/ecm_rndis_device.c index f6b318058..d85a3f778 100644 --- a/src/class/net/ecm_rndis_device.c +++ b/src/class/net/ecm_rndis_device.c @@ -108,20 +108,22 @@ static bool can_xmit; void tud_network_recv_renew(void) { - usbd_edpt_xfer(TUD_OPT_RHPORT, _netd_itf.ep_out, received, sizeof(received)); + usbd_edpt_xfer(0, _netd_itf.ep_out, received, sizeof(received)); } static void do_in_xfer(uint8_t *buf, uint16_t len) { can_xmit = false; - usbd_edpt_xfer(TUD_OPT_RHPORT, _netd_itf.ep_in, buf, len); + usbd_edpt_xfer(0, _netd_itf.ep_in, buf, len); } void netd_report(uint8_t *buf, uint16_t len) { + uint8_t const rhport = 0; + // skip if previous report not yet acknowledged by host - if ( usbd_edpt_busy(TUD_OPT_RHPORT, _netd_itf.ep_notif) ) return; - usbd_edpt_xfer(TUD_OPT_RHPORT, _netd_itf.ep_notif, buf, len); + if ( usbd_edpt_busy(rhport, _netd_itf.ep_notif) ) return; + usbd_edpt_xfer(rhport, _netd_itf.ep_notif, buf, len); } //--------------------------------------------------------------------+ diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 1987337f8..00892b49c 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -188,7 +188,7 @@ static void ncm_start_tx(void) { ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramLength = 0; // Kick off an endpoint transfer - usbd_edpt_xfer(TUD_OPT_RHPORT, ncm_interface.ep_in, ntb->data, ntb_length); + usbd_edpt_xfer(0, ncm_interface.ep_in, ntb->data, ntb_length); ncm_interface.transferring = true; // Swap to the other NTB and clear it out @@ -229,7 +229,7 @@ void tud_network_recv_renew(void) { if (!ncm_interface.num_datagrams) { - usbd_edpt_xfer(TUD_OPT_RHPORT, ncm_interface.ep_out, receive_ntb, sizeof(receive_ntb)); + usbd_edpt_xfer(0, ncm_interface.ep_out, receive_ntb, sizeof(receive_ntb)); return; } @@ -316,14 +316,15 @@ uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint1 static void ncm_report(void) { + uint8_t const rhport = 0; if (ncm_interface.report_state == REPORT_SPEED) { ncm_notify_speed_change.header.wIndex = ncm_interface.itf_num; - usbd_edpt_xfer(TUD_OPT_RHPORT, ncm_interface.ep_notif, (uint8_t *) &ncm_notify_speed_change, sizeof(ncm_notify_speed_change)); + usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t *) &ncm_notify_speed_change, sizeof(ncm_notify_speed_change)); ncm_interface.report_state = REPORT_CONNECTED; ncm_interface.report_pending = true; } else if (ncm_interface.report_state == REPORT_CONNECTED) { ncm_notify_connected.header.wIndex = ncm_interface.itf_num; - usbd_edpt_xfer(TUD_OPT_RHPORT, ncm_interface.ep_notif, (uint8_t *) &ncm_notify_connected, sizeof(ncm_notify_connected)); + usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t *) &ncm_notify_connected, sizeof(ncm_notify_connected)); ncm_interface.report_state = REPORT_DONE; ncm_interface.report_pending = true; } diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index 6e3ceb1c4..c7dfa0062 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -84,14 +84,16 @@ bool tud_vendor_n_peek(uint8_t itf, uint8_t* u8) //--------------------------------------------------------------------+ static void _prep_out_transaction (vendord_interface_t* p_itf) { + uint8_t const rhport = 0; + // skip if previous transfer not complete - if ( usbd_edpt_busy(TUD_OPT_RHPORT, p_itf->ep_out) ) return; + if ( usbd_edpt_busy(rhport, p_itf->ep_out) ) return; // Prepare for incoming data but only allow what we can store in the ring buffer. uint16_t max_read = tu_fifo_remaining(&p_itf->rx_ff); if ( max_read >= CFG_TUD_VENDOR_EPSIZE ) { - usbd_edpt_xfer(TUD_OPT_RHPORT, p_itf->ep_out, p_itf->epout_buf, CFG_TUD_VENDOR_EPSIZE); + usbd_edpt_xfer(rhport, p_itf->ep_out, p_itf->epout_buf, CFG_TUD_VENDOR_EPSIZE); } } @@ -115,13 +117,15 @@ void tud_vendor_n_read_flush (uint8_t itf) //--------------------------------------------------------------------+ static uint16_t maybe_transmit(vendord_interface_t* p_itf) { + uint8_t const rhport = 0; + // skip if previous transfer not complete - TU_VERIFY( !usbd_edpt_busy(TUD_OPT_RHPORT, p_itf->ep_in) ); + TU_VERIFY( !usbd_edpt_busy(rhport, p_itf->ep_in) ); uint16_t count = tu_fifo_read_n(&p_itf->tx_ff, p_itf->epin_buf, CFG_TUD_VENDOR_EPSIZE); if (count > 0) { - TU_ASSERT( usbd_edpt_xfer(TUD_OPT_RHPORT, p_itf->ep_in, p_itf->epin_buf, count) ); + TU_ASSERT( usbd_edpt_xfer(rhport, p_itf->ep_in, p_itf->epin_buf, count) ); } return count; } diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index c1cf2a810..383a8d686 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -45,8 +45,7 @@ * - ENDPOINT_MAX: max (logical) number of endpoint * - ENDPOINT_EXCLUSIVE_NUMBER: endpoint number with different direction IN and OUT aren't allowed, * e.g EP1 OUT & EP1 IN cannot exist together - * - RHPORT_HIGHSPEED: mask to indicate which port support highspeed mode (without external PHY) - * bit0 for port0 and so on. + * - RHPORT_HIGHSPEED: support highspeed with on-chip PHY */ //------------- NXP -------------// @@ -63,8 +62,7 @@ #define TUP_USBIP_EHCI #define TUP_DCD_ENDPOINT_MAX 6 - #define TUP_RHPORT_HIGHSPEED 0x01 // Port0 HS, Port1 FS - + #define TUP_RHPORT_HIGHSPEED 1 // Port0 HS, Port1 FS #elif TU_CHECK_MCU(OPT_MCU_LPC51UXX) #define TUP_DCD_ENDPOINT_MAX 5 @@ -82,8 +80,7 @@ #define TUP_USBIP_EHCI #define TUP_DCD_ENDPOINT_MAX 8 - #define TUP_RHPORT_HIGHSPEED 0x03 // Port0 HS, Port1 HS - + #define TUP_RHPORT_HIGHSPEED 1 // Port0 HS, Port1 HS #elif TU_CHECK_MCU(OPT_MCU_MKL25ZXX, OPT_MCU_K32L2BXX) #define TUP_DCD_ENDPOINT_MAX 16 @@ -107,7 +104,7 @@ #elif TU_CHECK_MCU(OPT_MCU_SAMX7X) #define TUP_DCD_ENDPOINT_MAX 10 - #define TUP_RHPORT_HIGHSPEED 0x01 + #define TUP_RHPORT_HIGHSPEED 1 #define TUP_DCD_ENDPOINT_EXCLUSIVE_NUMBER #elif TU_CHECK_MCU(OPT_MCU_PIC32MZ) @@ -155,7 +152,7 @@ // MCU with on-chip HS Phy #if defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F733xx) - #define TUP_RHPORT_HIGHSPEED 0x02 // Port 0: FS, Port 1: HS + #define TUP_RHPORT_HIGHSPEED 1 // Port0: FS, Port1: HS #endif #elif TU_CHECK_MCU(OPT_MCU_STM32H7) @@ -185,12 +182,12 @@ #endif #elif TU_CHECK_MCU(OPT_MCU_STM32WB) -#define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 //------------- Sony -------------// #elif TU_CHECK_MCU(OPT_MCU_CXD56) #define TUP_DCD_ENDPOINT_MAX 7 - #define TUP_RHPORT_HIGHSPEED 0x01 + #define TUP_RHPORT_HIGHSPEED 1 #define TUP_DCD_ENDPOINT_EXCLUSIVE_NUMBER //------------- TI -------------// @@ -213,7 +210,7 @@ #elif TU_CHECK_MCU(OPT_MCU_NUC505) #define TUP_DCD_ENDPOINT_MAX 12 - #define TUP_RHPORT_HIGHSPEED 0x01 + #define TUP_RHPORT_HIGHSPEED 1 //------------- Espressif -------------// #elif TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) @@ -228,7 +225,7 @@ #elif TU_CHECK_MCU(OPT_MCU_RP2040) #define TUP_DCD_ENDPOINT_MAX 16 - #define TU_ATTR_FAST_FUNC __attribute__((section(".time_critical.tinyusb"))) + #define TU_ATTR_FAST_FUNC __attribute__((section(".time_critical.tinyusb"))) //------------- Silabs -------------// #elif TU_CHECK_MCU(OPT_MCU_EFM32GG) @@ -248,7 +245,7 @@ #elif TU_CHECK_MCU(OPT_MCU_BCM2711, OPT_MCU_BCM2835, OPT_MCU_BCM2837) #define TUP_USBIP_DWC2 #define TUP_DCD_ENDPOINT_MAX 8 - #define TUP_RHPORT_HIGHSPEED 0x01 + #define TUP_RHPORT_HIGHSPEED 1 //------------- Broadcom -------------// #elif TU_CHECK_MCU(OPT_MCU_XMC4000) @@ -258,11 +255,11 @@ //------------- BridgeTek -------------// #elif TU_CHECK_MCU(OPT_MCU_FT90X) #define TUP_DCD_ENDPOINT_MAX 8 - #define TUP_RHPORT_HIGHSPEED 0x01 + #define TUP_RHPORT_HIGHSPEED 1 #elif TU_CHECK_MCU(OPT_MCU_FT93X) #define TUP_DCD_ENDPOINT_MAX 16 - #define TUP_RHPORT_HIGHSPEED 0x01 + #define TUP_RHPORT_HIGHSPEED 1 //------------ Allwinner -------------// #elif TU_CHECK_MCU(OPT_MCU_F1C100S) @@ -281,7 +278,7 @@ // Default to fullspeed if not defined #ifndef TUP_RHPORT_HIGHSPEED - #define TUP_RHPORT_HIGHSPEED 0x00 + #define TUP_RHPORT_HIGHSPEED 0 #endif // fast function, normally mean placing function in SRAM diff --git a/src/device/usbd.c b/src/device/usbd.c index fa75c0214..55e478a4e 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -428,7 +428,6 @@ bool tud_init (uint8_t rhport) dcd_init(rhport); dcd_int_enable(rhport); - return true; } @@ -1199,6 +1198,8 @@ void usbd_defer_func(osal_task_func_t func, void* param, bool in_isr) bool usbd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) { + rhport = _usbd_rhport; + TU_ASSERT(tu_edpt_number(desc_ep->bEndpointAddress) < CFG_TUD_ENDPPOINT_MAX); TU_ASSERT(tu_edpt_validate(desc_ep, (tusb_speed_t) _usbd_dev.speed)); @@ -1240,6 +1241,8 @@ bool usbd_edpt_release(uint8_t rhport, uint8_t ep_addr) bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) { + rhport = _usbd_rhport; + uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); @@ -1275,6 +1278,8 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t // into the USB buffer! bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) { + rhport = _usbd_rhport; + uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); @@ -1314,6 +1319,7 @@ bool usbd_edpt_busy(uint8_t rhport, uint8_t ep_addr) void usbd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { + rhport = _usbd_rhport; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); @@ -1330,6 +1336,8 @@ void usbd_edpt_stall(uint8_t rhport, uint8_t ep_addr) void usbd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { + rhport = _usbd_rhport; + uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); @@ -1361,6 +1369,8 @@ bool usbd_edpt_stalled(uint8_t rhport, uint8_t ep_addr) */ void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr) { + rhport = _usbd_rhport; + TU_ASSERT(dcd_edpt_close, /**/); TU_LOG2(" CLOSING Endpoint: 0x%02X\r\n", ep_addr); @@ -1377,6 +1387,8 @@ void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr) void usbd_sof_enable(uint8_t rhport, bool en) { + rhport = _usbd_rhport; + // TODO: Check needed if all drivers including the user sof_cb does not need an active SOF ISR any more. // Only if all drivers switched off SOF calls the SOF interrupt may be disabled dcd_sof_enable(rhport, en); diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index 603ffc936..17ebbfcd4 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -62,6 +62,7 @@ void usbd_int_set(bool enabled); //--------------------------------------------------------------------+ // USBD Endpoint API +// Note: rhport should be 0 since device stack only support 1 rhport for now //--------------------------------------------------------------------+ // Open an endpoint diff --git a/src/tusb_option.h b/src/tusb_option.h index ce22a8a6a..c198e4ef3 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -195,25 +195,21 @@ typedef int make_iso_compilers_happy ; #define OPT_MODE_HIGH_SPEED 0x0400 ///< High Speed #define OPT_MODE_SPEED_MASK 0xff00 -#ifndef CFG_TUSB_RHPORT0_MODE - #define CFG_TUSB_RHPORT0_MODE OPT_MODE_NONE -#endif - -#ifndef CFG_TUSB_RHPORT1_MODE - #define CFG_TUSB_RHPORT1_MODE OPT_MODE_NONE -#endif - -#if (((CFG_TUSB_RHPORT0_MODE) & OPT_MODE_HOST ) && ((CFG_TUSB_RHPORT1_MODE) & OPT_MODE_HOST )) || \ - (((CFG_TUSB_RHPORT0_MODE) & OPT_MODE_DEVICE) && ((CFG_TUSB_RHPORT1_MODE) & OPT_MODE_DEVICE)) - #error "TinyUSB currently does not support same modes on more than 1 roothub port" -#endif - //------------- Roothub as Device -------------// -#if (CFG_TUSB_RHPORT0_MODE) & OPT_MODE_DEVICE +//#ifndef CFG_TUSB_RHPORT0_MODE +// #define CFG_TUSB_RHPORT0_MODE OPT_MODE_NONE +//#endif +// +//#ifndef CFG_TUSB_RHPORT1_MODE +// #define CFG_TUSB_RHPORT1_MODE OPT_MODE_NONE +//#endif + + +#if defined(CFG_TUSB_RHPORT0_MODE) && ((CFG_TUSB_RHPORT0_MODE) & OPT_MODE_DEVICE) #define TUD_RHPORT_MODE (CFG_TUSB_RHPORT0_MODE) #define TUD_OPT_RHPORT 0 -#elif (CFG_TUSB_RHPORT1_MODE) & OPT_MODE_DEVICE +#elif defined(CFG_TUSB_RHPORT1_MODE) && ((CFG_TUSB_RHPORT1_MODE) & OPT_MODE_DEVICE) #define TUD_RHPORT_MODE (CFG_TUSB_RHPORT1_MODE) #define TUD_OPT_RHPORT 1 #else @@ -222,21 +218,24 @@ typedef int make_iso_compilers_happy ; #endif #ifndef CFG_TUD_ENABLED -#define CFG_TUD_ENABLED (TUD_RHPORT_MODE & OPT_MODE_DEVICE) + // fallback to use CFG_TUSB_RHPORTx_MODE + #define CFG_TUD_ENABLED (TUD_RHPORT_MODE & OPT_MODE_DEVICE) #endif -#if CFG_TUD_ENABLED - #define TUD_OPT_HIGH_SPEED ((TUD_RHPORT_MODE & OPT_MODE_SPEED_MASK) ? (TUD_RHPORT_MODE & OPT_MODE_HIGH_SPEED) : (TUP_RHPORT_HIGHSPEED & (1 << TUD_OPT_RHPORT))) -#else - #define TUD_OPT_HIGH_SPEED 0 +#ifndef CFG_TUD_MAX_SPEED + // fallback to use CFG_TUSB_RHPORTx_MODE + #define CFG_TUD_MAX_SPEED (TUD_RHPORT_MODE & OPT_MODE_SPEED_MASK) #endif +// highspeed support indicator +#define TUD_OPT_HIGH_SPEED (CFG_TUD_MAX_SPEED ? CFG_TUD_MAX_SPEED : TUP_RHPORT_HIGHSPEED) + //------------- Roothub as Host -------------// -#if (CFG_TUSB_RHPORT0_MODE) & OPT_MODE_HOST +#if defined(CFG_TUSB_RHPORT0_MODE) && ((CFG_TUSB_RHPORT0_MODE) & OPT_MODE_HOST) #define TUH_RHPORT_MODE (CFG_TUSB_RHPORT0_MODE) #define TUH_OPT_RHPORT 0 -#elif (CFG_TUSB_RHPORT1_MODE) & OPT_MODE_HOST +#elif defined(CFG_TUSB_RHPORT1_MODE) && ((CFG_TUSB_RHPORT1_MODE) & OPT_MODE_HOST) #define TUH_RHPORT_MODE (CFG_TUSB_RHPORT1_MODE) #define TUH_OPT_RHPORT 1 #else @@ -244,7 +243,10 @@ typedef int make_iso_compilers_happy ; #define TUH_OPT_RHPORT -1 #endif -#define CFG_TUH_ENABLED (TUH_RHPORT_MODE & OPT_MODE_HOST) +#ifndef CFG_TUH_ENABLED + // fallback to use CFG_TUSB_RHPORTx_MODE + #define CFG_TUH_ENABLED (TUH_RHPORT_MODE & OPT_MODE_HOST) +#endif // For backward compatible #define TUSB_OPT_DEVICE_ENABLED CFG_TUD_ENABLED From 8b37aa157911ff2cd470d090bb2e276ca57f5af4 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Wed, 1 Jun 2022 21:50:15 +0200 Subject: [PATCH 358/504] nrf5x: Fix DMA access There were two problems: - dma_running flag could be checked in USB interrupt (not set yet) then higher priority interrupt could start transfer, check dma_running (not set yet) set it to true start DMA; then when USB interrupt continues it starts another DMA that is not allowed - when DMA is started some registers can't be safely accessed, read can yield invalid values (SIZE.EPOUT, SIZE.EPISO) current implementation could start DMA for one OUT endpoint then check that another endpoint also has data and while DMA was not started right away, SIZE.EPOUT was copied already to MAXCNT register. Later on when DMA was started not all data was read from endpoint due to incorrect DMA size previously set. To prevent both cases dma_running is changed in atomic way. Only code that actually set this value to true starts DMA, code that tried and had dma_running flag already set simply defers DMA start to USB task. This eliminates also need to have mutex that was there to limit access to dma_running flag to one task only. transfer also now has started flag that is set only after dcd_edpt_xfer() sets up total_len and actua_len. Previously USB interrupt was disabled when total_len and actual_len were setup to prevent race condition when data arrived to ednpoint before transfer was setup was finished. --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 93 +++++++++++---------------- 1 file changed, 37 insertions(+), 56 deletions(-) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 430d8eded..efa30c60a 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -28,6 +28,7 @@ #if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_NRF5X +#include #include "nrf.h" #include "nrf_clock.h" #include "nrf_power.h" @@ -72,6 +73,7 @@ typedef struct // nRF will auto accept OUT packet after DMA is done // indicate packet is already ACK volatile bool data_received; + volatile bool started; // Set to true when data was transferred from RAM to ISO IN output buffer. // New data can be put in ISO IN output buffer after SOF. @@ -79,9 +81,6 @@ typedef struct } xfer_td_t; -static osal_mutex_def_t dcd_mutex_def; -static osal_mutex_t dcd_mutex; - // Data for managing dcd static struct { @@ -90,7 +89,7 @@ static struct xfer_td_t xfer[EP_CBI_COUNT + 1][2]; // nRF can only carry one DMA at a time, this is used to guard the access to EasyDMA - volatile bool dma_running; + atomic_bool dma_running; }_dcd; /*------------------------------------------------------------------*/ @@ -121,8 +120,6 @@ TU_ATTR_ALWAYS_INLINE static inline bool is_in_isr(void) // helper to start DMA static void start_dma(volatile uint32_t* reg_startep) { - _dcd.dma_running = true; - (*reg_startep) = 1; __ISB(); __DSB(); @@ -131,50 +128,18 @@ static void start_dma(volatile uint32_t* reg_startep) // Therefore dma_pending is corrected right away if ( (reg_startep == &NRF_USBD->TASKS_EP0STATUS) || (reg_startep == &NRF_USBD->TASKS_EP0RCVOUT) ) { - _dcd.dma_running = false; + atomic_flag_clear(&_dcd.dma_running); } } -// only 1 EasyDMA can be active at any time -// TODO use Cortex M4 LDREX and STREX command (atomic) to have better mutex access to EasyDMA -// since current implementation does not 100% guarded against race condition static void edpt_dma_start(volatile uint32_t* reg_startep) { - // Called in critical section i.e within USB ISR, or USB/Global interrupt disabled - if ( is_in_isr() || __get_PRIMASK() || !NVIC_GetEnableIRQ(USBD_IRQn) ) + if ( atomic_flag_test_and_set(&_dcd.dma_running) ) { - if (_dcd.dma_running) - { - //use usbd task to defer later - usbd_defer_func((osal_task_func_t) edpt_dma_start, (void*) (uintptr_t) reg_startep, true); - }else - { - start_dma(reg_startep); - } + usbd_defer_func((osal_task_func_t) edpt_dma_start, (void*) (uintptr_t) reg_startep, true); }else { - // Called in non-critical thread-mode, should be 99% of the time. - // Should be safe to blocking wait until previous DMA transfer complete - uint8_t const rhport = 0; - bool started = false; - osal_mutex_lock(dcd_mutex, OSAL_TIMEOUT_WAIT_FOREVER); - while(!started) - { - // LDREX/STREX may be needed in form of std atomic (required C11) or - // use osal mutex to guard against multiple core MCUs such as nRF53 - dcd_int_disable(rhport); - - if ( !_dcd.dma_running ) - { - start_dma(reg_startep); - started = true; - } - - dcd_int_enable(rhport); - - // osal_yield(); - } - osal_mutex_unlock(dcd_mutex); + start_dma(reg_startep); } } @@ -182,7 +147,7 @@ static void edpt_dma_start(volatile uint32_t* reg_startep) static void edpt_dma_end(void) { TU_ASSERT(_dcd.dma_running, ); - _dcd.dma_running = false; + atomic_flag_clear(&_dcd.dma_running); } // helper getting td @@ -191,12 +156,26 @@ static inline xfer_td_t* get_td(uint8_t epnum, uint8_t dir) return &_dcd.xfer[epnum][dir]; } +static void xact_out_dma(uint8_t epnum); +// Function wraps xact_out_dma which wants uint8_t while usbd_defer_func wants void (*)(void *) +static void xact_out_dma_wrapper(void *epnum) +{ + xact_out_dma((uint8_t)((uintptr_t)epnum)); +} + // Start DMA to move data from Endpoint -> RAM static void xact_out_dma(uint8_t epnum) { xfer_td_t* xfer = get_td(epnum, TUSB_DIR_OUT); uint32_t xact_len; + // DMA can't be active during read of SIZE.EPOUT or SIZE.ISOOUT, so try to lock, + // If already running deffer call regardless if it was called from ISR or task, + if ( atomic_flag_test_and_set(&_dcd.dma_running) ) + { + usbd_defer_func((osal_task_func_t)xact_out_dma_wrapper, (void *)(uint32_t)epnum, is_in_isr()); + return; + } if (epnum == EP_ISO_NUM) { xact_len = NRF_USBD->SIZE.ISOOUT; @@ -204,6 +183,7 @@ static void xact_out_dma(uint8_t epnum) if (xact_len & USBD_SIZE_ISOOUT_ZERO_Msk) { xact_len = 0; + atomic_flag_clear(&_dcd.dma_running); } else { @@ -211,7 +191,7 @@ static void xact_out_dma(uint8_t epnum) NRF_USBD->ISOOUT.PTR = (uint32_t) xfer->buffer; NRF_USBD->ISOOUT.MAXCNT = xact_len; - edpt_dma_start(&NRF_USBD->TASKS_STARTISOOUT); + start_dma(&NRF_USBD->TASKS_STARTISOOUT); } } else @@ -223,7 +203,7 @@ static void xact_out_dma(uint8_t epnum) NRF_USBD->EPOUT[epnum].PTR = (uint32_t) xfer->buffer; NRF_USBD->EPOUT[epnum].MAXCNT = xact_len; - edpt_dma_start(&NRF_USBD->TASKS_STARTEPOUT[epnum]); + start_dma(&NRF_USBD->TASKS_STARTEPOUT[epnum]); } } @@ -248,7 +228,6 @@ static void xact_in_dma(uint8_t epnum) void dcd_init (uint8_t rhport) { TU_LOG1("dcd init\r\n"); - dcd_mutex = osal_mutex_create(&dcd_mutex_def); (void) rhport; } @@ -471,17 +450,10 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t xfer_td_t* xfer = get_td(epnum, dir); - if (!is_in_isr()) { - osal_mutex_lock(dcd_mutex, OSAL_TIMEOUT_WAIT_FOREVER); - dcd_int_disable(rhport); - } + TU_ASSERT(!xfer->started); xfer->buffer = buffer; xfer->total_len = total_bytes; xfer->actual_len = 0; - if (!is_in_isr()) { - dcd_int_enable(rhport); - osal_mutex_unlock(dcd_mutex); - } // Control endpoint with zero-length packet and opposite direction to 1st request byte --> status stage bool const control_status = (epnum == 0 && total_bytes == 0 && dir != tu_edpt_dir(NRF_USBD->BMREQUESTTYPE)); @@ -496,13 +468,20 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t } else if ( dir == TUSB_DIR_OUT ) { + xfer->started = true; if ( epnum == 0 ) { // Accept next Control Out packet. TASKS_EP0RCVOUT also require EasyDMA edpt_dma_start(&NRF_USBD->TASKS_EP0RCVOUT); }else { - if ( xfer->data_received && xfer->total_len > xfer->actual_len) + // started just set, it could start DMA transfer if interrupt was trigger after this line + // code only needs to start transfer (from Endpoint to RAM) when data_received was set + // before started was set. If started is NOT set but data_received is, it means that + // current transfer was already finished and next data is already present in endpoint and + // can be consumed by future transfer + __ISB(); __DSB(); + if ( xfer->data_received && xfer->started ) { // Data is already received previously // start DMA to copy to SRAM @@ -804,7 +783,9 @@ void dcd_int_handler(uint8_t rhport) } }else { + TU_ASSERT(xfer->started,); xfer->total_len = xfer->actual_len; + xfer->started = false; // CBI OUT complete dcd_event_xfer_complete(0, epnum, xfer->actual_len, XFER_RESULT_SUCCESS, true); @@ -857,7 +838,7 @@ void dcd_int_handler(uint8_t rhport) { xfer_td_t* xfer = get_td(epnum, TUSB_DIR_OUT); - if (xfer->actual_len < xfer->total_len) + if ( xfer->started && xfer->actual_len < xfer->total_len ) { xact_out_dma(epnum); }else From 2571211957b28be7fd706d3cdd4209f17189788a Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 3 Jun 2022 11:32:09 +0700 Subject: [PATCH 359/504] remove static port defined for device/host --- examples/device/cdc_msc/src/main.c | 4 +++- hw/bsp/lpc18/family.c | 4 ++-- src/tusb.c | 10 ++++++---- src/tusb_option.h | 12 +----------- 4 files changed, 12 insertions(+), 18 deletions(-) diff --git a/examples/device/cdc_msc/src/main.c b/examples/device/cdc_msc/src/main.c index 131ae6549..c3666763b 100644 --- a/examples/device/cdc_msc/src/main.c +++ b/examples/device/cdc_msc/src/main.c @@ -54,7 +54,9 @@ void cdc_task(void); int main(void) { board_init(); - tusb_init(); + + // init device stack on configured roothub port + tud_init(BOARD_TUD_RHPORT); while (1) { diff --git a/hw/bsp/lpc18/family.c b/hw/bsp/lpc18/family.c index a59b6e89d..0fc788873 100644 --- a/hw/bsp/lpc18/family.c +++ b/hw/bsp/lpc18/family.c @@ -96,8 +96,8 @@ void board_init(void) SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) - NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); - NVIC_SetPriority(USB1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); + NVIC_SetPriority(USB1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif Chip_GPIO_Init(LPC_GPIO_PORT); diff --git a/src/tusb.c b/src/tusb.c index c86bdd891..709bb7d48 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -38,12 +38,14 @@ bool tusb_init(void) { -#if CFG_TUD_ENABLED - TU_ASSERT ( tud_init(TUD_OPT_RHPORT) ); // init device stack +#if CFG_TUD_ENABLED && defined(TUD_OPT_RHPORT) + // init device stack CFG_TUSB_RHPORTx_MODE must be defined + TU_ASSERT ( tud_init(TUD_OPT_RHPORT) ); #endif -#if CFG_TUH_ENABLED - TU_ASSERT( tuh_init(TUH_OPT_RHPORT) ); // init host stack +#if CFG_TUH_ENABLED && defined(TUH_OPT_RHPORT) + // init host stack CFG_TUSB_RHPORTx_MODE must be defined + TU_ASSERT( tuh_init(TUH_OPT_RHPORT) ); #endif return true; diff --git a/src/tusb_option.h b/src/tusb_option.h index c198e4ef3..0a0b20dca 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -197,15 +197,6 @@ typedef int make_iso_compilers_happy ; //------------- Roothub as Device -------------// -//#ifndef CFG_TUSB_RHPORT0_MODE -// #define CFG_TUSB_RHPORT0_MODE OPT_MODE_NONE -//#endif -// -//#ifndef CFG_TUSB_RHPORT1_MODE -// #define CFG_TUSB_RHPORT1_MODE OPT_MODE_NONE -//#endif - - #if defined(CFG_TUSB_RHPORT0_MODE) && ((CFG_TUSB_RHPORT0_MODE) & OPT_MODE_DEVICE) #define TUD_RHPORT_MODE (CFG_TUSB_RHPORT0_MODE) #define TUD_OPT_RHPORT 0 @@ -214,7 +205,6 @@ typedef int make_iso_compilers_happy ; #define TUD_OPT_RHPORT 1 #else #define TUD_RHPORT_MODE OPT_MODE_NONE - #define TUD_OPT_RHPORT -1 #endif #ifndef CFG_TUD_ENABLED @@ -228,7 +218,7 @@ typedef int make_iso_compilers_happy ; #endif // highspeed support indicator -#define TUD_OPT_HIGH_SPEED (CFG_TUD_MAX_SPEED ? CFG_TUD_MAX_SPEED : TUP_RHPORT_HIGHSPEED) +#define TUD_OPT_HIGH_SPEED (CFG_TUD_MAX_SPEED ? CFG_TUD_MAX_SPEED : TUP_RHPORT_HIGHSPEED) //------------- Roothub as Host -------------// From 31134f41a17c004aa48d87e397a6bae061f5b328 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 3 Jun 2022 17:24:28 +0700 Subject: [PATCH 360/504] make dwc2 stm32 rhport support dynamic --- src/portable/synopsys/dwc2/dcd_dwc2.c | 80 ++++++++++++++----------- src/portable/synopsys/dwc2/dwc2_stm32.h | 63 ++++++++++++------- src/portable/synopsys/dwc2/dwc2_type.h | 17 ++++-- 3 files changed, 98 insertions(+), 62 deletions(-) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index e489f6445..4d9e43ba8 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -50,12 +50,14 @@ #error "Unsupported MCUs" #endif +// Note _dwc2_controller[] must be defined by port header + //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ // DWC2 registers -#define DWC2_REG(_port) ((dwc2_regs_t*) DWC2_REG_BASE) +#define DWC2_REG(_port) ((dwc2_regs_t*) _dwc2_controller[_port].reg_base) // Debug level for DWC2 #define DWC2_DEBUG 2 @@ -72,7 +74,6 @@ #define dcache_clean_invalidate(_addr, _size) #endif - static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[2]; typedef struct { @@ -97,34 +98,32 @@ static bool _out_ep_closed; // Flag to check if RX FIFO si static bool _sof_en; // Calculate the RX FIFO size according to recommendations from reference manual -static inline uint16_t calc_rx_ff_size(uint16_t ep_size) +static inline uint16_t calc_grxfsiz(uint16_t max_ep_size, uint8_t ep_count) { - return 15 + 2*(ep_size/4) + 2*DWC2_EP_MAX; + return 15 + 2*(max_ep_size/4) + 2*ep_count; } static void update_grxfsiz(uint8_t rhport) { - (void) rhport; - - dwc2_regs_t * dwc2 = DWC2_REG(rhport); + dwc2_regs_t * dwc2 = DWC2_REG(rhport); + uint8_t const ep_count = _dwc2_controller[rhport].ep_count; // Determine largest EP size for RX FIFO uint16_t max_epsize = 0; - for (uint8_t epnum = 0; epnum < DWC2_EP_MAX; epnum++) + for (uint8_t epnum = 0; epnum < ep_count; epnum++) { max_epsize = tu_max16(max_epsize, xfer_status[epnum][TUSB_DIR_OUT].max_size); } // Update size of RX FIFO - dwc2->grxfsiz = calc_rx_ff_size(max_epsize); + dwc2->grxfsiz = calc_grxfsiz(max_epsize, ep_count); } -// Setup the control endpoint 0. +// Start of Bus Reset static void bus_reset(uint8_t rhport) { - (void) rhport; - - dwc2_regs_t * dwc2 = DWC2_REG(rhport); + dwc2_regs_t * dwc2 = DWC2_REG(rhport); + uint8_t const ep_count = _dwc2_controller[rhport].ep_count; tu_memclr(xfer_status, sizeof(xfer_status)); _out_ep_closed = false; @@ -135,7 +134,7 @@ static void bus_reset(uint8_t rhport) dwc2->dcfg &= ~DCFG_DAD_Msk; // 1. NAK for all OUT endpoints - for ( uint8_t n = 0; n < DWC2_EP_MAX; n++ ) + for ( uint8_t n = 0; n < ep_count; n++ ) { dwc2->epout[n].doepctl |= DOEPCTL_SNAK; } @@ -185,22 +184,24 @@ static void bus_reset(uint8_t rhport) // - 2 for each used OUT endpoint // // Therefore GRXFSIZ = 13 + 1 + 1 + 2 x (Largest-EPsize/4) + 2 x EPOUTnum - // - FullSpeed (64 Bytes ): GRXFSIZ = 15 + 2 x 16 + 2 x DWC2_EP_MAX = 47 + 2 x DWC2_EP_MAX - // - Highspeed (512 bytes): GRXFSIZ = 15 + 2 x 128 + 2 x DWC2_EP_MAX = 271 + 2 x DWC2_EP_MAX + // - FullSpeed (64 Bytes ): GRXFSIZ = 15 + 2 x 16 + 2 x ep_count = 47 + 2 x ep_count + // - Highspeed (512 bytes): GRXFSIZ = 15 + 2 x 128 + 2 x ep_count = 271 + 2 x ep_count // // NOTE: Largest-EPsize & EPOUTnum is actual used endpoints in configuration. Since DCD has no knowledge - // of the overall picture yet. We will use the worst scenario: largest possible + DWC2_EP_MAX + // of the overall picture yet. We will use the worst scenario: largest possible + ep_count // // For Isochronous, largest EP size can be 1023/1024 for FS/HS respectively. In addition if multiple ISO // are enabled at least "2 x (Largest-EPsize/4) + 1" are recommended. Maybe provide a macro for application to // overwrite this. - dwc2->grxfsiz = calc_rx_ff_size(TUD_OPT_HIGH_SPEED ? 512 : 64); + // EP0 out max is 64 + dwc2->grxfsiz = calc_grxfsiz(64, ep_count); + // Setup the control endpoint 0 _allocated_fifo_words_tx = 16; // Control IN uses FIFO 0 with 64 bytes ( 16 32-bit word ) - dwc2->dieptxf0 = (16 << DIEPTXF0_TX0FD_Pos) | (DWC2_EP_FIFO_SIZE/4 - _allocated_fifo_words_tx); + dwc2->dieptxf0 = (16 << DIEPTXF0_TX0FD_Pos) | (_dwc2_controller[rhport].ep_fifo_size/4 - _allocated_fifo_words_tx); // Fixed control EP0 size to 64 bytes dwc2->epin[0].diepctl &= ~(0x03 << DIEPCTL_MPSIZ_Pos); @@ -363,7 +364,11 @@ static void reset_core(dwc2_regs_t * dwc2) static bool phy_hs_supported(dwc2_regs_t * dwc2) { // note: esp32 incorrect report its hs_phy_type as utmi +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) + return false; +#else return TUD_OPT_HIGH_SPEED && dwc2->ghwcfg2_bm.hs_phy_type != HS_PHY_TYPE_NONE; +#endif } static void phy_fs_init(dwc2_regs_t * dwc2) @@ -620,12 +625,13 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) { (void) rhport; - dwc2_regs_t * dwc2 = DWC2_REG(rhport); + dwc2_regs_t * dwc2 = DWC2_REG(rhport); + uint8_t const ep_count = _dwc2_controller[rhport].ep_count; uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); - TU_ASSERT(epnum < DWC2_EP_MAX); + TU_ASSERT(epnum < ep_count); xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); xfer->max_size = tu_edpt_packet_size(desc_edpt); @@ -636,12 +642,12 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) if(dir == TUSB_DIR_OUT) { // Calculate required size of RX FIFO - uint16_t const sz = calc_rx_ff_size(4*fifo_size); + uint16_t const sz = calc_grxfsiz(4*fifo_size, ep_count); // If size_rx needs to be extended check if possible and if so enlarge it if (dwc2->grxfsiz < sz) { - TU_ASSERT(sz + _allocated_fifo_words_tx <= DWC2_EP_FIFO_SIZE/4); + TU_ASSERT(sz + _allocated_fifo_words_tx <= _dwc2_controller[rhport].ep_fifo_size/4); // Enlarge RX FIFO dwc2->grxfsiz = sz; @@ -678,15 +684,15 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) // - IN EP 1 gets FIFO 1, IN EP "n" gets FIFO "n". // Check if free space is available - TU_ASSERT(_allocated_fifo_words_tx + fifo_size + dwc2->grxfsiz <= DWC2_EP_FIFO_SIZE/4); + TU_ASSERT(_allocated_fifo_words_tx + fifo_size + dwc2->grxfsiz <= _dwc2_controller[rhport].ep_fifo_size/4); _allocated_fifo_words_tx += fifo_size; - TU_LOG(DWC2_DEBUG, " Allocated %u bytes at offset %u", fifo_size*4, DWC2_EP_FIFO_SIZE-_allocated_fifo_words_tx*4); + TU_LOG(DWC2_DEBUG, " Allocated %u bytes at offset %lu", fifo_size*4, _dwc2_controller[rhport].ep_fifo_size-_allocated_fifo_words_tx*4); // DIEPTXF starts at FIFO #1. // Both TXFD and TXSA are in unit of 32-bit words. - dwc2->dieptxf[epnum - 1] = (fifo_size << DIEPTXF_INEPTXFD_Pos) | (DWC2_EP_FIFO_SIZE/4 - _allocated_fifo_words_tx); + dwc2->dieptxf[epnum - 1] = (fifo_size << DIEPTXF_INEPTXFD_Pos) | (_dwc2_controller[rhport].ep_fifo_size/4 - _allocated_fifo_words_tx); dwc2->epin[epnum].diepctl |= (1 << DIEPCTL_USBAEP_Pos) | (epnum << DIEPCTL_TXFNUM_Pos) | @@ -703,14 +709,13 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) // Close all non-control endpoints, cancel all pending transfers if any. void dcd_edpt_close_all (uint8_t rhport) { - (void) rhport; - - dwc2_regs_t * dwc2 = DWC2_REG(rhport); + dwc2_regs_t * dwc2 = DWC2_REG(rhport); + uint8_t const ep_count = _dwc2_controller[rhport].ep_count; // Disable non-control interrupt dwc2->daintmsk = (1 << DAINTMSK_OEPM_Pos) | (1 << DAINTMSK_IEPM_Pos); - for(uint8_t n = 1; n < DWC2_EP_MAX; n++) + for(uint8_t n = 1; n < ep_count; n++) { // disable OUT endpoint dwc2->epout[n].doepctl = 0; @@ -871,8 +876,9 @@ void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) { uint16_t const fifo_size = (dwc2->dieptxf[epnum - 1] & DIEPTXF_INEPTXFD_Msk) >> DIEPTXF_INEPTXFD_Pos; uint16_t const fifo_start = (dwc2->dieptxf[epnum - 1] & DIEPTXF_INEPTXSA_Msk) >> DIEPTXF_INEPTXSA_Pos; + // For now only the last opened endpoint can be closed without fuss. - TU_ASSERT(fifo_start == DWC2_EP_FIFO_SIZE/4 - _allocated_fifo_words_tx,); + TU_ASSERT(fifo_start == _dwc2_controller[rhport].ep_fifo_size/4 - _allocated_fifo_words_tx,); _allocated_fifo_words_tx -= fifo_size; } else @@ -1075,11 +1081,12 @@ static void handle_rxflvl_irq(uint8_t rhport) static void handle_epout_irq (uint8_t rhport) { - dwc2_regs_t *dwc2 = DWC2_REG(rhport); + dwc2_regs_t * dwc2 = DWC2_REG(rhport); + uint8_t const ep_count = _dwc2_controller[rhport].ep_count; // DAINT for a given EP clears when DOEPINTx is cleared. // OEPINT will be cleared when DAINT's out bits are cleared. - for ( uint8_t n = 0; n < DWC2_EP_MAX; n++ ) + for ( uint8_t n = 0; n < ep_count; n++ ) { if ( dwc2->daint & TU_BIT(DAINT_OEPINT_Pos + n) ) { @@ -1126,12 +1133,13 @@ static void handle_epout_irq (uint8_t rhport) static void handle_epin_irq (uint8_t rhport) { - dwc2_regs_t *dwc2 = DWC2_REG(rhport); - dwc2_epin_t* epin = dwc2->epin; + dwc2_regs_t * dwc2 = DWC2_REG(rhport); + uint8_t const ep_count = _dwc2_controller[rhport].ep_count; + dwc2_epin_t* epin = dwc2->epin; // DAINT for a given EP clears when DIEPINTx is cleared. // IEPINT will be cleared when DAINT's out bits are cleared. - for ( uint8_t n = 0; n < DWC2_EP_MAX; n++ ) + for ( uint8_t n = 0; n < ep_count; n++ ) { if ( dwc2->daint & TU_BIT(DAINT_IEPINT_Pos + n) ) { diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index d54bf1fd7..23632616a 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -56,12 +56,9 @@ #define EP_FIFO_SIZE_FS 4096 #define EP_MAX_HS 9 #define EP_FIFO_SIZE_HS 4096 - #if (! defined USB2_OTG_FS) - // H7 with only 1 USB port: H72x / H73x / H7Ax / H7Bx - // USB_OTG_FS_PERIPH_BASE and OTG_FS_IRQn not defined - #define USB_OTG_FS_PERIPH_BASE USB1_OTG_HS_PERIPH_BASE - #define OTG_FS_IRQn OTG_HS_IRQn - #endif + + // NOTE: H7 with only 1 USB port: H72x / H73x / H7Ax / H7Bx + // USB_OTG_FS_PERIPH_BASE and OTG_FS_IRQn not defined #elif CFG_TUSB_MCU == OPT_MCU_STM32F7 #include "stm32f7xx.h" @@ -79,35 +76,57 @@ #error "Unsupported MCUs" #endif -// On STM32 we associate Port0 to OTG_FS, and Port1 to OTG_HS -#if TUD_OPT_RHPORT == 0 - #define DWC2_REG_BASE USB_OTG_FS_PERIPH_BASE - #define DWC2_EP_MAX EP_MAX_FS - #define DWC2_EP_FIFO_SIZE EP_FIFO_SIZE_FS - #define RHPORT_IRQn OTG_FS_IRQn - +// OTG HS always has higher number of endpoints than FS +#ifdef EP_MAX_HS + #define DWC2_EP_MAX EP_MAX_HS #else - #define DWC2_REG_BASE USB_OTG_HS_PERIPH_BASE - #define DWC2_EP_MAX EP_MAX_HS - #define DWC2_EP_FIFO_SIZE EP_FIFO_SIZE_HS - #define RHPORT_IRQn OTG_HS_IRQn - + #define DWC2_EP_MAX EP_MAX_FS #endif +// On STM32 we associate Port0 to OTG_FS, and Port1 to OTG_HS +//#if TUD_OPT_RHPORT == 0 +// #define DWC2_REG_BASE USB_OTG_FS_PERIPH_BASE +// #define DWC2_EP_MAX EP_MAX_FS +// #define DWC2_EP_FIFO_SIZE EP_FIFO_SIZE_FS +// #define RHPORT_IRQn OTG_FS_IRQn +// +//#else +// #define DWC2_REG_BASE USB_OTG_HS_PERIPH_BASE +// #define DWC2_EP_MAX EP_MAX_HS +// #define DWC2_EP_FIFO_SIZE EP_FIFO_SIZE_HS +// #define RHPORT_IRQn OTG_HS_IRQn +// +//#endif + +// On STM32 for consistency we associate +// - Port0 to OTG_FS, and Port1 to OTG_HS +static const dwc2_controller_t _dwc2_controller[] = +{ +#ifdef USB_OTG_FS_PERIPH_BASE + { .reg_base = USB_OTG_FS_PERIPH_BASE, .irqnum = OTG_FS_IRQn, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS}, +#endif + +#ifdef USB_OTG_HS_PERIPH_BASE + { .reg_base = USB_OTG_HS_PERIPH_BASE, .irqnum = OTG_HS_IRQn, .ep_count = EP_MAX_HS, .ep_fifo_size = EP_FIFO_SIZE_HS}, +#endif +}; + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ + extern uint32_t SystemCoreClock; TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_enable(uint8_t rhport) { - (void) rhport; - NVIC_EnableIRQ(RHPORT_IRQn); + NVIC_EnableIRQ(_dwc2_controller[rhport].irqnum); } TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_disable (uint8_t rhport) { - (void) rhport; - NVIC_DisableIRQ(RHPORT_IRQn); + NVIC_DisableIRQ(_dwc2_controller[rhport].irqnum); } TU_ATTR_ALWAYS_INLINE diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h index 7fa2028eb..e9df7335e 100644 --- a/src/portable/synopsys/dwc2/dwc2_type.h +++ b/src/portable/synopsys/dwc2/dwc2_type.h @@ -19,6 +19,19 @@ #include "stdint.h" +#ifdef __cplusplus + extern "C" { +#endif + +// Controller +typedef struct +{ + uint32_t reg_base; + uint32_t irqnum; + uint8_t ep_count; + uint32_t ep_fifo_size; +}dwc2_controller_t; + /* DWC OTG HW Release versions */ #define DWC2_CORE_REV_2_71a 0x4f54271a #define DWC2_CORE_REV_2_72a 0x4f54272a @@ -40,10 +53,6 @@ #define DWC2_FS_IOT_ID 0x55310000 #define DWC2_HS_IOT_ID 0x55320000 -#ifdef __cplusplus - extern "C" { -#endif - #if 0 // HS PHY typedef struct From 7df7590f7f96f0647e3164c7c7b368decffc87a2 Mon Sep 17 00:00:00 2001 From: Ryzee119 Date: Sun, 29 May 2022 14:01:24 +0930 Subject: [PATCH 361/504] Hub: Remove multi-level hub bypass --- src/host/usbh.c | 47 +++++++++++++++++++---------------------------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index af2ad0575..908230c83 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -1513,40 +1513,31 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur uint16_t const drv_len = tu_desc_get_interface_total_len(desc_itf, assoc_itf_count, desc_end-p_desc); TU_ASSERT(drv_len >= sizeof(tusb_desc_interface_t)); - if (desc_itf->bInterfaceClass == TUSB_CLASS_HUB && dev->hub_addr != 0) + // Find driver for this interface + uint8_t drv_id; + for (drv_id = 0; drv_id < USBH_CLASS_DRIVER_COUNT; drv_id++) { - // TODO Attach hub to Hub is not currently supported - // skip this interface - TU_LOG(USBH_DBG_LVL, "Only 1 level of HUB is supported\r\n"); - } - else - { - // Find driver for this interface - uint8_t drv_id; - for (drv_id = 0; drv_id < USBH_CLASS_DRIVER_COUNT; drv_id++) + usbh_class_driver_t const * driver = &usbh_class_drivers[drv_id]; + + if ( driver->open(dev->rhport, dev_addr, desc_itf, drv_len) ) { - usbh_class_driver_t const * driver = &usbh_class_drivers[drv_id]; + // open successfully + TU_LOG2(" %s opened\r\n", driver->name); - if ( driver->open(dev->rhport, dev_addr, desc_itf, drv_len) ) + // bind (associated) interfaces to found driver + for(uint8_t i=0; iname); + uint8_t const itf_num = desc_itf->bInterfaceNumber+i; - // bind (associated) interfaces to found driver - for(uint8_t i=0; ibInterfaceNumber+i; - - // Interface number must not be used already - TU_ASSERT( DRVID_INVALID == dev->itf2drv[itf_num] ); - dev->itf2drv[itf_num] = drv_id; - } - - // bind all endpoints to found driver - tu_edpt_bind_driver(dev->ep2drv, desc_itf, drv_len, drv_id); - - break; // exit driver find loop + // Interface number must not be used already + TU_ASSERT( DRVID_INVALID == dev->itf2drv[itf_num] ); + dev->itf2drv[itf_num] = drv_id; } + + // bind all endpoints to found driver + tu_edpt_bind_driver(dev->ep2drv, desc_itf, drv_len, drv_id); + + break; // exit driver find loop } if( drv_id >= USBH_CLASS_DRIVER_COUNT ) From f626916a5733fc7beff29ff6f907433e28ff14e0 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 4 Jun 2022 23:52:12 +0700 Subject: [PATCH 362/504] update all dwc2 ports to support new dynamic controller support --- src/portable/synopsys/dwc2/dcd_dwc2.c | 10 ++++++++-- src/portable/synopsys/dwc2/dwc2_bcm.h | 13 +++++++------ src/portable/synopsys/dwc2/dwc2_efm32.h | 12 +++++++----- src/portable/synopsys/dwc2/dwc2_esp32.h | 8 +++++--- src/portable/synopsys/dwc2/dwc2_gd32.h | 13 +++++++------ src/portable/synopsys/dwc2/dwc2_stm32.h | 19 ++----------------- src/portable/synopsys/dwc2/dwc2_type.h | 8 ++++---- src/portable/synopsys/dwc2/dwc2_xmc.h | 15 ++++++++------- 8 files changed, 48 insertions(+), 50 deletions(-) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 4d9e43ba8..f5ecdfe4f 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -34,6 +34,13 @@ #include "device/dcd.h" #include "dwc2_type.h" +// Following symbols must be defined by port header +// - _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_dcd_int_enable/dwc2_dcd_int_disable +// - dwc2_remote_wakeup_delay + #if defined(TUP_USBIP_DWC2_STM32) #include "dwc2_stm32.h" #elif TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) @@ -50,8 +57,6 @@ #error "Unsupported MCUs" #endif -// Note _dwc2_controller[] must be defined by port header - //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ @@ -467,6 +472,7 @@ static bool check_dwc2(dwc2_regs_t * dwc2) #endif // For some reasons: GD32VF103 snpsid and all hwcfg register are always zero (skip it) + (void) dwc2; #if !TU_CHECK_MCU(OPT_MCU_GD32VF103) uint32_t const gsnpsid = dwc2->gsnpsid & GSNPSID_ID_MASK; TU_ASSERT(gsnpsid == DWC2_OTG_ID || gsnpsid == DWC2_FS_IOT_ID || gsnpsid == DWC2_HS_IOT_ID); diff --git a/src/portable/synopsys/dwc2/dwc2_bcm.h b/src/portable/synopsys/dwc2/dwc2_bcm.h index 14194e754..732d96ae0 100644 --- a/src/portable/synopsys/dwc2/dwc2_bcm.h +++ b/src/portable/synopsys/dwc2/dwc2_bcm.h @@ -35,9 +35,12 @@ #include "broadcom/interrupts.h" #include "broadcom/caches.h" -#define DWC2_REG_BASE USB_OTG_GLOBAL_BASE #define DWC2_EP_MAX 8 -#define DWC2_EP_FIFO_SIZE 4096 + +static const dwc2_controller_t _dwc2_controller[] = +{ + { .reg_base = USB_OTG_GLOBAL_BASE, .irqnum = USB_IRQn, .ep_count = DWC2_EP_MAX, .ep_fifo_size = 4096 } +}; #define dcache_clean(_addr, _size) data_clean(_addr, _size) #define dcache_invalidate(_addr, _size) data_invalidate(_addr, _size) @@ -46,15 +49,13 @@ TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_enable(uint8_t rhport) { - (void) rhport; - BP_EnableIRQ(USB_IRQn); + BP_EnableIRQ(_dwc2_controller[rhport].irqnum); } TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_disable (uint8_t rhport) { - (void) rhport; - BP_DisableIRQ(USB_IRQn); + BP_DisableIRQ(_dwc2_controller[rhport].irqnum); } static inline void dwc2_remote_wakeup_delay(void) diff --git a/src/portable/synopsys/dwc2/dwc2_efm32.h b/src/portable/synopsys/dwc2/dwc2_efm32.h index ee4c3c715..0e3570cbb 100644 --- a/src/portable/synopsys/dwc2/dwc2_efm32.h +++ b/src/portable/synopsys/dwc2/dwc2_efm32.h @@ -37,20 +37,22 @@ // EFM32 has custom control register before DWC registers #define DWC2_REG_BASE (USB_BASE + offsetof(USB_TypeDef, GOTGCTL)) #define DWC2_EP_MAX 7 -#define DWC2_EP_FIFO_SIZE 2048 + +static const dwc2_controller_t _dwc2_controller[] = +{ + { .reg_base = DWC2_REG_BASE, .irqnum = USB_IRQn, .ep_count = DWC2_EP_MAX, .ep_fifo_size = 2048 } +}; TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_enable(uint8_t rhport) { - (void) rhport; - NVIC_EnableIRQ(USB_IRQn); + NVIC_EnableIRQ(_dwc2_controller[rhport].irqnum); } TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_disable (uint8_t rhport) { - (void) rhport; - NVIC_DisableIRQ(USB_IRQn); + NVIC_DisableIRQ(_dwc2_controller[rhport].irqnum); } static inline void dwc2_remote_wakeup_delay(void) diff --git a/src/portable/synopsys/dwc2/dwc2_esp32.h b/src/portable/synopsys/dwc2/dwc2_esp32.h index 78da277d5..c50dd66b8 100644 --- a/src/portable/synopsys/dwc2/dwc2_esp32.h +++ b/src/portable/synopsys/dwc2/dwc2_esp32.h @@ -37,10 +37,12 @@ //#include "soc/usb_periph.h" #define DWC2_REG_BASE 0x60080000UL -#define DWC2_EP_MAX 5 // USB_OUT_EP_NUM -#define DWC2_EP_FIFO_SIZE 1024 +#define DWC2_EP_MAX 6 // USB_OUT_EP_NUM. TODO ESP32Sx only has 5 tx fifo (5 endpoint IN) -// #define EP_FIFO_NUM 5 +static const dwc2_controller_t _dwc2_controller[] = +{ + { .reg_base = DWC2_REG_BASE, .irqnum = 0, .ep_count = DWC2_EP_MAX, .ep_fifo_size = 1024 } +}; static intr_handle_t usb_ih; diff --git a/src/portable/synopsys/dwc2/dwc2_gd32.h b/src/portable/synopsys/dwc2/dwc2_gd32.h index f8fa01ee0..0375fffe4 100644 --- a/src/portable/synopsys/dwc2/dwc2_gd32.h +++ b/src/portable/synopsys/dwc2/dwc2_gd32.h @@ -34,8 +34,11 @@ #define DWC2_REG_BASE 0x50000000UL #define DWC2_EP_MAX 4 -#define DWC2_EP_FIFO_SIZE 1280 -#define RHPORT_IRQn 86 + +static const dwc2_controller_t _dwc2_controller[] = +{ + { .reg_base = DWC2_REG_BASE, .irqnum = 86, .ep_count = DWC2_EP_MAX, .ep_fifo_size = 1280 } +}; extern uint32_t SystemCoreClock; @@ -57,15 +60,13 @@ static inline void __eclic_disable_interrupt (uint32_t irq){ TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_enable(uint8_t rhport) { - (void) rhport; - __eclic_enable_interrupt(RHPORT_IRQn); + __eclic_enable_interrupt(_dwc2_controller[rhport].irqnum); } TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_disable (uint8_t rhport) { - (void) rhport; - __eclic_disable_interrupt(RHPORT_IRQn); + __eclic_disable_interrupt(_dwc2_controller[rhport].irqnum); } static inline void dwc2_remote_wakeup_delay(void) diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index 23632616a..709428f7f 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -83,31 +83,16 @@ #define DWC2_EP_MAX EP_MAX_FS #endif -// On STM32 we associate Port0 to OTG_FS, and Port1 to OTG_HS -//#if TUD_OPT_RHPORT == 0 -// #define DWC2_REG_BASE USB_OTG_FS_PERIPH_BASE -// #define DWC2_EP_MAX EP_MAX_FS -// #define DWC2_EP_FIFO_SIZE EP_FIFO_SIZE_FS -// #define RHPORT_IRQn OTG_FS_IRQn -// -//#else -// #define DWC2_REG_BASE USB_OTG_HS_PERIPH_BASE -// #define DWC2_EP_MAX EP_MAX_HS -// #define DWC2_EP_FIFO_SIZE EP_FIFO_SIZE_HS -// #define RHPORT_IRQn OTG_HS_IRQn -// -//#endif - // On STM32 for consistency we associate // - Port0 to OTG_FS, and Port1 to OTG_HS static const dwc2_controller_t _dwc2_controller[] = { #ifdef USB_OTG_FS_PERIPH_BASE - { .reg_base = USB_OTG_FS_PERIPH_BASE, .irqnum = OTG_FS_IRQn, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS}, + { .reg_base = USB_OTG_FS_PERIPH_BASE, .irqnum = OTG_FS_IRQn, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS }, #endif #ifdef USB_OTG_HS_PERIPH_BASE - { .reg_base = USB_OTG_HS_PERIPH_BASE, .irqnum = OTG_HS_IRQn, .ep_count = EP_MAX_HS, .ep_fifo_size = EP_FIFO_SIZE_HS}, + { .reg_base = USB_OTG_HS_PERIPH_BASE, .irqnum = OTG_HS_IRQn, .ep_count = EP_MAX_HS, .ep_fifo_size = EP_FIFO_SIZE_HS }, #endif }; diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h index e9df7335e..3fc979337 100644 --- a/src/portable/synopsys/dwc2/dwc2_type.h +++ b/src/portable/synopsys/dwc2/dwc2_type.h @@ -26,10 +26,10 @@ // Controller typedef struct { - uint32_t reg_base; - uint32_t irqnum; - uint8_t ep_count; - uint32_t ep_fifo_size; + uintptr_t reg_base; + uint32_t irqnum; + uint8_t ep_count; + uint32_t ep_fifo_size; }dwc2_controller_t; /* DWC OTG HW Release versions */ diff --git a/src/portable/synopsys/dwc2/dwc2_xmc.h b/src/portable/synopsys/dwc2/dwc2_xmc.h index 4e6bebb01..63419abf7 100644 --- a/src/portable/synopsys/dwc2/dwc2_xmc.h +++ b/src/portable/synopsys/dwc2/dwc2_xmc.h @@ -34,23 +34,24 @@ #include "xmc_device.h" -// XMC has custom control register before DWC registers -#define DWC2_REG_BASE USB0_BASE #define DWC2_EP_MAX 7 -#define DWC2_EP_FIFO_SIZE 2048 + +static const dwc2_controller_t _dwc2_controller[] = +{ + // Note: XMC has some custom control registers before DWC registers + { .reg_base = USB0_BASE, .irqnum = USB0_0_IRQn, .ep_count = DWC2_EP_MAX, .ep_fifo_size = 2048 } +}; TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_enable(uint8_t rhport) { - (void) rhport; - NVIC_EnableIRQ(USB0_0_IRQn); + NVIC_EnableIRQ(_dwc2_controller[rhport].irqnum); } TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_disable (uint8_t rhport) { - (void) rhport; - NVIC_DisableIRQ(USB0_0_IRQn); + NVIC_DisableIRQ(_dwc2_controller[rhport].irqnum); } static inline void dwc2_remote_wakeup_delay(void) From 7187cd9a8528bfe2b570567ca2d0a2ae36b7c478 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 6 Jun 2022 12:51:10 +0700 Subject: [PATCH 363/504] fix ci, remove use of CFG_TUSB_RHPORT0_MODE in bsp --- hw/bsp/ea4088qs/ea4088qs.c | 6 ++-- hw/bsp/ea4357/ea4357.c | 36 ++++++++++++++-------- hw/bsp/fomu/fomu.c | 2 +- hw/bsp/imxrt/family.c | 38 +++++++++++++++++------- hw/bsp/lpc54/family.c | 19 ++++++++---- hw/bsp/lpc55/family.c | 16 ++++++++-- hw/bsp/lpcxpresso1769/lpcxpresso1769.c | 8 ++--- hw/bsp/mbed1768/mbed1768.c | 8 ++--- hw/bsp/ngx4330/ngx4330.c | 35 +++++++++++++--------- hw/bsp/samg55xplained/samg55xplained.c | 2 +- src/portable/bridgetek/ft9xx/dcd_ft9xx.c | 2 +- 11 files changed, 114 insertions(+), 58 deletions(-) diff --git a/hw/bsp/ea4088qs/ea4088qs.c b/hw/bsp/ea4088qs/ea4088qs.c index b25f9101c..fa905b2f9 100644 --- a/hw/bsp/ea4088qs/ea4088qs.c +++ b/hw/bsp/ea4088qs/ea4088qs.c @@ -32,11 +32,11 @@ //--------------------------------------------------------------------+ void USB_IRQHandler(void) { - #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST + #if CFG_TUD_ENABLED tuh_int_handler(0); #endif - #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE + #if CFG_TUH_ENABLED tud_int_handler(0); #endif } @@ -115,7 +115,7 @@ void board_init(void) SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) - NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif Chip_GPIO_Init(LPC_GPIO); diff --git a/hw/bsp/ea4357/ea4357.c b/hw/bsp/ea4357/ea4357.c index aa206a28d..2c1d08770 100644 --- a/hw/bsp/ea4357/ea4357.c +++ b/hw/bsp/ea4357/ea4357.c @@ -53,6 +53,18 @@ // {0x02, 7, 0, 7 }, // SW6 //}; +#ifdef BOARD_TUD_RHPORT + #define PORT_SUPPORT_DEVICE(_n) (BOARD_TUD_RHPORT == _n) +#else + #define PORT_SUPPORT_DEVICE(_n) 0 +#endif + +#ifdef BOARD_TUH_RHPORT + #define PORT_SUPPORT_HOST(_n) (BOARD_TUH_RHPORT == _n) +#else + #define PORT_SUPPORT_HOST(_n) 0 +#endif + /*------------------------------------------------------------------*/ /* BOARD API *------------------------------------------------------------------*/ @@ -116,7 +128,7 @@ void board_init(void) SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) - //NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif Chip_GPIO_Init(LPC_GPIO_PORT); @@ -170,7 +182,7 @@ void board_init(void) * - Insert jumpers in position 2-3 in JP17/JP18/JP19 * - Insert jumpers in JP31 (OTG) */ -#if CFG_TUSB_RHPORT0_MODE +#if PORT_SUPPORT_DEVICE(0) || PORT_SUPPORT_HOST(0) Chip_USB0_Init(); #endif @@ -195,14 +207,14 @@ void board_init(void) * - LED34 lights green when +5V is available on J20. * - JP15 shall not be inserted. JP16 has no effect */ -#if CFG_TUSB_RHPORT1_MODE +#if PORT_SUPPORT_DEVICE(1) || PORT_SUPPORT_HOST(1) Chip_USB1_Init(); #endif // 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); - #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE + #if PORT_SUPPORT_DEVICE(0) // P9_5 (GPIO5[18]) (GPIO28 on oem base) as USB connect, active low. Chip_SCU_PinMuxSet(9, 5, SCU_MODE_PULLDOWN | SCU_MODE_FUNC4); Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, 5, 18); @@ -217,23 +229,23 @@ void board_init(void) //--------------------------------------------------------------------+ void USB0_IRQHandler(void) { - #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST - tuh_int_handler(0); + #if PORT_SUPPORT_DEVICE(0) + tud_int_handler(0); #endif - #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE - tud_int_handler(0); + #if PORT_SUPPORT_HOST(0) + tuh_int_handler(0); #endif } void USB1_IRQHandler(void) { - #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST - tuh_int_handler(1); + #if PORT_SUPPORT_DEVICE(1) + tud_int_handler(1); #endif - #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE - tud_int_handler(1); + #if PORT_SUPPORT_HOST(1) + tuh_int_handler(1); #endif } diff --git a/hw/bsp/fomu/fomu.c b/hw/bsp/fomu/fomu.c index 12b7bfd18..33c630303 100644 --- a/hw/bsp/fomu/fomu.c +++ b/hw/bsp/fomu/fomu.c @@ -61,7 +61,7 @@ void isr(void) irqs = irq_pending() & irq_getmask(); -#if CFG_TUSB_RHPORT0_MODE == OPT_MODE_DEVICE +#if CFG_TUD_ENABLED if (irqs & (1 << USB_INTERRUPT)) { tud_int_handler(0); } diff --git a/hw/bsp/imxrt/family.c b/hw/bsp/imxrt/family.c index 8d34d4b9f..e5f630108 100644 --- a/hw/bsp/imxrt/family.c +++ b/hw/bsp/imxrt/family.c @@ -34,9 +34,25 @@ #include "clock_config.h" +#ifdef BOARD_TUD_RHPORT + #define PORT_SUPPORT_DEVICE(_n) (BOARD_TUD_RHPORT == _n) +#else + #define PORT_SUPPORT_DEVICE(_n) 0 +#endif + +#ifdef BOARD_TUH_RHPORT + #define PORT_SUPPORT_HOST(_n) (BOARD_TUH_RHPORT == _n) +#else + #define PORT_SUPPORT_HOST(_n) 0 +#endif + // needed by fsl_flexspi_nor_boot const uint8_t dcd_data[] = { 0x00 }; +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ + void board_init(void) { // Init clock @@ -51,9 +67,9 @@ void board_init(void) SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) - NVIC_SetPriority(USB_OTG1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); -#ifdef USB_OTG2_IRQn - NVIC_SetPriority(USB_OTG2_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + NVIC_SetPriority(USB_OTG1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); +#ifdef USBPHY2 + NVIC_SetPriority(USB_OTG2_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif #endif @@ -149,23 +165,23 @@ void board_init(void) //--------------------------------------------------------------------+ void USB_OTG1_IRQHandler(void) { - #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST - tuh_int_handler(0); + #if PORT_SUPPORT_DEVICE(0) + tud_int_handler(0); #endif - #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE - tud_int_handler(0); + #if PORT_SUPPORT_HOST(0) + tuh_int_handler(0); #endif } void USB_OTG2_IRQHandler(void) { - #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST - tuh_int_handler(1); + #if PORT_SUPPORT_DEVICE(1) + tud_int_handler(1); #endif - #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE - tud_int_handler(1); + #if PORT_SUPPORT_HOST(1) + tuh_int_handler(1); #endif } diff --git a/hw/bsp/lpc54/family.c b/hw/bsp/lpc54/family.c index 4f1199c3a..9bb341e73 100644 --- a/hw/bsp/lpc54/family.c +++ b/hw/bsp/lpc54/family.c @@ -33,6 +33,18 @@ #include "bsp/board.h" #include "board.h" +#ifdef BOARD_TUD_RHPORT + #define PORT_SUPPORT_DEVICE(_n) (BOARD_TUD_RHPORT == _n) +#else + #define PORT_SUPPORT_DEVICE(_n) 0 +#endif + +#ifdef BOARD_TUH_RHPORT + #define PORT_SUPPORT_HOST(_n) (BOARD_TUH_RHPORT == _n) +#else + #define PORT_SUPPORT_HOST(_n) 0 +#endif + //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ @@ -152,8 +164,7 @@ void board_init(void) #if defined(FSL_FEATURE_SOC_USBHSD_COUNT) && FSL_FEATURE_SOC_USBHSD_COUNT // LPC546xx and LPC540xx has OTG 1 FS + 1 HS rhports - - #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE + #if PORT_SUPPORT_DEVICE(0) // Port0 is Full Speed POWER_DisablePD(kPDRUNCFG_PD_USB0_PHY); /*< Turn on USB Phy */ CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1, false); @@ -167,7 +178,7 @@ void board_init(void) CLOCK_EnableUsbfs0DeviceClock(kCLOCK_UsbSrcFro, CLOCK_GetFroHfFreq()); #endif - #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE + #if PORT_SUPPORT_DEVICE(1) // Port1 is High Speed POWER_DisablePD(kPDRUNCFG_PD_USB1_PHY); @@ -178,10 +189,8 @@ void board_init(void) CLOCK_EnableUsbhs0DeviceClock(kCLOCK_UsbSrcUsbPll, 0U); #endif - #else // 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 */ #endif diff --git a/hw/bsp/lpc55/family.c b/hw/bsp/lpc55/family.c index f037a9f5b..e7aed5759 100644 --- a/hw/bsp/lpc55/family.c +++ b/hw/bsp/lpc55/family.c @@ -34,6 +34,18 @@ #include "fsl_sctimer.h" #include "sct_neopixel.h" +#ifdef BOARD_TUD_RHPORT + #define PORT_SUPPORT_DEVICE(_n) (BOARD_TUD_RHPORT == _n) +#else + #define PORT_SUPPORT_DEVICE(_n) 0 +#endif + +#ifdef BOARD_TUH_RHPORT + #define PORT_SUPPORT_HOST(_n) (BOARD_TUH_RHPORT == _n) +#else + #define PORT_SUPPORT_HOST(_n) 0 +#endif + //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ @@ -164,7 +176,7 @@ void board_init(void) /* PORT0 PIN22 configured as USB0_VBUS */ IOCON_PinMuxSet(IOCON, 0U, 22U, IOCON_PIO_DIG_FUNC7_EN); -#if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE +#if PORT_SUPPORT_DEVICE(0) // Port0 is Full Speed /* Turn on USB0 Phy */ @@ -189,7 +201,7 @@ void board_init(void) CLOCK_EnableUsbfs0DeviceClock(kCLOCK_UsbfsSrcFro, CLOCK_GetFreq(kCLOCK_FroHf)); #endif -#if CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE +#if PORT_SUPPORT_DEVICE(1) // Port1 is High Speed /* Turn on USB1 Phy */ diff --git a/hw/bsp/lpcxpresso1769/lpcxpresso1769.c b/hw/bsp/lpcxpresso1769/lpcxpresso1769.c index b82e5ffe0..b7bce93d2 100644 --- a/hw/bsp/lpcxpresso1769/lpcxpresso1769.c +++ b/hw/bsp/lpcxpresso1769/lpcxpresso1769.c @@ -32,12 +32,12 @@ //--------------------------------------------------------------------+ void USB_IRQHandler(void) { - #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST - tuh_int_handler(0); + #if CFG_TUD_ENABLED + tud_int_handler(0); #endif - #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE - tud_int_handler(0); + #if CFG_TUH_ENABLED + tuh_int_handler(0); #endif } diff --git a/hw/bsp/mbed1768/mbed1768.c b/hw/bsp/mbed1768/mbed1768.c index 7c2b37016..08cf3adbd 100644 --- a/hw/bsp/mbed1768/mbed1768.c +++ b/hw/bsp/mbed1768/mbed1768.c @@ -146,12 +146,12 @@ void board_init(void) //--------------------------------------------------------------------+ void USB_IRQHandler(void) { - #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST - tuh_int_handler(0); + #if CFG_TUD_ENABLED + tud_int_handler(0); #endif - #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE - tud_int_handler(0); + #if CFG_TUH_ENABLED + tuh_int_handler(0); #endif } diff --git a/hw/bsp/ngx4330/ngx4330.c b/hw/bsp/ngx4330/ngx4330.c index b63f9b894..4fc314165 100644 --- a/hw/bsp/ngx4330/ngx4330.c +++ b/hw/bsp/ngx4330/ngx4330.c @@ -40,6 +40,18 @@ #define BOARD_UART_PIN_TX 10 // PF.10 : UART0_TXD #define BOARD_UART_PIN_RX 11 // PF.11 : UART0_RXD +#ifdef BOARD_TUD_RHPORT + #define PORT_SUPPORT_DEVICE(_n) (BOARD_TUD_RHPORT == _n) +#else + #define PORT_SUPPORT_DEVICE(_n) 0 +#endif + +#ifdef BOARD_TUH_RHPORT + #define PORT_SUPPORT_HOST(_n) (BOARD_TUH_RHPORT == _n) +#else + #define PORT_SUPPORT_HOST(_n) 0 +#endif + /*------------------------------------------------------------------*/ /* BOARD API *------------------------------------------------------------------*/ @@ -120,7 +132,7 @@ void board_init(void) SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) - //NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif Chip_GPIO_Init(LPC_GPIO_PORT); @@ -167,9 +179,7 @@ void board_init(void) * status feedback from the distribution switch. GPIO54 is used for VBUS sensing. 15Kohm pull-down * resistors are always active */ -#if CFG_TUSB_RHPORT0_MODE Chip_USB0_Init(); -#endif /* USB1 * When USB channel #1 is used as USB Host, 15Kohm pull-down resistors are needed on the USB data @@ -189,12 +199,9 @@ void board_init(void) * of VBUS can be read via U31. * JP16 shall not be inserted. */ -#if CFG_TUSB_RHPORT1_MODE Chip_USB1_Init(); - // Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, 5, 6); /* GPIO5[6] = USB1_PWR_EN */ // Chip_GPIO_SetPinState(LPC_GPIO_PORT, 5, 6, true); /* GPIO5[6] output high */ -#endif } //--------------------------------------------------------------------+ @@ -202,23 +209,23 @@ void board_init(void) //--------------------------------------------------------------------+ void USB0_IRQHandler(void) { - #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST - tuh_int_handler(0); + #if PORT_SUPPORT_DEVICE(0) + tud_int_handler(0); #endif - #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE - tud_int_handler(0); + #if PORT_SUPPORT_HOST(0) + tuh_int_handler(0); #endif } void USB1_IRQHandler(void) { - #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST - tuh_int_handler(1); + #if PORT_SUPPORT_DEVICE(1) + tud_int_handler(1); #endif - #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE - tud_int_handler(1); + #if PORT_SUPPORT_HOST(1) + tuh_int_handler(1); #endif } diff --git a/hw/bsp/samg55xplained/samg55xplained.c b/hw/bsp/samg55xplained/samg55xplained.c index ed106b06b..027c88e2f 100644 --- a/hw/bsp/samg55xplained/samg55xplained.c +++ b/hw/bsp/samg55xplained/samg55xplained.c @@ -99,7 +99,7 @@ void board_init(void) //--------------------------------------------------------------------+ void UDP_Handler(void) { - #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE + #if CFG_TUD_ENABLED tud_int_handler(0); #endif } diff --git a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c index 7a65cf5d0..2445593fe 100644 --- a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c +++ b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c @@ -312,7 +312,7 @@ static void _dcd_ft90x_detach(void) // Determine the speed of the USB to which we are connected. // Set the speed of the PHY accordingly. -// High speed can be disabled through CFG_TUSB_RHPORT0_MODE settings. +// High speed can be disabled through CFG_TUSB_RHPORT0_MODE or CFG_TUD_MAX_SPEED settings. static void _ft90x_usb_speed(void) { uint8_t fctrl_val; From 1b086729452c67e3e78a736506732ca013959572 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 6 Jun 2022 13:25:48 +0700 Subject: [PATCH 364/504] more ci fix --- hw/bsp/imxrt/family.c | 4 ++-- src/portable/synopsys/dwc2/dwc2_stm32.h | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/hw/bsp/imxrt/family.c b/hw/bsp/imxrt/family.c index e5f630108..fc6e9e266 100644 --- a/hw/bsp/imxrt/family.c +++ b/hw/bsp/imxrt/family.c @@ -34,13 +34,13 @@ #include "clock_config.h" -#ifdef BOARD_TUD_RHPORT +#if defined(BOARD_TUD_RHPORT) && CFG_TUD_ENABLED #define PORT_SUPPORT_DEVICE(_n) (BOARD_TUD_RHPORT == _n) #else #define PORT_SUPPORT_DEVICE(_n) 0 #endif -#ifdef BOARD_TUH_RHPORT +#if defined(BOARD_TUH_RHPORT) && CFG_TUH_ENABLED #define PORT_SUPPORT_HOST(_n) (BOARD_TUH_RHPORT == _n) #else #define PORT_SUPPORT_HOST(_n) 0 diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index 709428f7f..b500ddc46 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -47,6 +47,7 @@ #include "stm32f4xx.h" #define EP_MAX_FS USB_OTG_FS_MAX_IN_ENDPOINTS #define EP_FIFO_SIZE_FS USB_OTG_FS_TOTAL_FIFO_SIZE + #define EP_MAX_HS USB_OTG_HS_MAX_IN_ENDPOINTS #define EP_FIFO_SIZE_HS USB_OTG_HS_TOTAL_FIFO_SIZE @@ -54,6 +55,7 @@ #include "stm32h7xx.h" #define EP_MAX_FS 9 #define EP_FIFO_SIZE_FS 4096 + #define EP_MAX_HS 9 #define EP_FIFO_SIZE_HS 4096 @@ -64,6 +66,7 @@ #include "stm32f7xx.h" #define EP_MAX_FS 6 #define EP_FIFO_SIZE_FS 1280 + #define EP_MAX_HS 9 #define EP_FIFO_SIZE_HS 4096 @@ -77,7 +80,7 @@ #endif // OTG HS always has higher number of endpoints than FS -#ifdef EP_MAX_HS +#ifdef USB_OTG_HS_PERIPH_BASE #define DWC2_EP_MAX EP_MAX_HS #else #define DWC2_EP_MAX EP_MAX_FS From f4c80dd218240d934a28cb21d8ddd6a0e3a33fe5 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 6 Jun 2022 17:35:17 +0700 Subject: [PATCH 365/504] clean up example to use CFG_TUD_ENABLED + CFG_TUD_MAX_SPEED instead of CFG_TUSB_RHPORT0_MODE --- .../device/audio_4_channel_mic/src/main.c | 3 +- .../audio_4_channel_mic/src/tusb_config.h | 63 +++++++++++-------- examples/device/board_test/src/tusb_config.h | 19 +----- examples/device/cdc_msc/src/tusb_config.h | 39 ++++++------ examples/device/cdc_msc_freertos/src/main.c | 3 +- .../device/cdc_msc_freertos/src/tusb_config.h | 57 ++++++++--------- 6 files changed, 89 insertions(+), 95 deletions(-) diff --git a/examples/device/audio_4_channel_mic/src/main.c b/examples/device/audio_4_channel_mic/src/main.c index d085dd43a..9c94edd49 100644 --- a/examples/device/audio_4_channel_mic/src/main.c +++ b/examples/device/audio_4_channel_mic/src/main.c @@ -81,7 +81,8 @@ int main(void) { board_init(); - tusb_init(); + // init device stack on configured roothub port + tud_init(BOARD_TUD_RHPORT); // Init values sampFreq = AUDIO_SAMPLE_RATE; diff --git a/examples/device/audio_4_channel_mic/src/tusb_config.h b/examples/device/audio_4_channel_mic/src/tusb_config.h index 023faa7e2..0f5fbfef7 100644 --- a/examples/device/audio_4_channel_mic/src/tusb_config.h +++ b/examples/device/audio_4_channel_mic/src/tusb_config.h @@ -30,6 +30,20 @@ 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 //-------------------------------------------------------------------- @@ -39,18 +53,19 @@ extern "C" { #error CFG_TUSB_MCU must be defined #endif -#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE - #ifndef CFG_TUSB_OS -#define CFG_TUSB_OS OPT_OS_NONE +#define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG -#define CFG_TUSB_DEBUG 0 +#define CFG_TUSB_DEBUG 0 #endif -// CFG_TUSB_DEBUG is defined by compiler in DEBUG build -// #define CFG_TUSB_DEBUG 0 +// 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 @@ -64,7 +79,7 @@ extern "C" { #endif #ifndef CFG_TUSB_MEM_ALIGN -#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- @@ -75,13 +90,7 @@ extern "C" { #define CFG_TUD_ENDPOINT0_SIZE 64 #endif -//------------- CLASS -------------// -#define CFG_TUD_CDC 0 -#define CFG_TUD_MSC 0 -#define CFG_TUD_HID 0 -#define CFG_TUD_MIDI 0 #define CFG_TUD_AUDIO 1 -#define CFG_TUD_VENDOR 0 //-------------------------------------------------------------------- // AUDIO CLASS DRIVER CONFIGURATION @@ -89,23 +98,23 @@ extern "C" { // Have a look into audio_device.h for all configurations -#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_MIC_FOUR_CH_DESC_LEN +#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_MIC_FOUR_CH_DESC_LEN -#define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 1 -#define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64 +#define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 1 +#define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64 -#define CFG_TUD_AUDIO_ENABLE_EP_IN 1 -#define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup -#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 4 // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup -#define CFG_TUD_AUDIO_EP_SZ_IN (48 + 1) * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX // 48 Samples (48 kHz) x 2 Bytes/Sample x CFG_TUD_AUDIO_N_CHANNELS_TX Channels - the Windows driver always needs an extra sample per channel of space more, otherwise it complains... found by trial and error -#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN -#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ CFG_TUD_AUDIO_EP_SZ_IN +#define CFG_TUD_AUDIO_ENABLE_EP_IN 1 +#define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup +#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 4 // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup +#define CFG_TUD_AUDIO_EP_SZ_IN (48 + 1) * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX // 48 Samples (48 kHz) x 2 Bytes/Sample x CFG_TUD_AUDIO_N_CHANNELS_TX Channels - the Windows driver always needs an extra sample per channel of space more, otherwise it complains... found by trial and error +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ CFG_TUD_AUDIO_EP_SZ_IN -#define CFG_TUD_AUDIO_ENABLE_ENCODING 1 -#define CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING 1 -#define CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX 2 // One I2S stream contains two channels, each stream is saved within one support FIFO - this value is currently fixed, the driver does not support a changing value -#define CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO (CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX / CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX) -#define CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ (CFG_TUD_AUDIO_EP_SZ_IN / CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO) +#define CFG_TUD_AUDIO_ENABLE_ENCODING 1 +#define CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING 1 +#define CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX 2 // One I2S stream contains two channels, each stream is saved within one support FIFO - this value is currently fixed, the driver does not support a changing value +#define CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO (CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX / CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX) +#define CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ (CFG_TUD_AUDIO_EP_SZ_IN / CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO) #ifdef __cplusplus } diff --git a/examples/device/board_test/src/tusb_config.h b/examples/device/board_test/src/tusb_config.h index da33729e7..5aea4fd2c 100644 --- a/examples/device/board_test/src/tusb_config.h +++ b/examples/device/board_test/src/tusb_config.h @@ -43,7 +43,9 @@ #define CFG_TUSB_OS OPT_OS_NONE #endif -#define CFG_TUSB_RHPORT0_MODE OPT_MODE_NONE +// This example only test LED & GPIO, disable both device and host stack +#define CFG_TUD_ENABLED 0 +#define CFG_TUH_ENABLED 0 // CFG_TUSB_DEBUG is defined by compiler in DEBUG build // #define CFG_TUSB_DEBUG 0 @@ -63,21 +65,6 @@ #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_CDC 0 -#define CFG_TUD_MSC 0 -#define CFG_TUD_HID 0 -#define CFG_TUD_MIDI 0 -#define CFG_TUD_VENDOR 0 - #ifdef __cplusplus } #endif diff --git a/examples/device/cdc_msc/src/tusb_config.h b/examples/device/cdc_msc/src/tusb_config.h index 363da88d7..03e0e649c 100644 --- a/examples/device/cdc_msc/src/tusb_config.h +++ b/examples/device/cdc_msc/src/tusb_config.h @@ -30,42 +30,43 @@ 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 +// Common Configuration //-------------------------------------------------------------------- -// defined by board.mk +// defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU - #error CFG_TUSB_MCU must be defined +#error CFG_TUSB_MCU must be defined #endif -// This example doesn't use an RTOS #ifndef CFG_TUSB_OS - #define CFG_TUSB_OS OPT_OS_NONE +#define CFG_TUSB_OS OPT_OS_NONE #endif -// CFG_TUSB_DEBUG is defined by compiler in DEBUG build #ifndef CFG_TUSB_DEBUG - #define CFG_TUSB_DEBUG 0 +#define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 -// 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 - // 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. @@ -78,7 +79,7 @@ #endif #ifndef CFG_TUSB_MEM_ALIGN -#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- diff --git a/examples/device/cdc_msc_freertos/src/main.c b/examples/device/cdc_msc_freertos/src/main.c index a5e907199..755220c13 100644 --- a/examples/device/cdc_msc_freertos/src/main.c +++ b/examples/device/cdc_msc_freertos/src/main.c @@ -123,9 +123,10 @@ void usb_device_task(void* param) { (void) param; + // init device stack on configured roothub port // This should be called after scheduler/kernel is started. // Otherwise it could cause kernel issue since USB IRQ handler does use RTOS queue API. - tusb_init(); + tud_init(BOARD_TUD_RHPORT); // RTOS forever loop while (1) diff --git a/examples/device/cdc_msc_freertos/src/tusb_config.h b/examples/device/cdc_msc_freertos/src/tusb_config.h index d8eeda07d..0ec8896b9 100644 --- a/examples/device/cdc_msc_freertos/src/tusb_config.h +++ b/examples/device/cdc_msc_freertos/src/tusb_config.h @@ -30,53 +30,48 @@ 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 board.mk #ifndef CFG_TUSB_MCU - #error CFG_TUSB_MCU must be defined -#endif - -// 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 -// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed -#ifndef BOARD_TUD_MAX_SPEED - #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ - CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56) - #define BOARD_TUD_MAX_SPEED OPT_MODE_HIGH_SPEED - #else - #define BOARD_TUD_MAX_SPEED OPT_MODE_FULL_SPEED - #endif -#endif - -// Device mode with rhport and speed defined by board.mk -#if BOARD_TUD_RHPORT == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#elif BOARD_TUD_RHPORT == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#else - #error "Incorrect RHPort configuration" +#error CFG_TUSB_MCU must be defined #endif // This examples use FreeRTOS -#define CFG_TUSB_OS OPT_OS_FREERTOS +#define CFG_TUSB_OS OPT_OS_FREERTOS // Espressif IDF requires "freertos/" prefix in include path #if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) - #define CFG_TUSB_OS_INC_PATH freertos/ +#define CFG_TUSB_OS_INC_PATH freertos/ #endif // can be defined by compiler in DEBUG build #ifndef CFG_TUSB_DEBUG - #define CFG_TUSB_DEBUG 0 +#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. @@ -89,7 +84,7 @@ #endif #ifndef CFG_TUSB_MEM_ALIGN -#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- @@ -97,7 +92,7 @@ //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE -#define CFG_TUD_ENDPOINT0_SIZE 64 +#define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// From 9794a2b865df81e667b464481bb9b1c70587e64b Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 6 Jun 2022 22:41:04 +0700 Subject: [PATCH 366/504] more example update --- .../audio_4_channel_mic/src/tusb_config.h | 6 ++ examples/device/audio_test/src/main.c | 3 +- examples/device/audio_test/src/tusb_config.h | 24 +++++++- examples/device/cdc_dual_ports/src/main.c | 3 +- .../device/cdc_dual_ports/src/tusb_config.h | 49 ++++++++-------- examples/device/dfu/src/main.c | 3 +- examples/device/dfu/src/tusb_config.h | 57 ++++++++++--------- examples/device/dfu_runtime/src/main.c | 3 +- examples/device/dfu_runtime/src/tusb_config.h | 51 +++++++++-------- .../device/dynamic_configuration/src/main.c | 4 +- .../dynamic_configuration/src/tusb_config.h | 53 ++++++++--------- examples/device/hid_boot_interface/src/main.c | 4 +- .../hid_boot_interface/src/tusb_config.h | 57 +++++++++---------- examples/device/hid_composite/src/main.c | 4 +- .../device/hid_composite/src/tusb_config.h | 51 +++++++++-------- .../device/hid_composite_freertos/src/main.c | 3 +- .../hid_composite_freertos/src/tusb_config.h | 50 ++++++++-------- examples/device/hid_generic_inout/src/main.c | 3 +- .../hid_generic_inout/src/tusb_config.h | 53 ++++++++--------- .../device/hid_multiple_interface/src/main.c | 4 +- .../hid_multiple_interface/src/tusb_config.h | 51 +++++++++-------- examples/device/midi_test/src/main.c | 3 +- examples/device/midi_test/src/tusb_config.h | 53 ++++++++--------- examples/device/msc_dual_lun/src/main.c | 3 +- .../device/msc_dual_lun/src/tusb_config.h | 53 ++++++++--------- examples/device/net_lwip_webserver/src/main.c | 4 +- .../net_lwip_webserver/src/tusb_config.h | 45 ++++++++------- examples/device/uac2_headset/src/main.c | 3 +- .../device/uac2_headset/src/tusb_config.h | 39 +++++++++---- examples/device/usbtmc/src/main.c | 3 +- examples/device/usbtmc/src/tusb_config.h | 45 ++++++++------- examples/device/video_capture/src/main.c | 4 +- .../device/video_capture/src/tusb_config.h | 41 +++++++------ examples/device/webusb_serial/src/main.c | 3 +- .../device/webusb_serial/src/tusb_config.h | 45 ++++++++------- 35 files changed, 478 insertions(+), 402 deletions(-) diff --git a/examples/device/audio_4_channel_mic/src/tusb_config.h b/examples/device/audio_4_channel_mic/src/tusb_config.h index 0f5fbfef7..5cf6d07c3 100644 --- a/examples/device/audio_4_channel_mic/src/tusb_config.h +++ b/examples/device/audio_4_channel_mic/src/tusb_config.h @@ -90,7 +90,13 @@ extern "C" { #define CFG_TUD_ENDPOINT0_SIZE 64 #endif +//------------- CLASS -------------// #define CFG_TUD_AUDIO 1 +#define CFG_TUD_CDC 0 +#define CFG_TUD_MSC 0 +#define CFG_TUD_HID 0 +#define CFG_TUD_MIDI 0 +#define CFG_TUD_VENDOR 0 //-------------------------------------------------------------------- // AUDIO CLASS DRIVER CONFIGURATION diff --git a/examples/device/audio_test/src/main.c b/examples/device/audio_test/src/main.c index ed13ce993..51f55b772 100644 --- a/examples/device/audio_test/src/main.c +++ b/examples/device/audio_test/src/main.c @@ -82,7 +82,8 @@ int main(void) { board_init(); - tusb_init(); + // init device stack on configured roothub port + tud_init(BOARD_TUD_RHPORT); // Init values sampFreq = AUDIO_SAMPLE_RATE; diff --git a/examples/device/audio_test/src/tusb_config.h b/examples/device/audio_test/src/tusb_config.h index 9b8514265..355ed1011 100644 --- a/examples/device/audio_test/src/tusb_config.h +++ b/examples/device/audio_test/src/tusb_config.h @@ -30,6 +30,20 @@ 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 //-------------------------------------------------------------------- @@ -39,8 +53,6 @@ extern "C" { #error CFG_TUSB_MCU must be defined #endif -#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE - #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif @@ -49,6 +61,12 @@ extern "C" { #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 + // CFG_TUSB_DEBUG is defined by compiler in DEBUG build // #define CFG_TUSB_DEBUG 0 @@ -76,11 +94,11 @@ extern "C" { #endif //------------- CLASS -------------// +#define CFG_TUD_AUDIO 1 #define CFG_TUD_CDC 0 #define CFG_TUD_MSC 0 #define CFG_TUD_HID 0 #define CFG_TUD_MIDI 0 -#define CFG_TUD_AUDIO 1 #define CFG_TUD_VENDOR 0 //-------------------------------------------------------------------- diff --git a/examples/device/cdc_dual_ports/src/main.c b/examples/device/cdc_dual_ports/src/main.c index 34cd29edd..6053a3b81 100644 --- a/examples/device/cdc_dual_ports/src/main.c +++ b/examples/device/cdc_dual_ports/src/main.c @@ -39,7 +39,8 @@ int main(void) { board_init(); - tusb_init(); + // init device stack on configured roothub port + tud_init(BOARD_TUD_RHPORT); while (1) { diff --git a/examples/device/cdc_dual_ports/src/tusb_config.h b/examples/device/cdc_dual_ports/src/tusb_config.h index 037fc8290..070f08ed1 100644 --- a/examples/device/cdc_dual_ports/src/tusb_config.h +++ b/examples/device/cdc_dual_ports/src/tusb_config.h @@ -30,41 +30,42 @@ 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 board.mk #ifndef CFG_TUSB_MCU - #error CFG_TUSB_MCU must be defined -#endif - -// 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 -// Default to max (auto) speed for MCU with internal HighSpeed PHY -#ifndef BOARD_TUD_MAX_SPEED - #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED -#endif - -// Device mode with rhport and speed defined by board.mk -#if BOARD_TUD_RHPORT == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#elif BOARD_TUD_RHPORT == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#else - #error "Incorrect RHPort configuration" +#error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS -#define CFG_TUSB_OS OPT_OS_NONE +#define CFG_TUSB_OS OPT_OS_NONE #endif -// CFG_TUSB_DEBUG is defined by compiler in DEBUG build -// #define CFG_TUSB_DEBUG 0 +#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 diff --git a/examples/device/dfu/src/main.c b/examples/device/dfu/src/main.c index 5c8464526..6bb183819 100644 --- a/examples/device/dfu/src/main.c +++ b/examples/device/dfu/src/main.c @@ -74,7 +74,8 @@ int main(void) { board_init(); - tusb_init(); + // init device stack on configured roothub port + tud_init(BOARD_TUD_RHPORT); while (1) { diff --git a/examples/device/dfu/src/tusb_config.h b/examples/device/dfu/src/tusb_config.h index 924ede47a..38064147c 100644 --- a/examples/device/dfu/src/tusb_config.h +++ b/examples/device/dfu/src/tusb_config.h @@ -12,41 +12,42 @@ 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 board.mk +// defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU - #error CFG_TUSB_MCU must be defined -#endif - -// 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 -// Default to max (auto) speed for MCU with internal HighSpeed PHY -#ifndef BOARD_TUD_MAX_SPEED - #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED -#endif - -// Device mode with rhport and speed defined by board.mk -#if BOARD_TUD_RHPORT == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#elif BOARD_TUD_RHPORT == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#else - #error "Incorrect RHPort configuration" +#error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS -#define CFG_TUSB_OS OPT_OS_NONE +#define CFG_TUSB_OS OPT_OS_NONE #endif -// CFG_TUSB_DEBUG is defined by compiler in DEBUG build -// #define CFG_TUSB_DEBUG 0 +#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 @@ -60,7 +61,7 @@ #endif #ifndef CFG_TUSB_MEM_ALIGN -#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- @@ -72,10 +73,10 @@ #endif //------------- CLASS -------------// -#define CFG_TUD_DFU 1 +#define CFG_TUD_DFU 1 // DFU buffer size, it has to be set to the buffer size used in TUD_DFU_DESCRIPTOR -#define CFG_TUD_DFU_XFER_BUFSIZE ( OPT_MODE_HIGH_SPEED ? 512 : 64 ) +#define CFG_TUD_DFU_XFER_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #ifdef __cplusplus } diff --git a/examples/device/dfu_runtime/src/main.c b/examples/device/dfu_runtime/src/main.c index 823c71ae5..55b380353 100644 --- a/examples/device/dfu_runtime/src/main.c +++ b/examples/device/dfu_runtime/src/main.c @@ -69,7 +69,8 @@ int main(void) { board_init(); - tusb_init(); + // init device stack on configured roothub port + tud_init(BOARD_TUD_RHPORT); while (1) { diff --git a/examples/device/dfu_runtime/src/tusb_config.h b/examples/device/dfu_runtime/src/tusb_config.h index f31c9c970..fa1ae6ed3 100644 --- a/examples/device/dfu_runtime/src/tusb_config.h +++ b/examples/device/dfu_runtime/src/tusb_config.h @@ -12,41 +12,42 @@ 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 board.mk +// defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU - #error CFG_TUSB_MCU must be defined -#endif - -// 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 -// Default to max (auto) speed for MCU with internal HighSpeed PHY -#ifndef BOARD_TUD_MAX_SPEED - #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED -#endif - -// Device mode with rhport and speed defined by board.mk -#if BOARD_TUD_RHPORT == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#elif BOARD_TUD_RHPORT == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#else - #error "Incorrect RHPort configuration" +#error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS -#define CFG_TUSB_OS OPT_OS_NONE +#define CFG_TUSB_OS OPT_OS_NONE #endif -// CFG_TUSB_DEBUG is defined by compiler in DEBUG build -// #define CFG_TUSB_DEBUG 0 +#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 diff --git a/examples/device/dynamic_configuration/src/main.c b/examples/device/dynamic_configuration/src/main.c index 4c10f55b0..95f8b8286 100644 --- a/examples/device/dynamic_configuration/src/main.c +++ b/examples/device/dynamic_configuration/src/main.c @@ -55,7 +55,9 @@ void midi_task(void); int main(void) { board_init(); - tusb_init(); + + // init device stack on configured roothub port + tud_init(BOARD_TUD_RHPORT); while (1) { diff --git a/examples/device/dynamic_configuration/src/tusb_config.h b/examples/device/dynamic_configuration/src/tusb_config.h index 333b62e03..b9b3878cc 100644 --- a/examples/device/dynamic_configuration/src/tusb_config.h +++ b/examples/device/dynamic_configuration/src/tusb_config.h @@ -30,41 +30,42 @@ 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 board.mk +// defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU - #error CFG_TUSB_MCU must be defined -#endif - -// 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 -// Default to max (auto) speed for MCU with internal HighSpeed PHY -#ifndef BOARD_TUD_MAX_SPEED - #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED -#endif - -// Device mode with rhport and speed defined by board.mk -#if BOARD_TUD_RHPORT == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#elif BOARD_TUD_RHPORT == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#else - #error "Incorrect RHPort configuration" +#error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS -#define CFG_TUSB_OS OPT_OS_NONE +#define CFG_TUSB_OS OPT_OS_NONE #endif -// CFG_TUSB_DEBUG is defined by compiler in DEBUG build -// #define CFG_TUSB_DEBUG 0 +#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 @@ -78,7 +79,7 @@ #endif #ifndef CFG_TUSB_MEM_ALIGN -#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- diff --git a/examples/device/hid_boot_interface/src/main.c b/examples/device/hid_boot_interface/src/main.c index e5e2f6856..21cdb383d 100644 --- a/examples/device/hid_boot_interface/src/main.c +++ b/examples/device/hid_boot_interface/src/main.c @@ -55,7 +55,9 @@ void hid_task(void); int main(void) { board_init(); - tusb_init(); + + // init device stack on configured roothub port + tud_init(BOARD_TUD_RHPORT); while (1) { diff --git a/examples/device/hid_boot_interface/src/tusb_config.h b/examples/device/hid_boot_interface/src/tusb_config.h index e3c50aa3f..52723e09f 100644 --- a/examples/device/hid_boot_interface/src/tusb_config.h +++ b/examples/device/hid_boot_interface/src/tusb_config.h @@ -30,45 +30,42 @@ 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 board.mk +// defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU - #error CFG_TUSB_MCU must be defined -#endif - -// Use raspberry pio-usb for device -// #define CFG_TUD_RPI_PIO_USB 1 -// #define BOARD_TUD_RHPORT 1 - -// 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 -// Default to max (auto) speed for MCU with internal HighSpeed PHY -#ifndef BOARD_TUD_MAX_SPEED - #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED -#endif - -// Device mode with rhport and speed defined by board.mk -#if BOARD_TUD_RHPORT == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#elif BOARD_TUD_RHPORT == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#else - #error "Incorrect RHPort configuration" +#error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS -#define CFG_TUSB_OS OPT_OS_NONE +#define CFG_TUSB_OS OPT_OS_NONE #endif -// CFG_TUSB_DEBUG is defined by compiler in DEBUG build -// #define CFG_TUSB_DEBUG 0 +#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 @@ -82,7 +79,7 @@ #endif #ifndef CFG_TUSB_MEM_ALIGN -#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- diff --git a/examples/device/hid_composite/src/main.c b/examples/device/hid_composite/src/main.c index fd25e620a..bc2347ab8 100644 --- a/examples/device/hid_composite/src/main.c +++ b/examples/device/hid_composite/src/main.c @@ -56,7 +56,9 @@ void hid_task(void); int main(void) { board_init(); - tusb_init(); + + // init device stack on configured roothub port + tud_init(BOARD_TUD_RHPORT); while (1) { diff --git a/examples/device/hid_composite/src/tusb_config.h b/examples/device/hid_composite/src/tusb_config.h index 1a9223f5b..6bd32c427 100644 --- a/examples/device/hid_composite/src/tusb_config.h +++ b/examples/device/hid_composite/src/tusb_config.h @@ -30,41 +30,42 @@ 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 board.mk +// defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU - #error CFG_TUSB_MCU must be defined -#endif - -// 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 -// Default to max (auto) speed for MCU with internal HighSpeed PHY -#ifndef BOARD_TUD_MAX_SPEED - #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED -#endif - -// Device mode with rhport and speed defined by board.mk -#if BOARD_TUD_RHPORT == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#elif BOARD_TUD_RHPORT == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#else - #error "Incorrect RHPort configuration" +#error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS -#define CFG_TUSB_OS OPT_OS_NONE +#define CFG_TUSB_OS OPT_OS_NONE #endif -// CFG_TUSB_DEBUG is defined by compiler in DEBUG build -// #define CFG_TUSB_DEBUG 0 +#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 diff --git a/examples/device/hid_composite_freertos/src/main.c b/examples/device/hid_composite_freertos/src/main.c index 317b64611..1030f3d05 100644 --- a/examples/device/hid_composite_freertos/src/main.c +++ b/examples/device/hid_composite_freertos/src/main.c @@ -125,9 +125,10 @@ void usb_device_task(void* param) { (void) param; + // init device stack on configured roothub port // This should be called after scheduler/kernel is started. // Otherwise it could cause kernel issue since USB IRQ handler does use RTOS queue API. - tusb_init(); + tud_init(BOARD_TUD_RHPORT); // RTOS forever loop while (1) diff --git a/examples/device/hid_composite_freertos/src/tusb_config.h b/examples/device/hid_composite_freertos/src/tusb_config.h index 8fd6498e6..935ae9453 100644 --- a/examples/device/hid_composite_freertos/src/tusb_config.h +++ b/examples/device/hid_composite_freertos/src/tusb_config.h @@ -30,48 +30,48 @@ 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 board.mk #ifndef CFG_TUSB_MCU - #error CFG_TUSB_MCU must be defined -#endif - -// 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 -// Default to max (auto) speed for MCU with internal HighSpeed PHY -#ifndef BOARD_TUD_MAX_SPEED - #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED -#endif - -// Device mode with rhport and speed defined by board.mk -#if BOARD_TUD_RHPORT == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#elif BOARD_TUD_RHPORT == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#else - #error "Incorrect RHPort configuration" +#error CFG_TUSB_MCU must be defined #endif // This examples use FreeRTOS -#define CFG_TUSB_OS OPT_OS_FREERTOS +#define CFG_TUSB_OS OPT_OS_FREERTOS // Espressif IDF requires "freertos/" prefix in include path #if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) - #define CFG_TUSB_OS_INC_PATH freertos/ +#define CFG_TUSB_OS_INC_PATH freertos/ #endif - +// can be defined by compiler in DEBUG build #ifndef CFG_TUSB_DEBUG -#define CFG_TUSB_DEBUG 0 +#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. diff --git a/examples/device/hid_generic_inout/src/main.c b/examples/device/hid_generic_inout/src/main.c index 32185560e..5b7daf118 100644 --- a/examples/device/hid_generic_inout/src/main.c +++ b/examples/device/hid_generic_inout/src/main.c @@ -80,7 +80,8 @@ int main(void) { board_init(); - tusb_init(); + // init device stack on configured roothub port + tud_init(BOARD_TUD_RHPORT); while (1) { diff --git a/examples/device/hid_generic_inout/src/tusb_config.h b/examples/device/hid_generic_inout/src/tusb_config.h index e5ae4b0cc..98143ac4d 100644 --- a/examples/device/hid_generic_inout/src/tusb_config.h +++ b/examples/device/hid_generic_inout/src/tusb_config.h @@ -30,41 +30,42 @@ 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 board.mk +// defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU - #error CFG_TUSB_MCU must be defined -#endif - -// 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 -// Default to max (auto) speed for MCU with internal HighSpeed PHY -#ifndef BOARD_TUD_MAX_SPEED - #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED -#endif - -// Device mode with rhport and speed defined by board.mk -#if BOARD_TUD_RHPORT == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#elif BOARD_TUD_RHPORT == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#else - #error "Incorrect RHPort configuration" +#error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS -#define CFG_TUSB_OS OPT_OS_NONE +#define CFG_TUSB_OS OPT_OS_NONE #endif -// CFG_TUSB_DEBUG is defined by compiler in DEBUG build -// #define CFG_TUSB_DEBUG 0 +#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 @@ -78,7 +79,7 @@ #endif #ifndef CFG_TUSB_MEM_ALIGN -#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- diff --git a/examples/device/hid_multiple_interface/src/main.c b/examples/device/hid_multiple_interface/src/main.c index 7cb1d75a7..29ba74398 100644 --- a/examples/device/hid_multiple_interface/src/main.c +++ b/examples/device/hid_multiple_interface/src/main.c @@ -60,7 +60,9 @@ void hid_task(void); int main(void) { board_init(); - tusb_init(); + + // init device stack on configured roothub port + tud_init(BOARD_TUD_RHPORT); while (1) { diff --git a/examples/device/hid_multiple_interface/src/tusb_config.h b/examples/device/hid_multiple_interface/src/tusb_config.h index 766b8e518..49dc962fe 100644 --- a/examples/device/hid_multiple_interface/src/tusb_config.h +++ b/examples/device/hid_multiple_interface/src/tusb_config.h @@ -30,41 +30,42 @@ 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 board.mk +// defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU - #error CFG_TUSB_MCU must be defined -#endif - -// 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 -// Default to max (auto) speed for MCU with internal HighSpeed PHY -#ifndef BOARD_TUD_MAX_SPEED - #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED -#endif - -// Device mode with rhport and speed defined by board.mk -#if BOARD_TUD_RHPORT == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#elif BOARD_TUD_RHPORT == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#else - #error "Incorrect RHPort configuration" +#error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS -#define CFG_TUSB_OS OPT_OS_NONE +#define CFG_TUSB_OS OPT_OS_NONE #endif -// CFG_TUSB_DEBUG is defined by compiler in DEBUG build -// #define CFG_TUSB_DEBUG 0 +#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 diff --git a/examples/device/midi_test/src/main.c b/examples/device/midi_test/src/main.c index 193748477..b47d1af76 100644 --- a/examples/device/midi_test/src/main.c +++ b/examples/device/midi_test/src/main.c @@ -62,7 +62,8 @@ int main(void) { board_init(); - tusb_init(); + // init device stack on configured roothub port + tud_init(BOARD_TUD_RHPORT); while (1) { diff --git a/examples/device/midi_test/src/tusb_config.h b/examples/device/midi_test/src/tusb_config.h index a7673245e..314dde438 100644 --- a/examples/device/midi_test/src/tusb_config.h +++ b/examples/device/midi_test/src/tusb_config.h @@ -30,41 +30,42 @@ 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 board.mk +// defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU - #error CFG_TUSB_MCU must be defined -#endif - -// 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 -// Default to max (auto) speed for MCU with internal HighSpeed PHY -#ifndef BOARD_TUD_MAX_SPEED - #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED -#endif - -// Device mode with rhport and speed defined by board.mk -#if BOARD_TUD_RHPORT == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#elif BOARD_TUD_RHPORT == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#else - #error "Incorrect RHPort configuration" +#error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS -#define CFG_TUSB_OS OPT_OS_NONE +#define CFG_TUSB_OS OPT_OS_NONE #endif -// CFG_TUSB_DEBUG is defined by compiler in DEBUG build -// #define CFG_TUSB_DEBUG 0 +#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 @@ -78,7 +79,7 @@ #endif #ifndef CFG_TUSB_MEM_ALIGN -#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- diff --git a/examples/device/msc_dual_lun/src/main.c b/examples/device/msc_dual_lun/src/main.c index 0293261ad..96790d20c 100644 --- a/examples/device/msc_dual_lun/src/main.c +++ b/examples/device/msc_dual_lun/src/main.c @@ -54,7 +54,8 @@ int main(void) { board_init(); - tusb_init(); + // init device stack on configured roothub port + tud_init(BOARD_TUD_RHPORT); while (1) { diff --git a/examples/device/msc_dual_lun/src/tusb_config.h b/examples/device/msc_dual_lun/src/tusb_config.h index 2778e61b0..9cbbbade9 100644 --- a/examples/device/msc_dual_lun/src/tusb_config.h +++ b/examples/device/msc_dual_lun/src/tusb_config.h @@ -30,41 +30,42 @@ 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 board.mk +// defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU - #error CFG_TUSB_MCU must be defined -#endif - -// 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 -// Default to max (auto) speed for MCU with internal HighSpeed PHY -#ifndef BOARD_TUD_MAX_SPEED - #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED -#endif - -// Device mode with rhport and speed defined by board.mk -#if BOARD_TUD_RHPORT == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#elif BOARD_TUD_RHPORT == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#else - #error "Incorrect RHPort configuration" +#error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS -#define CFG_TUSB_OS OPT_OS_NONE +#define CFG_TUSB_OS OPT_OS_NONE #endif -// CFG_TUSB_DEBUG is defined by compiler in DEBUG build -// #define CFG_TUSB_DEBUG 0 +#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 @@ -78,7 +79,7 @@ #endif #ifndef CFG_TUSB_MEM_ALIGN -#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- diff --git a/examples/device/net_lwip_webserver/src/main.c b/examples/device/net_lwip_webserver/src/main.c index 30bb3577b..33b4d38b6 100644 --- a/examples/device/net_lwip_webserver/src/main.c +++ b/examples/device/net_lwip_webserver/src/main.c @@ -228,7 +228,9 @@ int main(void) { /* initialize TinyUSB */ board_init(); - tusb_init(); + + // init device stack on configured roothub port + tud_init(BOARD_TUD_RHPORT); /* initialize lwip, dhcp-server, dns-server, and http */ init_lwip(); diff --git a/examples/device/net_lwip_webserver/src/tusb_config.h b/examples/device/net_lwip_webserver/src/tusb_config.h index 5042c0e5d..fe72ecdfe 100644 --- a/examples/device/net_lwip_webserver/src/tusb_config.h +++ b/examples/device/net_lwip_webserver/src/tusb_config.h @@ -30,41 +30,42 @@ extern "C" { #endif -//-------------------------------------------------------------------- -// COMMON CONFIGURATION -//-------------------------------------------------------------------- - -// defined by board.mk -#ifndef CFG_TUSB_MCU - #error CFG_TUSB_MCU must be defined -#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 +#define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk -// Default to max (auto) speed for MCU with internal HighSpeed PHY #ifndef BOARD_TUD_MAX_SPEED - #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED +#define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif -// Device mode with rhport and speed defined by board.mk -#if BOARD_TUD_RHPORT == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#elif BOARD_TUD_RHPORT == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#else - #error "Incorrect RHPort configuration" +//-------------------------------------------------------------------- +// 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 +#define CFG_TUSB_OS OPT_OS_NONE #endif -// CFG_TUSB_DEBUG is defined by compiler in DEBUG build -// #define CFG_TUSB_DEBUG 0 +#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 @@ -78,7 +79,7 @@ #endif #ifndef CFG_TUSB_MEM_ALIGN -#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- diff --git a/examples/device/uac2_headset/src/main.c b/examples/device/uac2_headset/src/main.c index bbaacd975..a8d204eaa 100644 --- a/examples/device/uac2_headset/src/main.c +++ b/examples/device/uac2_headset/src/main.c @@ -102,7 +102,8 @@ int main(void) { board_init(); - tusb_init(); + // init device stack on configured roothub port + tud_init(BOARD_TUD_RHPORT); TU_LOG1("Headset running\r\n"); diff --git a/examples/device/uac2_headset/src/tusb_config.h b/examples/device/uac2_headset/src/tusb_config.h index 2a1189a79..1a3e23e95 100644 --- a/examples/device/uac2_headset/src/tusb_config.h +++ b/examples/device/uac2_headset/src/tusb_config.h @@ -31,30 +31,45 @@ extern "C" { #endif -//-------------------------------------------------------------------- -// COMMON CONFIGURATION -//-------------------------------------------------------------------- - #include "usb_descriptors.h" +//--------------------------------------------------------------------+ +// 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 -#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE - #ifndef CFG_TUSB_OS -#define CFG_TUSB_OS OPT_OS_NONE +#define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG -// Can be set during compilation i.e.: make LOG= BOARD= -// Keep in mind that enabling logs when data is streaming can disrupt data flow. -// It can be very helpful though when audio unit requests are tested/debugged. -#define CFG_TUSB_DEBUG 0 +#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. @@ -67,7 +82,7 @@ extern "C" { #endif #ifndef CFG_TUSB_MEM_ALIGN -#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- diff --git a/examples/device/usbtmc/src/main.c b/examples/device/usbtmc/src/main.c index 1fce48f45..6945d8743 100644 --- a/examples/device/usbtmc/src/main.c +++ b/examples/device/usbtmc/src/main.c @@ -54,7 +54,8 @@ int main(void) { board_init(); - tusb_init(); + // init device stack on configured roothub port + tud_init(BOARD_TUD_RHPORT); while (1) { diff --git a/examples/device/usbtmc/src/tusb_config.h b/examples/device/usbtmc/src/tusb_config.h index 0b2df291a..ab486b108 100644 --- a/examples/device/usbtmc/src/tusb_config.h +++ b/examples/device/usbtmc/src/tusb_config.h @@ -12,41 +12,42 @@ extern "C" { #endif -//-------------------------------------------------------------------- -// COMMON CONFIGURATION -//-------------------------------------------------------------------- - -// defined by board.mk -#ifndef CFG_TUSB_MCU - #error CFG_TUSB_MCU must be defined -#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 +#define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk -// Default to max (auto) speed for MCU with internal HighSpeed PHY #ifndef BOARD_TUD_MAX_SPEED - #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED +#define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif -// Device mode with rhport and speed defined by board.mk -#if BOARD_TUD_RHPORT == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#elif BOARD_TUD_RHPORT == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#else - #error "Incorrect RHPort configuration" +//-------------------------------------------------------------------- +// 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 +#define CFG_TUSB_OS OPT_OS_NONE #endif -// CFG_TUSB_DEBUG is defined by compiler in DEBUG build -// #define CFG_TUSB_DEBUG 0 +#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 @@ -60,7 +61,7 @@ #endif #ifndef CFG_TUSB_MEM_ALIGN -#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- diff --git a/examples/device/video_capture/src/main.c b/examples/device/video_capture/src/main.c index f1d48385f..4028352da 100644 --- a/examples/device/video_capture/src/main.c +++ b/examples/device/video_capture/src/main.c @@ -55,7 +55,9 @@ void video_task(void); int main(void) { board_init(); - tusb_init(); + + // init device stack on configured roothub port + tud_init(BOARD_TUD_RHPORT); while (1) { diff --git a/examples/device/video_capture/src/tusb_config.h b/examples/device/video_capture/src/tusb_config.h index 85bf80a64..e567ba669 100644 --- a/examples/device/video_capture/src/tusb_config.h +++ b/examples/device/video_capture/src/tusb_config.h @@ -30,37 +30,42 @@ extern "C" { #endif -//-------------------------------------------------------------------- -// COMMON CONFIGURATION -//-------------------------------------------------------------------- +//--------------------------------------------------------------------+ +// 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 +#define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk -// Default to max (auto) speed for MCU with internal HighSpeed PHY #ifndef BOARD_TUD_MAX_SPEED - #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED +#define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif -// Device mode with rhport and speed defined by board.mk -#if BOARD_TUD_RHPORT == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#elif BOARD_TUD_RHPORT == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#else - #error "Incorrect RHPort configuration" +//-------------------------------------------------------------------- +// Common Configuration +//-------------------------------------------------------------------- + +// defined by compiler flags for flexibility +#ifndef CFG_TUSB_MCU +#error CFG_TUSB_MCU must be defined #endif -// This example doesn't use an RTOS #ifndef CFG_TUSB_OS -#define CFG_TUSB_OS OPT_OS_NONE +#define CFG_TUSB_OS OPT_OS_NONE #endif -// CFG_TUSB_DEBUG is defined by compiler in DEBUG build -// #define CFG_TUSB_DEBUG 0 +#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 @@ -74,7 +79,7 @@ #endif #ifndef CFG_TUSB_MEM_ALIGN -#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- diff --git a/examples/device/webusb_serial/src/main.c b/examples/device/webusb_serial/src/main.c index 2716825f8..8eaad7706 100644 --- a/examples/device/webusb_serial/src/main.c +++ b/examples/device/webusb_serial/src/main.c @@ -93,7 +93,8 @@ int main(void) { board_init(); - tusb_init(); + // init device stack on configured roothub port + tud_init(BOARD_TUD_RHPORT); while (1) { diff --git a/examples/device/webusb_serial/src/tusb_config.h b/examples/device/webusb_serial/src/tusb_config.h index eab1d6387..fde732b9e 100644 --- a/examples/device/webusb_serial/src/tusb_config.h +++ b/examples/device/webusb_serial/src/tusb_config.h @@ -30,41 +30,42 @@ extern "C" { #endif -//-------------------------------------------------------------------- -// COMMON CONFIGURATION -//-------------------------------------------------------------------- - -// defined by board.mk -#ifndef CFG_TUSB_MCU - #error CFG_TUSB_MCU must be defined -#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 +#define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk -// Default to max (auto) speed for MCU with internal HighSpeed PHY #ifndef BOARD_TUD_MAX_SPEED - #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED +#define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif -// Device mode with rhport and speed defined by board.mk -#if BOARD_TUD_RHPORT == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#elif BOARD_TUD_RHPORT == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#else - #error "Incorrect RHPort configuration" +//-------------------------------------------------------------------- +// 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 +#define CFG_TUSB_OS OPT_OS_NONE #endif -// CFG_TUSB_DEBUG is defined by compiler in DEBUG build -// #define CFG_TUSB_DEBUG 0 +#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 @@ -78,7 +79,7 @@ #endif #ifndef CFG_TUSB_MEM_ALIGN -#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- From 7c8278303bc14770ea9fcd9f6e4a9dbba32572e3 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 6 Jun 2022 23:16:49 +0700 Subject: [PATCH 367/504] update all host examples --- .../dual/host_hid_to_device_cdc/src/main.c | 4 +- .../host_hid_to_device_cdc/src/tusb_config.h | 106 ++++++++---------- examples/host/bare_api/src/main.c | 6 +- examples/host/bare_api/src/tusb_config.h | 35 ++++-- examples/host/cdc_msc_hid/src/main.c | 3 +- examples/host/cdc_msc_hid/src/tusb_config.h | 42 ++++--- examples/host/hid_controller/src/main.c | 5 +- .../host/hid_controller/src/tusb_config.h | 35 ++++-- src/tusb_option.h | 8 ++ 9 files changed, 141 insertions(+), 103 deletions(-) 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 62ecb2c3f..6a25a28da 100644 --- a/examples/dual/host_hid_to_device_cdc/src/main.c +++ b/examples/dual/host_hid_to_device_cdc/src/main.c @@ -79,7 +79,9 @@ int main(void) printf("TinyUSB Host HID <-> Device CDC Example\r\n"); - tusb_init(); + // init device and host stack on configured roothub port + tud_init(BOARD_TUD_RHPORT); + tuh_init(BOARD_TUH_RHPORT); while (1) { diff --git a/examples/dual/host_hid_to_device_cdc/src/tusb_config.h b/examples/dual/host_hid_to_device_cdc/src/tusb_config.h index 9a8f31da0..f749bd712 100644 --- a/examples/dual/host_hid_to_device_cdc/src/tusb_config.h +++ b/examples/dual/host_hid_to_device_cdc/src/tusb_config.h @@ -30,75 +30,61 @@ 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 + +// RHPort number used for host can be defined by board.mk, default to port 1 +#ifndef BOARD_TUH_RHPORT +#define BOARD_TUH_RHPORT 1 +#endif + +// RHPort max operational speed can defined by board.mk +#ifndef BOARD_TUH_MAX_SPEED +#define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED +#endif + //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- -// defined by board.mk +// defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU - #error CFG_TUSB_MCU must be defined +#error CFG_TUSB_MCU must be defined #endif -// 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 number used for device can be defined by board.mk, default to port 1 -#ifndef BOARD_TUH_RHPORT - #define BOARD_TUH_RHPORT 1 -#endif - -// Use raspberry pio-usb for host -#define CFG_TUH_RPI_PIO_USB 1 - -// RHPort max operational speed can defined by board.mk -// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed -#ifndef BOARD_TUD_MAX_SPEED - #if TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX, OPT_MCU_MIMXRT10XX, OPT_MCU_NUC505) ||\ - TU_CHECK_MCU(OPT_MCU_CXD56, OPT_MCU_SAMX7X, OPT_MCU_BCM2711) ||\ - TU_CHECK_MCU(OPT_MCU_FT90X, OPT_MCU_FT93X) - #define BOARD_TUD_MAX_SPEED OPT_MODE_HIGH_SPEED - #else - #define BOARD_TUD_MAX_SPEED OPT_MODE_FULL_SPEED - #endif -#endif - -// RHPort max operational speed can defined by board.mk -// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed -#ifndef BOARD_TUH_MAX_SPEED - #if TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX, OPT_MCU_MIMXRT10XX, OPT_MCU_NUC505) ||\ - TU_CHECK_MCU(OPT_MCU_CXD56, OPT_MCU_SAMX7X, OPT_MCU_BCM2711) ||\ - TU_CHECK_MCU(OPT_MCU_FT90X, OPT_MCU_FT93X) - #define BOARD_TUH_MAX_SPEED OPT_MODE_HIGH_SPEED - #else - #define BOARD_TUH_MAX_SPEED OPT_MODE_FULL_SPEED - #endif -#endif - -// Device mode with rhport and speed defined by board.mk -#if BOARD_TUD_RHPORT == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#elif BOARD_TUD_RHPORT == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_TUD_MAX_SPEED) -#else - #error "Incorrect RHPort configuration" -#endif - -// Device mode with rhport and speed defined by board.mk -#if BOARD_TUH_RHPORT == 0 - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | BOARD_TUH_MAX_SPEED) -#elif BOARD_TUH_RHPORT == 1 - #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_HOST | BOARD_TUH_MAX_SPEED) -#else - #error "Incorrect RHPort configuration" -#endif - -// This example doesn't use an RTOS #ifndef CFG_TUSB_OS -#define CFG_TUSB_OS OPT_OS_NONE +#define CFG_TUSB_OS OPT_OS_NONE #endif +#ifndef CFG_TUSB_DEBUG +#define CFG_TUSB_DEBUG 0 +#endif + +// Enable Device stack, Default is max speed that hardware controller could support with on-chip PHY +#define CFG_TUD_ENABLED 1 +#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED + +// Enable Host stack, Default is max speed that hardware controller could support with on-chip PHY +#define CFG_TUH_ENABLED 1 +#define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED + +#if CFG_TUSB_MCU == OPT_MCU_RP2040 +// Use pico-pio-usb as host controller for raspberry rp2040 +#define CFG_TUH_RPI_PIO_USB 1 +#endif + + // CFG_TUSB_DEBUG is defined by compiler in DEBUG build // #define CFG_TUSB_DEBUG 0 @@ -114,7 +100,7 @@ #endif #ifndef CFG_TUSB_MEM_ALIGN -#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index eb3f7d8d7..2cc05d34d 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -62,8 +62,10 @@ int main(void) { board_init(); - printf("TinyUSB Host HID Controller Example\r\n"); - tusb_init(); + printf("TinyUSB Bare API Example\r\n"); + + // init host stack on configured roothub port + tuh_init(BOARD_TUH_RHPORT); while (1) { diff --git a/examples/host/bare_api/src/tusb_config.h b/examples/host/bare_api/src/tusb_config.h index 9b789290d..ed0aaf7da 100644 --- a/examples/host/bare_api/src/tusb_config.h +++ b/examples/host/bare_api/src/tusb_config.h @@ -30,27 +30,42 @@ extern "C" { #endif +//--------------------------------------------------------------------+ +// Board Specific Configuration +//--------------------------------------------------------------------+ + +// RHPort number used for host can be defined by board.mk, default to port 0 +#ifndef BOARD_TUH_RHPORT +#define BOARD_TUH_RHPORT 0 +#endif + +// RHPort max operational speed can defined by board.mk +#ifndef BOARD_TUH_MAX_SPEED +#define BOARD_TUH_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 - -#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | OPT_MODE_HIGH_SPEED) -#else - #define CFG_TUSB_RHPORT0_MODE OPT_MODE_HOST +#error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS -#define CFG_TUSB_OS OPT_OS_NONE +#define CFG_TUSB_OS OPT_OS_NONE #endif -// CFG_TUSB_DEBUG is defined by compiler in DEBUG build -// #define CFG_TUSB_DEBUG 0 +#ifndef CFG_TUSB_DEBUG +#define CFG_TUSB_DEBUG 0 +#endif + +// Enable Host stack +#define CFG_TUH_ENABLED 1 + +// Default is max speed that hardware controller could support with on-chip PHY +#define CFG_TUH_MAX_SPEED BOARD_TUH_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 diff --git a/examples/host/cdc_msc_hid/src/main.c b/examples/host/cdc_msc_hid/src/main.c index 0fc7ef146..664cbf035 100644 --- a/examples/host/cdc_msc_hid/src/main.c +++ b/examples/host/cdc_msc_hid/src/main.c @@ -45,7 +45,8 @@ int main(void) printf("TinyUSB Host CDC MSC HID Example\r\n"); - tusb_init(); + // init host stack on configured roothub port + tuh_init(BOARD_TUH_RHPORT); while (1) { diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index e9e68cf5a..76d96b556 100644 --- a/examples/host/cdc_msc_hid/src/tusb_config.h +++ b/examples/host/cdc_msc_hid/src/tusb_config.h @@ -30,34 +30,42 @@ extern "C" { #endif +//--------------------------------------------------------------------+ +// Board Specific Configuration +//--------------------------------------------------------------------+ + +// RHPort number used for host can be defined by board.mk, default to port 0 +#ifndef BOARD_TUH_RHPORT +#define BOARD_TUH_RHPORT 0 +#endif + +// RHPort max operational speed can defined by board.mk +#ifndef BOARD_TUH_MAX_SPEED +#define BOARD_TUH_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 - -// Use raspberry pio-usb for host -// #define CFG_TUH_RPI_PIO_USB 1 -// #define CFG_TUH_RPI_PIO_USB 1 - -#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | OPT_MODE_HIGH_SPEED) -#elif defined(CFG_TUH_RPI_PIO_USB) && CFG_TUH_RPI_PIO_USB - // rp2040: port0 is native, port 1 for PIO-USB - #define CFG_TUSB_RHPORT1_MODE OPT_MODE_HOST -#else - #define CFG_TUSB_RHPORT0_MODE OPT_MODE_HOST +#error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS -#define CFG_TUSB_OS OPT_OS_NONE +#define CFG_TUSB_OS OPT_OS_NONE #endif -// CFG_TUSB_DEBUG is defined by compiler in DEBUG build -// #define CFG_TUSB_DEBUG 0 +#ifndef CFG_TUSB_DEBUG +#define CFG_TUSB_DEBUG 0 +#endif + +// Enable Host stack +#define CFG_TUH_ENABLED 1 + +// Default is max speed that hardware controller could support with on-chip PHY +#define CFG_TUH_MAX_SPEED BOARD_TUH_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 diff --git a/examples/host/hid_controller/src/main.c b/examples/host/hid_controller/src/main.c index b9b37a4d2..299a3ff10 100644 --- a/examples/host/hid_controller/src/main.c +++ b/examples/host/hid_controller/src/main.c @@ -49,9 +49,10 @@ int main(void) board_init(); printf("TinyUSB Host HID Controller Example\r\n"); - printf("Note: Events only displayed for explictly supported controllers\r\n"); + printf("Note: Events only displayed for explicit supported controllers\r\n"); - tusb_init(); + // init host stack on configured roothub port + tuh_init(BOARD_TUH_RHPORT); while (1) { diff --git a/examples/host/hid_controller/src/tusb_config.h b/examples/host/hid_controller/src/tusb_config.h index 74b471ae4..475b9ca8f 100644 --- a/examples/host/hid_controller/src/tusb_config.h +++ b/examples/host/hid_controller/src/tusb_config.h @@ -30,27 +30,42 @@ extern "C" { #endif +//--------------------------------------------------------------------+ +// Board Specific Configuration +//--------------------------------------------------------------------+ + +// RHPort number used for host can be defined by board.mk, default to port 0 +#ifndef BOARD_TUH_RHPORT +#define BOARD_TUH_RHPORT 0 +#endif + +// RHPort max operational speed can defined by board.mk +#ifndef BOARD_TUH_MAX_SPEED +#define BOARD_TUH_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 - -#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | OPT_MODE_HIGH_SPEED) -#else - #define CFG_TUSB_RHPORT0_MODE OPT_MODE_HOST +#error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS -#define CFG_TUSB_OS OPT_OS_NONE +#define CFG_TUSB_OS OPT_OS_NONE #endif -// CFG_TUSB_DEBUG is defined by compiler in DEBUG build -// #define CFG_TUSB_DEBUG 0 +#ifndef CFG_TUSB_DEBUG +#define CFG_TUSB_DEBUG 0 +#endif + +// Enable Host stack +#define CFG_TUH_ENABLED 1 + +// Default is max speed that hardware controller could support with on-chip PHY +#define CFG_TUH_MAX_SPEED BOARD_TUH_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 diff --git a/src/tusb_option.h b/src/tusb_option.h index 0a0b20dca..e332c5728 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -238,11 +238,19 @@ typedef int make_iso_compilers_happy ; #define CFG_TUH_ENABLED (TUH_RHPORT_MODE & OPT_MODE_HOST) #endif +#ifndef CFG_TUH_MAX_SPEED + // fallback to use CFG_TUSB_RHPORTx_MODE + #define CFG_TUH_MAX_SPEED (TUH_RHPORT_MODE & OPT_MODE_SPEED_MASK) +#endif + // For backward compatible #define TUSB_OPT_DEVICE_ENABLED CFG_TUD_ENABLED #define TUSB_OPT_HOST_ENABLED CFG_TUH_ENABLED +//--------------------------------------------------------------------+ // TODO move later +//--------------------------------------------------------------------+ + // TUP_MCU_STRICT_ALIGN will overwrite TUP_ARCH_STRICT_ALIGN. // In case TUP_MCU_STRICT_ALIGN = 1 and TUP_ARCH_STRICT_ALIGN =0, we will not reply on compiler // to generate unaligned access code. From 06392247ebce685a7bd81da4f3f38722767288c2 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 7 Jun 2022 11:50:50 +0700 Subject: [PATCH 368/504] add TU_ATTR_FAST_FUNC for audio sof isr call chain --- src/class/audio/audio_device.c | 2 +- src/class/audio/audio_device.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index a2801e299..dbd8ab54b 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -2114,7 +2114,7 @@ uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles) } #endif -void audiod_sof_isr (uint8_t rhport, uint32_t frame_count) +TU_ATTR_FAST_FUNC void audiod_sof_isr (uint8_t rhport, uint32_t frame_count) { (void) rhport; (void) frame_count; diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index 13f24fb62..0ef100fa4 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -524,10 +524,10 @@ typedef struct { TU_ATTR_WEAK void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedback_params_t* feedback_param); // Callback in ISR context, invoked periodically according to feedback endpoint bInterval. -// Could be used to compute and update feedback value +// Could be used to compute and update feedback value, should be placed in RAM if possible // frame_number : current SOF count // interval_shift: number of bit shift i.e log2(interval) from Feedback endpoint descriptor -TU_ATTR_WEAK void tud_audio_feedback_interval_isr(uint8_t func_id, uint32_t frame_number, uint8_t interval_shift); +TU_ATTR_WEAK TU_ATTR_FAST_FUNC void tud_audio_feedback_interval_isr(uint8_t func_id, uint32_t frame_number, uint8_t interval_shift); #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP From 8cbc34de11ccaaf0831cda14ad703d8d962ae725 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 8 Jun 2022 01:17:01 +0700 Subject: [PATCH 369/504] add tuh_configure() for port/dynamic host behavior config --- hw/bsp/rp2040/family.c | 16 +++++++- src/device/usbd.c | 2 +- src/host/hcd.h | 5 ++- src/host/usbh.c | 39 ++++++++++++------- src/host/usbh.h | 16 +++++++- .../raspberrypi/pio_usb/hcd_pio_usb.c | 12 +++++- 6 files changed, 67 insertions(+), 23 deletions(-) diff --git a/hw/bsp/rp2040/family.c b/hw/bsp/rp2040/family.c index 8de1c1aab..68c9e2d52 100644 --- a/hw/bsp/rp2040/family.c +++ b/hw/bsp/rp2040/family.c @@ -35,6 +35,13 @@ #include "bsp/board.h" #include "board.h" +#if CFG_TUH_RPI_PIO_USB || CFG_TUD_RPI_PIO_USB +#include "pio_usb.h" +#endif + +// PIO_USB_DP_PIN_DEFAULT is 0, which conflict with UART, change to 2 +#define PICO_PIO_USB_PIN_DP 2 + #ifdef BUTTON_BOOTSEL // This example blinks the Picoboard LED when the BOOTSEL button is pressed. // @@ -130,6 +137,12 @@ void board_init(void) #if CFG_TUH_RPI_PIO_USB || CFG_TUD_RPI_PIO_USB // Set the system clock to a multiple of 120mhz for bitbanging USB with pico-usb set_sys_clock_khz(120000, true); + + // rp2040 use pico-pio-usb for host tuh_configure() can be used to passed pio configuration to the host stack + // Note: tuh_configure() must be called before tuh_init() + pio_usb_configuration_t pio_cfg = PIO_USB_DEFAULT_CONFIG; + pio_cfg.pin_dp = PICO_PIO_USB_PIN_DP; + tuh_configure(BOARD_TUH_RHPORT, TUH_CFGID_RPI_PIO_USB_CONFIGURATION, &pio_cfg); #endif #if defined(UART_DEV) && defined(LIB_PICO_STDIO_UART) @@ -142,9 +155,8 @@ void board_init(void) stdio_rtt_init(); #endif - // todo probably set up device mode? #if CFG_TUD_ENABLED - + // TODO probably set up device mode? #endif #if CFG_TUH_ENABLED diff --git a/src/device/usbd.c b/src/device/usbd.c index 55e478a4e..697477584 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -392,7 +392,7 @@ bool tud_init (uint8_t rhport) // skip if already initialized if ( tud_inited() ) return true; - TU_LOG2("USBD init\r\n"); + TU_LOG2("USBD init rhport %u\r\n", rhport); TU_LOG2_INT(sizeof(usbd_device_t)); tu_varclr(&_usbd_dev); diff --git a/src/host/hcd.h b/src/host/hcd.h index 036394c72..2bc85034f 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -48,7 +48,7 @@ // #endif #endif - //--------------------------------------------------------------------+ +//--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ typedef enum @@ -106,6 +106,9 @@ typedef struct // Controller API //--------------------------------------------------------------------+ +// optional hcd configuration, called by tuh_config() +bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) TU_ATTR_WEAK; + // Initialize controller to host mode bool hcd_init(uint8_t rhport); diff --git a/src/host/usbh.c b/src/host/usbh.c index e0e41a8d1..ab2d8770a 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -274,9 +274,32 @@ static void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t h 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); +#if CFG_TUSB_OS == OPT_OS_NONE +// TODO rework time-related function later +void osal_task_delay(uint32_t msec) +{ + (void) msec; + + const uint32_t start = hcd_frame_number(TUH_OPT_RHPORT); + while ( ( hcd_frame_number(TUH_OPT_RHPORT) - start ) < msec ) {} +} +#endif + //--------------------------------------------------------------------+ // PUBLIC API (Parameter Verification is required) //--------------------------------------------------------------------+ + +bool tuh_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) +{ + if (hcd_configure) + { + return hcd_configure(rhport, cfg_id, cfg_param); + }else + { + return false; + } +} + bool tuh_mounted(uint8_t dev_addr) { usbh_device_t* dev = get_device(dev_addr); @@ -303,20 +326,6 @@ tusb_speed_t tuh_speed_get (uint8_t dev_addr) return (tusb_speed_t) (dev ? get_device(dev_addr)->speed : _dev0.speed); } -#if CFG_TUSB_OS == OPT_OS_NONE -void osal_task_delay(uint32_t msec) -{ - (void) msec; - - const uint32_t start = hcd_frame_number(TUH_OPT_RHPORT); - while ( ( hcd_frame_number(TUH_OPT_RHPORT) - start ) < msec ) {} -} -#endif - -//--------------------------------------------------------------------+ -// CLASS-USBD API (don't require to verify parameters) -//--------------------------------------------------------------------+ - static void clear_device(usbh_device_t* dev) { tu_memclr(dev, sizeof(usbh_device_t)); @@ -334,7 +343,7 @@ bool tuh_init(uint8_t rhport) // skip if already initialized if (_usbh_initialized) return _usbh_initialized; - TU_LOG2("USBH init\r\n"); + TU_LOG2("USBH init rhport %u\r\n", rhport); TU_LOG2_INT(sizeof(usbh_device_t)); TU_LOG2_INT(sizeof(hcd_event_t)); TU_LOG2_INT(sizeof(_ctrl_xfer)); diff --git a/src/host/usbh.h b/src/host/usbh.h index c6d36fb7f..4c65da206 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -46,8 +46,8 @@ typedef void (*tuh_xfer_cb_t)(tuh_xfer_t* xfer); // Note1: layout and order of this will be changed in near future // it is advised to initialize it using member name -// Note2: not all field is available/meaningful in callback, some info is not saved by -// usbh to save SRAM +// Note2: not all field is available/meaningful in callback, +// some info is not saved by usbh to save SRAM struct tuh_xfer_s { uint8_t daddr; @@ -69,6 +69,12 @@ struct tuh_xfer_s // uint32_t timeout_ms; // place holder, not supported yet }; +// ConfigID for tuh_config() +enum +{ + TUH_CFGID_RPI_PIO_USB_CONFIGURATION = OPT_MCU_RP2040 // cfg_param: pio_usb_configuration_t +}; + //--------------------------------------------------------------------+ // APPLICATION CALLBACK //--------------------------------------------------------------------+ @@ -85,6 +91,12 @@ TU_ATTR_WEAK void tuh_umount_cb(uint8_t daddr); // APPLICATION API //--------------------------------------------------------------------+ +// Configure host stack behavior with dynamic or port-specific parameters. +// Should be called before tuh_init() +// - cfg_id : configure ID (TBD) +// - cfg_param: configure data, structure depends on the ID +bool tuh_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param); + // Init host stack bool tuh_init(uint8_t rhport); diff --git a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c index 1b2d29331..58b153ac3 100644 --- a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c @@ -43,17 +43,25 @@ #define RHPORT_OFFSET 1 #define RHPORT_PIO(_x) ((_x)-RHPORT_OFFSET) -static pio_usb_configuration_t pio_host_config = PIO_USB_DEFAULT_CONFIG; +static pio_usb_configuration_t pio_host_cfg = PIO_USB_DEFAULT_CONFIG; //--------------------------------------------------------------------+ // HCD API //--------------------------------------------------------------------+ +bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) +{ + (void) rhport; + TU_VERIFY(cfg_id == TUH_CFGID_RPI_PIO_USB_CONFIGURATION); + memcpy(&pio_host_cfg, cfg_param, sizeof(pio_usb_configuration_t)); + return true; +} + bool hcd_init(uint8_t rhport) { (void) rhport; // To run USB SOF interrupt in core1, call this init in core1 - pio_usb_host_init(&pio_host_config); + pio_usb_host_init(&pio_host_cfg); return true; } From dd035b0eb2ed6ea7fee892d2a832e09f7c5c633c Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 8 Jun 2022 16:08:27 +0700 Subject: [PATCH 370/504] make all hcd/dcd function used in isr into ram with __no_inline_not_in_flash_func() for faster irq handling result is 1KB of code moved from rom -> ram --- src/common/tusb_types.h | 14 +++++++------- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 12 ++++++------ src/portable/raspberrypi/rp2040/hcd_rp2040.c | 18 ++++++++++++------ src/portable/raspberrypi/rp2040/rp2040_usb.c | 16 ++++++++-------- src/portable/raspberrypi/rp2040/rp2040_usb.h | 12 ++++++++---- 5 files changed, 41 insertions(+), 31 deletions(-) diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index e2fa17532..1f2a38d4c 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -492,23 +492,23 @@ TU_ATTR_BIT_FIELD_ORDER_END //--------------------------------------------------------------------+ // Get direction from Endpoint address -static inline tusb_dir_t tu_edpt_dir(uint8_t addr) +TU_ATTR_ALWAYS_INLINE static inline tusb_dir_t tu_edpt_dir(uint8_t addr) { return (addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT; } // Get Endpoint number from address -static inline uint8_t tu_edpt_number(uint8_t addr) +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_edpt_number(uint8_t addr) { return (uint8_t)(addr & (~TUSB_DIR_IN_MASK)); } -static inline uint8_t tu_edpt_addr(uint8_t num, uint8_t dir) +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_MASK : 0)); } -static inline uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const* desc_ep) +TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const* desc_ep) { return tu_le16toh(desc_ep->wMaxPacketSize) & TU_GENMASK(10, 0); } @@ -516,18 +516,18 @@ static inline uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const* desc_ep) //--------------------------------------------------------------------+ // Descriptor helper //--------------------------------------------------------------------+ -static inline uint8_t const * tu_desc_next(void const* desc) +TU_ATTR_ALWAYS_INLINE static inline uint8_t const * tu_desc_next(void const* desc) { uint8_t const* desc8 = (uint8_t const*) desc; return desc8 + desc8[DESC_OFFSET_LEN]; } -static inline uint8_t tu_desc_type(void const* desc) +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_type(void const* desc) { return ((uint8_t const*) desc)[DESC_OFFSET_TYPE]; } -static inline uint8_t tu_desc_len(void const* desc) +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_len(void const* desc) { return ((uint8_t const*) desc)[DESC_OFFSET_LEN]; } diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index 48793b0d0..3fefc972d 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -55,7 +55,7 @@ static uint8_t *next_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]; -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_by_num(uint8_t num, tusb_dir_t dir) { return &hw_endpoints[num][dir]; } @@ -185,7 +185,7 @@ static void hw_endpoint_xfer(uint8_t ep_addr, uint8_t *buffer, uint16_t total_by hw_endpoint_xfer_start(ep, buffer, total_bytes); } -static void hw_handle_buff_status(void) +static void __no_inline_not_in_flash_func(hw_handle_buff_status)(void) { uint32_t remaining_buffers = usb_hw->buf_status; pico_trace("buf_status = 0x%08x\n", remaining_buffers); @@ -214,7 +214,7 @@ static void hw_handle_buff_status(void) } } -static void reset_ep0_pid(void) +TU_ATTR_ALWAYS_INLINE static inline void reset_ep0_pid(void) { // If we have finished this transfer on EP0 set pid back to 1 for next // setup transfer. Also clear a stall in case @@ -226,7 +226,7 @@ static void reset_ep0_pid(void) } } -static void reset_non_control_endpoints(void) +static void __no_inline_not_in_flash_func(reset_non_control_endpoints)(void) { // Disable all non-control for ( uint8_t i = 0; i < USB_MAX_ENDPOINTS-1; i++ ) @@ -242,7 +242,7 @@ static void reset_non_control_endpoints(void) next_buffer_ptr = &usb_dpram->epx_data[0]; } -static void dcd_rp2040_irq(void) +static void __no_inline_not_in_flash_func(dcd_rp2040_irq)(void) { uint32_t const status = usb_hw->ints; uint32_t handled = 0; @@ -524,7 +524,7 @@ void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) hw_endpoint_close(ep_addr); } -void dcd_int_handler(uint8_t rhport) +void __no_inline_not_in_flash_func(dcd_int_handler)(uint8_t rhport) { (void) rhport; dcd_rp2040_irq(); diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 54c27ffe3..063a8acd0 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -79,7 +79,7 @@ static struct hw_endpoint *get_dev_ep(uint8_t dev_addr, uint8_t ep_addr) return NULL; } -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; } @@ -91,7 +91,7 @@ static bool need_pre(uint8_t dev_addr) return hcd_port_speed_get(0) != tuh_speed_get(dev_addr); } -static void hw_xfer_complete(struct hw_endpoint *ep, xfer_result_t xfer_result) +static void __no_inline_not_in_flash_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; @@ -101,7 +101,7 @@ static void hw_xfer_complete(struct hw_endpoint *ep, xfer_result_t xfer_result) hcd_event_xfer_complete(dev_addr, ep_addr, xferred_len, xfer_result, true); } -static void _handle_buff_status_bit(uint bit, struct hw_endpoint *ep) +static void __no_inline_not_in_flash_func(_handle_buff_status_bit)(uint bit, struct hw_endpoint *ep) { usb_hw_clear->buf_status = bit; bool done = hw_endpoint_xfer_continue(ep); @@ -111,7 +111,7 @@ static void _handle_buff_status_bit(uint bit, struct hw_endpoint *ep) } } -static void hw_handle_buff_status(void) +static void __no_inline_not_in_flash_func(hw_handle_buff_status)(void) { uint32_t remaining_buffers = usb_hw->buf_status; pico_trace("buf_status 0x%08x\n", remaining_buffers); @@ -159,7 +159,7 @@ static void hw_handle_buff_status(void) } } -static void hw_trans_complete(void) +static void __no_inline_not_in_flash_func(hw_trans_complete)(void) { if (usb_hw->sie_ctrl & USB_SIE_CTRL_SEND_SETUP_BITS) { @@ -175,7 +175,7 @@ static void hw_trans_complete(void) } } -static void hcd_rp2040_irq(void) +static void __no_inline_not_in_flash_func(hcd_rp2040_irq)(void) { uint32_t status = usb_hw->ints; uint32_t handled = 0; @@ -240,6 +240,12 @@ static void hcd_rp2040_irq(void) } } +void __no_inline_not_in_flash_func(hcd_int_handler)(uint8_t rhport) +{ + (void) rhport; + hcd_rp2040_irq(); +} + static struct hw_endpoint *_next_free_interrupt_ep(void) { struct hw_endpoint *ep = NULL; diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index c93199fd0..ebcc76a4b 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -38,7 +38,7 @@ const char *ep_dir_string[] = { "in", }; -static inline void _hw_endpoint_lock_update(__unused struct hw_endpoint * ep, __unused int delta) { +TU_ATTR_ALWAYS_INLINE static inline void _hw_endpoint_lock_update(__unused struct hw_endpoint * ep, __unused int delta) { // todo add critsec as necessary to prevent issues between worker and IRQ... // note that this is perhaps as simple as disabling IRQs because it would make // sense to have worker and IRQ on same core, however I think using critsec is about equivalent. @@ -69,7 +69,7 @@ void rp2040_usb_init(void) usb_hw->muxing = USB_USB_MUXING_TO_PHY_BITS | USB_USB_MUXING_SOFTCON_BITS; } -void hw_endpoint_reset_transfer(struct hw_endpoint *ep) +void __no_inline_not_in_flash_func(hw_endpoint_reset_transfer)(struct hw_endpoint *ep) { ep->active = false; ep->remaining_len = 0; @@ -77,7 +77,7 @@ void hw_endpoint_reset_transfer(struct hw_endpoint *ep) ep->user_buf = 0; } -void _hw_endpoint_buffer_control_update32(struct hw_endpoint *ep, uint32_t and_mask, uint32_t or_mask) { +void __no_inline_not_in_flash_func(_hw_endpoint_buffer_control_update32)(struct hw_endpoint *ep, uint32_t and_mask, uint32_t or_mask) { uint32_t value = 0; if (and_mask) { value = *ep->buffer_control & and_mask; @@ -108,7 +108,7 @@ void _hw_endpoint_buffer_control_update32(struct hw_endpoint *ep, uint32_t and_m } // prepare buffer, return buffer control -static uint32_t prepare_ep_buffer(struct hw_endpoint *ep, uint8_t buf_id) +static uint32_t __no_inline_not_in_flash_func(prepare_ep_buffer)(struct hw_endpoint *ep, uint8_t buf_id) { uint16_t const buflen = tu_min16(ep->remaining_len, ep->wMaxPacketSize); ep->remaining_len = (uint16_t)(ep->remaining_len - buflen); @@ -143,7 +143,7 @@ static uint32_t prepare_ep_buffer(struct hw_endpoint *ep, uint8_t buf_id) } // Prepare buffer control register value -static void _hw_endpoint_start_next_buffer(struct hw_endpoint *ep) +static void __no_inline_not_in_flash_func(_hw_endpoint_start_next_buffer)(struct hw_endpoint *ep) { uint32_t ep_ctrl = *ep->endpoint_control; @@ -205,7 +205,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 sync_ep_buffer(struct hw_endpoint *ep, uint8_t buf_id) +static uint16_t __no_inline_not_in_flash_func(sync_ep_buffer)(struct hw_endpoint *ep, uint8_t buf_id) { uint32_t buf_ctrl = _hw_endpoint_buffer_control_get_value32(ep); if (buf_id) buf_ctrl = buf_ctrl >> 16; @@ -241,7 +241,7 @@ static uint16_t sync_ep_buffer(struct hw_endpoint *ep, uint8_t buf_id) return xferred_bytes; } -static void _hw_endpoint_xfer_sync (struct hw_endpoint *ep) +static void __no_inline_not_in_flash_func(_hw_endpoint_xfer_sync) (struct hw_endpoint *ep) { // Update hw endpoint struct with info from hardware // after a buff status interrupt @@ -292,7 +292,7 @@ static void _hw_endpoint_xfer_sync (struct hw_endpoint *ep) } // Returns true if transfer is complete -bool hw_endpoint_xfer_continue(struct hw_endpoint *ep) +bool __no_inline_not_in_flash_func(hw_endpoint_xfer_continue)(struct hw_endpoint *ep) { _hw_endpoint_lock_update(ep, 1); // Part way through a transfer diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.h b/src/portable/raspberrypi/rp2040/rp2040_usb.h index da1933ddd..4442e22dc 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.h +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.h @@ -72,16 +72,20 @@ bool hw_endpoint_xfer_continue(struct hw_endpoint *ep); void hw_endpoint_reset_transfer(struct hw_endpoint *ep); void _hw_endpoint_buffer_control_update32(struct hw_endpoint *ep, uint32_t and_mask, uint32_t or_mask); -static inline uint32_t _hw_endpoint_buffer_control_get_value32(struct hw_endpoint *ep) { + +TU_ATTR_ALWAYS_INLINE static inline uint32_t _hw_endpoint_buffer_control_get_value32(struct hw_endpoint *ep) { return *ep->buffer_control; } -static inline void _hw_endpoint_buffer_control_set_value32(struct hw_endpoint *ep, uint32_t value) { + +TU_ATTR_ALWAYS_INLINE static inline void _hw_endpoint_buffer_control_set_value32(struct hw_endpoint *ep, uint32_t value) { return _hw_endpoint_buffer_control_update32(ep, 0, value); } -static inline void _hw_endpoint_buffer_control_set_mask32(struct hw_endpoint *ep, uint32_t value) { + +TU_ATTR_ALWAYS_INLINE static inline void _hw_endpoint_buffer_control_set_mask32(struct hw_endpoint *ep, uint32_t value) { return _hw_endpoint_buffer_control_update32(ep, ~value, value); } -static inline void _hw_endpoint_buffer_control_clear_mask32(struct hw_endpoint *ep, uint32_t value) { + +TU_ATTR_ALWAYS_INLINE static inline void _hw_endpoint_buffer_control_clear_mask32(struct hw_endpoint *ep, uint32_t value) { return _hw_endpoint_buffer_control_update32(ep, ~value, 0); } From 8451d05c50928b9aa370414f25a0e991cd4ecef3 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 10 Jun 2022 01:45:48 +0700 Subject: [PATCH 371/504] revert sof_isr driver rename since it cause issue with existing code also removed commented tud_sof_isr_set() API --- src/device/usbd.c | 40 ++++++++++++++-------------------------- src/device/usbd.h | 6 ------ src/device/usbd_pvt.h | 2 +- 3 files changed, 15 insertions(+), 33 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 697477584..ec598e49f 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -98,7 +98,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = cdcd_open, .control_xfer_cb = cdcd_control_xfer_cb, .xfer_cb = cdcd_xfer_cb, - .sof_isr = NULL + .sof = NULL }, #endif @@ -110,7 +110,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = mscd_open, .control_xfer_cb = mscd_control_xfer_cb, .xfer_cb = mscd_xfer_cb, - .sof_isr = NULL + .sof = NULL }, #endif @@ -122,7 +122,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = hidd_open, .control_xfer_cb = hidd_control_xfer_cb, .xfer_cb = hidd_xfer_cb, - .sof_isr = NULL + .sof = NULL }, #endif @@ -134,7 +134,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = audiod_open, .control_xfer_cb = audiod_control_xfer_cb, .xfer_cb = audiod_xfer_cb, - .sof_isr = audiod_sof_isr + .sof = audiod_sof_isr }, #endif @@ -146,7 +146,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = videod_open, .control_xfer_cb = videod_control_xfer_cb, .xfer_cb = videod_xfer_cb, - .sof_isr = NULL + .sof = NULL }, #endif @@ -158,7 +158,7 @@ static usbd_class_driver_t const _usbd_driver[] = .reset = midid_reset, .control_xfer_cb = midid_control_xfer_cb, .xfer_cb = midid_xfer_cb, - .sof_isr = NULL + .sof = NULL }, #endif @@ -170,7 +170,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = vendord_open, .control_xfer_cb = tud_vendor_control_xfer_cb, .xfer_cb = vendord_xfer_cb, - .sof_isr = NULL + .sof = NULL }, #endif @@ -182,7 +182,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = usbtmcd_open_cb, .control_xfer_cb = usbtmcd_control_xfer_cb, .xfer_cb = usbtmcd_xfer_cb, - .sof_isr = NULL + .sof = NULL }, #endif @@ -194,7 +194,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = dfu_rtd_open, .control_xfer_cb = dfu_rtd_control_xfer_cb, .xfer_cb = NULL, - .sof_isr = NULL + .sof = NULL }, #endif @@ -206,7 +206,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = dfu_moded_open, .control_xfer_cb = dfu_moded_control_xfer_cb, .xfer_cb = NULL, - .sof_isr = NULL + .sof = NULL }, #endif @@ -218,7 +218,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = netd_open, .control_xfer_cb = netd_control_xfer_cb, .xfer_cb = netd_xfer_cb, - .sof_isr = NULL, + .sof = NULL, }, #endif @@ -230,7 +230,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = btd_open, .control_xfer_cb = btd_control_xfer_cb, .xfer_cb = btd_xfer_cb, - .sof_isr = NULL + .sof = NULL }, #endif }; @@ -264,8 +264,6 @@ static inline usbd_class_driver_t const * get_driver(uint8_t drvid) // DCD Event //--------------------------------------------------------------------+ -//static tud_sof_isr_t _sof_isr = NULL; - enum { RHPORT_INVALID = 0xFFu }; static uint8_t _usbd_rhport = RHPORT_INVALID; @@ -373,12 +371,6 @@ bool tud_connect(void) return true; } -//void tud_sof_isr_set(tud_sof_isr_t sof_isr) -//{ -// _sof_isr = sof_isr; -// dcd_sof_enable(_usbd_rhport, _sof_isr != NULL); -//} - //--------------------------------------------------------------------+ // USBD Task //--------------------------------------------------------------------+ @@ -422,7 +414,6 @@ bool tud_init (uint8_t rhport) } _usbd_rhport = rhport; - //_sof_isr = NULL; // Init device controller driver dcd_init(rhport); @@ -1110,15 +1101,12 @@ TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const * event, bool in_isr) for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { usbd_class_driver_t const * driver = get_driver(i); - if (driver->sof_isr) + if (driver->sof) { - driver->sof_isr(event->rhport, event->sof.frame_count); + driver->sof(event->rhport, event->sof.frame_count); } } - // SOF user handler in ISR context - // if (_sof_isr) _sof_isr(event->sof.frame_count); - // Some MCUs after running dcd_remote_wakeup() does not have way to detect the end of remote wakeup // which last 1-15 ms. DCD can use SOF as a clear indicator that bus is back to operational if ( _usbd_dev.suspended ) diff --git a/src/device/usbd.h b/src/device/usbd.h index f1312f6ec..964cfb992 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -33,8 +33,6 @@ extern "C" { #endif -// typedef void (*tud_sof_isr_t) (uint32_t frame_count); - //--------------------------------------------------------------------+ // Application API //--------------------------------------------------------------------+ @@ -95,10 +93,6 @@ bool tud_disconnect(void); // Return false on unsupported MCUs bool tud_connect(void); -// Set Start-of-frame (1ms interval) IRQ handler -// NULL means disabled, frame_count may not be supported on mcus -// void tud_sof_isr_set(tud_sof_isr_t sof_isr); - // Carry out Data and Status stage of control transfer // - If len = 0, it is equivalent to sending status only // - If len > wLength : it will be truncated diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index 17ebbfcd4..6fad46db3 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -48,7 +48,7 @@ typedef struct uint16_t (* open ) (uint8_t rhport, tusb_desc_interface_t const * desc_intf, uint16_t max_len); bool (* control_xfer_cb ) (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); bool (* xfer_cb ) (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); - void (* sof_isr ) (uint8_t rhport, uint32_t frame_count); // optional + void (* sof ) (uint8_t rhport, uint32_t frame_count); // optional } usbd_class_driver_t; // Invoked when initializing device stack to get additional class drivers. From 040ef0640df837a49e7f46c12fa7b00fe6a77bf6 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 10 Jun 2022 14:53:03 +0700 Subject: [PATCH 372/504] more dynamic controller for host --- src/device/usbd.c | 2 +- src/host/usbh.c | 36 ++++++++++++++++++++---------------- src/host/usbh.h | 4 ++-- src/tusb_option.h | 7 ++++--- 4 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index ec598e49f..1806281ff 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -384,7 +384,7 @@ bool tud_init (uint8_t rhport) // skip if already initialized if ( tud_inited() ) return true; - TU_LOG2("USBD init rhport %u\r\n", rhport); + TU_LOG2("USBD init on controller %u\r\n", rhport); TU_LOG2_INT(sizeof(usbd_device_t)); tu_varclr(&_usbd_dev); diff --git a/src/host/usbh.c b/src/host/usbh.c index ab2d8770a..a600f7095 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -125,6 +125,7 @@ typedef struct { // Invalid driver ID in itf2drv[] ep2drv[][] mapping enum { DRVID_INVALID = 0xFFu }; enum { ADDR_INVALID = 0xFFu }; +enum { CONTROLLER_INVALID = 0xFFu }; #if CFG_TUSB_DEBUG >= 2 #define DRIVER_NAME(_name) .name = _name, @@ -203,7 +204,7 @@ enum { CONFIG_NUM = 1 }; // default to use configuration 1 // sum of end device + hub #define TOTAL_DEVICES (CFG_TUH_DEVICE_MAX + CFG_TUH_HUB) -static bool _usbh_initialized = false; +static uint8_t _usbh_controller = CONTROLLER_INVALID; // Device with address = 0 for enumeration static usbh_dev0_t _dev0; @@ -280,8 +281,8 @@ void osal_task_delay(uint32_t msec) { (void) msec; - const uint32_t start = hcd_frame_number(TUH_OPT_RHPORT); - while ( ( hcd_frame_number(TUH_OPT_RHPORT) - start ) < msec ) {} + const uint32_t start = hcd_frame_number(_usbh_controller); + while ( ( hcd_frame_number(_usbh_controller) - start ) < msec ) {} } #endif @@ -335,15 +336,15 @@ static void clear_device(usbh_device_t* dev) bool tuh_inited(void) { - return _usbh_initialized; + return _usbh_controller != CONTROLLER_INVALID; } -bool tuh_init(uint8_t rhport) +bool tuh_init(uint8_t controller_id) { // skip if already initialized - if (_usbh_initialized) return _usbh_initialized; + if ( tuh_inited() ) return true; - TU_LOG2("USBH init rhport %u\r\n", rhport); + TU_LOG2("USBH init on controller %u\r\n", controller_id); TU_LOG2_INT(sizeof(usbh_device_t)); TU_LOG2_INT(sizeof(hcd_event_t)); TU_LOG2_INT(sizeof(_ctrl_xfer)); @@ -376,10 +377,11 @@ bool tuh_init(uint8_t rhport) usbh_class_drivers[drv_id].init(); } - TU_ASSERT(hcd_init(rhport)); - hcd_int_enable(rhport); + _usbh_controller = controller_id;; + + TU_ASSERT(hcd_init(controller_id)); + hcd_int_enable(controller_id); - _usbh_initialized = true; return true; } @@ -721,13 +723,13 @@ uint8_t* usbh_get_enum_buf(void) void usbh_int_set(bool enabled) { - // TODO all host controller + // TODO all host controller if multiple is used if (enabled) { - hcd_int_enable(TUH_OPT_RHPORT); + hcd_int_enable(_usbh_controller); }else { - hcd_int_disable(TUH_OPT_RHPORT); + hcd_int_disable(_usbh_controller); } } @@ -1238,14 +1240,15 @@ static void process_enumeration(tuh_xfer_t* xfer) #if 0 case ENUM_RESET_2: - // XXX note used by now, but may be needed for some devices !? + // TODO not used by now, but may be needed for some devices !? // Reset device again before Set Address TU_LOG2("Port reset2 \r\n"); if (_dev0.hub_addr == 0) { // connected directly to roothub hcd_port_reset( _dev0.rhport ); - osal_task_delay(RESET_DELAY); + osal_task_delay(RESET_DELAY); // TODO may not work for no-OS on MCU that require reset_end() since + // sof of controller may not running while reseting hcd_port_reset_end(_dev0.rhport); // TODO: fall through to SET ADDRESS, refactor later } @@ -1364,7 +1367,8 @@ static bool enum_new_device(hcd_event_t* event) // connected/disconnected directly with roothub // wait until device is stable TODO non blocking hcd_port_reset(_dev0.rhport); - osal_task_delay(RESET_DELAY); + osal_task_delay(RESET_DELAY); // TODO may not work for no-OS on MCU that require reset_end() since + // sof of controller may not running while reseting hcd_port_reset_end( _dev0.rhport); // device unplugged while delaying diff --git a/src/host/usbh.h b/src/host/usbh.h index 4c65da206..347c75b8c 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -95,10 +95,10 @@ TU_ATTR_WEAK void tuh_umount_cb(uint8_t daddr); // Should be called before tuh_init() // - cfg_id : configure ID (TBD) // - cfg_param: configure data, structure depends on the ID -bool tuh_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param); +bool tuh_configure(uint8_t controller_id, uint32_t cfg_id, const void* cfg_param); // Init host stack -bool tuh_init(uint8_t rhport); +bool tuh_init(uint8_t controller_id); // Check if host stack is already initialized bool tuh_inited(void); diff --git a/src/tusb_option.h b/src/tusb_option.h index e332c5728..206d23e72 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -28,7 +28,7 @@ #define _TUSB_OPTION_H_ // To avoid GCC compiler warnings when -pedantic option is used (strict ISO C) -typedef int make_iso_compilers_happy ; +typedef int make_iso_compilers_happy; #include "common/tusb_compiler.h" @@ -217,6 +217,9 @@ typedef int make_iso_compilers_happy ; #define CFG_TUD_MAX_SPEED (TUD_RHPORT_MODE & OPT_MODE_SPEED_MASK) #endif +// For backward compatible +#define TUSB_OPT_DEVICE_ENABLED CFG_TUD_ENABLED + // highspeed support indicator #define TUD_OPT_HIGH_SPEED (CFG_TUD_MAX_SPEED ? CFG_TUD_MAX_SPEED : TUP_RHPORT_HIGHSPEED) @@ -230,7 +233,6 @@ typedef int make_iso_compilers_happy ; #define TUH_OPT_RHPORT 1 #else #define TUH_RHPORT_MODE OPT_MODE_NONE - #define TUH_OPT_RHPORT -1 #endif #ifndef CFG_TUH_ENABLED @@ -244,7 +246,6 @@ typedef int make_iso_compilers_happy ; #endif // For backward compatible -#define TUSB_OPT_DEVICE_ENABLED CFG_TUD_ENABLED #define TUSB_OPT_HOST_ENABLED CFG_TUH_ENABLED //--------------------------------------------------------------------+ From 19d054f7892beda36c7f6fe5f07d84a13db7df16 Mon Sep 17 00:00:00 2001 From: Liam Fraser Date: Thu, 13 Jan 2022 11:17:08 +0000 Subject: [PATCH 373/504] hcd_rp2040 improvements: - Stall now has priority over other interrupt responses - Delete eunused hcd_edpt_busy - Assert !ep->active when trying to start a new xfer - Assert !ep->active when handling buff_status bits - Set ep->xferred_len to 8 once a setup packet is finished so the data structure is accurate --- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 46 ++++++++++---------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 063a8acd0..dddb9cd90 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -104,6 +104,8 @@ static void __no_inline_not_in_flash_func(hw_xfer_complete)(struct hw_endpoint * static void __no_inline_not_in_flash_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); bool done = hw_endpoint_xfer_continue(ep); if (done) { @@ -166,6 +168,8 @@ static void __no_inline_not_in_flash_func(hw_trans_complete)(void) pico_trace("Sent setup packet\n"); struct hw_endpoint *ep = &epx; assert(ep->active); + // Set transferred length to 8 for a setup packet + ep->xferred_len = 8; hw_xfer_complete(ep, XFER_RESULT_SUCCESS); } else @@ -197,6 +201,18 @@ static void __no_inline_not_in_flash_func(hcd_rp2040_irq)(void) usb_hw_clear->sie_status = USB_SIE_STATUS_SPEED_BITS; } + if (status & USB_INTS_STALL_BITS) + { + // We have rx'd a stall from the device + // NOTE THIS SHOULD HAVE PRIORITY OVER BUFF_STATUS + // AND TRANS_COMPLETE as the stall is an alternative response + // to one of those events + pico_trace("Stall REC\n"); + handled |= USB_INTS_STALL_BITS; + usb_hw_clear->sie_status = USB_SIE_STATUS_STALL_REC_BITS; + hw_xfer_complete(&epx, XFER_RESULT_STALLED); + } + if (status & USB_INTS_BUFF_STATUS_BITS) { handled |= USB_INTS_BUFF_STATUS_BITS; @@ -212,15 +228,6 @@ static void __no_inline_not_in_flash_func(hcd_rp2040_irq)(void) hw_trans_complete(); } - if (status & USB_INTS_STALL_BITS) - { - // We have rx'd a stall from the device - pico_trace("Stall REC\n"); - handled |= USB_INTS_STALL_BITS; - usb_hw_clear->sie_status = USB_SIE_STATUS_STALL_REC_BITS; - hw_xfer_complete(&epx, XFER_RESULT_STALLED); - } - if (status & USB_INTS_ERROR_RX_TIMEOUT_BITS) { handled |= USB_INTS_ERROR_RX_TIMEOUT_BITS; @@ -505,6 +512,9 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * struct hw_endpoint *ep = get_dev_ep(dev_addr, ep_addr); assert(ep); + // EP should be inactive + assert(!ep->active); + // Control endpoint can change direction 0x00 <-> 0x80 if ( ep_addr != ep->ep_addr ) { @@ -552,6 +562,9 @@ 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(0); + // EPX should be inactive + assert(!ep->active); + // EP0 out _hw_endpoint_init(ep, dev_addr, 0x00, ep->wMaxPacketSize, 0, 0); assert(ep->configured); @@ -571,21 +584,6 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet return true; } - -//bool hcd_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) -//{ -// // EPX is shared, so multiple device addresses and endpoint addresses share that -// // so if any transfer is active on epx, we are busy. Interrupt endpoints have their own -// // EPX so ep->active will only be busy if there is a pending transfer on that interrupt endpoint -// // on that device -// pico_trace("hcd_edpt_busy dev addr %d ep_addr 0x%x\n", dev_addr, ep_addr); -// struct hw_endpoint *ep = get_dev_ep(dev_addr, ep_addr); -// assert(ep); -// bool busy = ep->active; -// pico_trace("busy == %d\n", busy); -// return busy; -//} - bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) { (void) dev_addr; From f4a7b5b80c86777b62842e19f9bd6236161f2e8d Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 16 Jun 2022 14:37:57 +0700 Subject: [PATCH 374/504] add note for recursive calls of process_device_unplugged() in case of hub --- examples/host/cdc_msc_hid/src/tusb_config.h | 2 +- src/host/usbh.c | 37 +++++++++++---------- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index e9e68cf5a..c469ec813 100644 --- a/examples/host/cdc_msc_hid/src/tusb_config.h +++ b/examples/host/cdc_msc_hid/src/tusb_config.h @@ -81,7 +81,7 @@ // Size of buffer to hold descriptors and other data used for enumeration #define CFG_TUH_ENUMERATION_BUFSIZE 256 -#define CFG_TUH_HUB 1 +#define CFG_TUH_HUB 1 // number of supported hubs #define CFG_TUH_CDC 1 #define CFG_TUH_HID 4 // typical keyboard + mouse device can have 3-4 HID interfaces #define CFG_TUH_MSC 1 diff --git a/src/host/usbh.c b/src/host/usbh.c index 908230c83..04d969ce6 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -1089,6 +1089,12 @@ uint8_t tuh_descriptor_get_serial_string_sync(uint8_t daddr, uint16_t language_i // //--------------------------------------------------------------------+ +TU_ATTR_ALWAYS_INLINE +static inline bool is_hub_addr(uint8_t daddr) +{ + return (CFG_TUH_HUB > 0) && (daddr > CFG_TUH_DEVICE_MAX); +} + // a device unplugged from rhport:hub_addr:hub_port static void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port) { @@ -1101,21 +1107,24 @@ static void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t h // TODO Hub multiple level if (dev->rhport == rhport && - (hub_addr == 0 || dev->hub_addr == hub_addr) && // hub_addr == 0 & hub_port == 0 means roothub - (hub_port == 0 || dev->hub_port == hub_port) && + (hub_addr == 0 || dev->hub_addr == hub_addr) && // hub_addr = 0 means roothub + (hub_port == 0 || dev->hub_port == hub_port) && // hub_port = 0 means all devices of downstream hub dev->connected) { TU_LOG2(" Address = %u\r\n", dev_addr); - // If the device itself is a usb hub, unplug downstream devices. - if (dev_addr > CFG_TUH_DEVICE_MAX) + if (is_hub_addr(dev_addr)) { + TU_LOG(USBH_DBG_LVL, "HUB address = %u is unmounted\r\n", dev_addr); + // If the device itself is a usb hub, unplug downstream devices. + // FIXME un-roll recursive calls to prevent potential stack overflow process_device_unplugged(rhport, dev_addr, 0); + }else + { + // Invoke callback before closing driver + if (tuh_umount_cb) tuh_umount_cb(dev_addr); } - // Invoke callback before close driver - if (tuh_umount_cb) tuh_umount_cb(dev_addr); - // Close class driver for (uint8_t drv_id = 0; drv_id < USBH_CLASS_DRIVER_COUNT; drv_id++) { @@ -1395,12 +1404,6 @@ static bool enum_new_device(hcd_event_t* event) return true; } -TU_ATTR_ALWAYS_INLINE -static inline bool is_hub_addr(uint8_t daddr) -{ - return daddr > CFG_TUH_DEVICE_MAX; -} - static uint8_t get_new_address(bool is_hub) { uint8_t start; @@ -1577,10 +1580,10 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) { enum_full_complete(); -#if CFG_TUH_HUB - // skip device mount callback for hub - if ( !is_hub_addr(dev_addr) ) -#endif + if (is_hub_addr(dev_addr)) + { + TU_LOG(USBH_DBG_LVL, "HUB address = %u is mounted\r\n", dev_addr); + }else { // Invoke callback if available if (tuh_mount_cb) tuh_mount_cb(dev_addr); From 2036a0b62a709168d80d2b314e580ee1d1eda0bf Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 16 Jun 2022 14:41:10 +0700 Subject: [PATCH 375/504] update readme --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 5b994c357..1a96f6e16 100644 --- a/README.rst +++ b/README.rst @@ -82,7 +82,7 @@ Host Stack - Human Interface Device (HID): Keyboard, Mouse, Generic - Mass Storage Class (MSC) -- Hub currently only supports 1 level of hub (due to my laziness) +- Hub with multiple-level support OS Abstraction layer ==================== From c5ba4af25babbf7fc6ee97d0f6ec06079e5f1b0f Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Thu, 16 Jun 2022 11:03:53 -0500 Subject: [PATCH 376/504] rp2040: make moving 1K of code into RAM optional - and off by default --- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 8 ++++---- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 12 ++++++------ src/portable/raspberrypi/rp2040/rp2040_usb.c | 14 +++++++------- src/portable/raspberrypi/rp2040/rp2040_usb.h | 9 +++++++++ 4 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index 3fefc972d..4c8084878 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -185,7 +185,7 @@ static void hw_endpoint_xfer(uint8_t ep_addr, uint8_t *buffer, uint16_t total_by hw_endpoint_xfer_start(ep, buffer, total_bytes); } -static void __no_inline_not_in_flash_func(hw_handle_buff_status)(void) +static void __tusb_irq_path_func(hw_handle_buff_status)(void) { uint32_t remaining_buffers = usb_hw->buf_status; pico_trace("buf_status = 0x%08x\n", remaining_buffers); @@ -226,7 +226,7 @@ TU_ATTR_ALWAYS_INLINE static inline void reset_ep0_pid(void) } } -static void __no_inline_not_in_flash_func(reset_non_control_endpoints)(void) +static void __tusb_irq_path_func(reset_non_control_endpoints)(void) { // Disable all non-control for ( uint8_t i = 0; i < USB_MAX_ENDPOINTS-1; i++ ) @@ -242,7 +242,7 @@ static void __no_inline_not_in_flash_func(reset_non_control_endpoints)(void) next_buffer_ptr = &usb_dpram->epx_data[0]; } -static void __no_inline_not_in_flash_func(dcd_rp2040_irq)(void) +static void __tusb_irq_path_func(dcd_rp2040_irq)(void) { uint32_t const status = usb_hw->ints; uint32_t handled = 0; @@ -524,7 +524,7 @@ void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) hw_endpoint_close(ep_addr); } -void __no_inline_not_in_flash_func(dcd_int_handler)(uint8_t rhport) +void __tusb_irq_path_func(dcd_int_handler)(uint8_t rhport) { (void) rhport; dcd_rp2040_irq(); diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 063a8acd0..346326cd0 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -91,7 +91,7 @@ static bool need_pre(uint8_t dev_addr) return hcd_port_speed_get(0) != tuh_speed_get(dev_addr); } -static void __no_inline_not_in_flash_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; @@ -101,7 +101,7 @@ static void __no_inline_not_in_flash_func(hw_xfer_complete)(struct hw_endpoint * hcd_event_xfer_complete(dev_addr, ep_addr, xferred_len, xfer_result, true); } -static void __no_inline_not_in_flash_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; bool done = hw_endpoint_xfer_continue(ep); @@ -111,7 +111,7 @@ static void __no_inline_not_in_flash_func(_handle_buff_status_bit)(uint bit, str } } -static void __no_inline_not_in_flash_func(hw_handle_buff_status)(void) +static void __tusb_irq_path_func(hw_handle_buff_status)(void) { uint32_t remaining_buffers = usb_hw->buf_status; pico_trace("buf_status 0x%08x\n", remaining_buffers); @@ -159,7 +159,7 @@ static void __no_inline_not_in_flash_func(hw_handle_buff_status)(void) } } -static void __no_inline_not_in_flash_func(hw_trans_complete)(void) +static void __tusb_irq_path_func(hw_trans_complete)(void) { if (usb_hw->sie_ctrl & USB_SIE_CTRL_SEND_SETUP_BITS) { @@ -175,7 +175,7 @@ static void __no_inline_not_in_flash_func(hw_trans_complete)(void) } } -static void __no_inline_not_in_flash_func(hcd_rp2040_irq)(void) +static void __tusb_irq_path_func(hcd_rp2040_irq)(void) { uint32_t status = usb_hw->ints; uint32_t handled = 0; @@ -240,7 +240,7 @@ static void __no_inline_not_in_flash_func(hcd_rp2040_irq)(void) } } -void __no_inline_not_in_flash_func(hcd_int_handler)(uint8_t rhport) +void __tusb_irq_path_func(hcd_int_handler)(uint8_t rhport) { (void) rhport; hcd_rp2040_irq(); diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index ebcc76a4b..f93568f0c 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -69,7 +69,7 @@ void rp2040_usb_init(void) usb_hw->muxing = USB_USB_MUXING_TO_PHY_BITS | USB_USB_MUXING_SOFTCON_BITS; } -void __no_inline_not_in_flash_func(hw_endpoint_reset_transfer)(struct hw_endpoint *ep) +void __tusb_irq_path_func(hw_endpoint_reset_transfer)(struct hw_endpoint *ep) { ep->active = false; ep->remaining_len = 0; @@ -77,7 +77,7 @@ void __no_inline_not_in_flash_func(hw_endpoint_reset_transfer)(struct hw_endpoin ep->user_buf = 0; } -void __no_inline_not_in_flash_func(_hw_endpoint_buffer_control_update32)(struct hw_endpoint *ep, uint32_t and_mask, uint32_t or_mask) { +void __tusb_irq_path_func(_hw_endpoint_buffer_control_update32)(struct hw_endpoint *ep, uint32_t and_mask, uint32_t or_mask) { uint32_t value = 0; if (and_mask) { value = *ep->buffer_control & and_mask; @@ -108,7 +108,7 @@ void __no_inline_not_in_flash_func(_hw_endpoint_buffer_control_update32)(struct } // prepare buffer, return buffer control -static uint32_t __no_inline_not_in_flash_func(prepare_ep_buffer)(struct hw_endpoint *ep, uint8_t buf_id) +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); ep->remaining_len = (uint16_t)(ep->remaining_len - buflen); @@ -143,7 +143,7 @@ static uint32_t __no_inline_not_in_flash_func(prepare_ep_buffer)(struct hw_endpo } // Prepare buffer control register value -static void __no_inline_not_in_flash_func(_hw_endpoint_start_next_buffer)(struct hw_endpoint *ep) +static void __tusb_irq_path_func(_hw_endpoint_start_next_buffer)(struct hw_endpoint *ep) { uint32_t ep_ctrl = *ep->endpoint_control; @@ -205,7 +205,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 __no_inline_not_in_flash_func(sync_ep_buffer)(struct hw_endpoint *ep, uint8_t buf_id) +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); if (buf_id) buf_ctrl = buf_ctrl >> 16; @@ -241,7 +241,7 @@ static uint16_t __no_inline_not_in_flash_func(sync_ep_buffer)(struct hw_endpoint return xferred_bytes; } -static void __no_inline_not_in_flash_func(_hw_endpoint_xfer_sync) (struct hw_endpoint *ep) +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 @@ -292,7 +292,7 @@ static void __no_inline_not_in_flash_func(_hw_endpoint_xfer_sync) (struct hw_end } // Returns true if transfer is complete -bool __no_inline_not_in_flash_func(hw_endpoint_xfer_continue)(struct hw_endpoint *ep) +bool __tusb_irq_path_func(hw_endpoint_xfer_continue)(struct hw_endpoint *ep) { _hw_endpoint_lock_update(ep, 1); // Part way through a transfer diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.h b/src/portable/raspberrypi/rp2040/rp2040_usb.h index 4442e22dc..c72dae64c 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.h +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.h @@ -16,6 +16,15 @@ #define TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX PICO_RP2040_USB_DEVICE_ENUMERATION_FIX #endif +#ifndef PICO_RP2040_USB_FAST_IRQ +#define PICO_RP2040_USB_FAST_IRQ 0 +#endif + +#if PICO_RP2040_USB_FAST_IRQ +#define __tusb_irq_path_func(x) __no_inline_not_in_flash_func(x) +#else +#define __tusb_irq_path_func(x) x +#endif #define pico_info(...) TU_LOG(2, __VA_ARGS__) #define pico_trace(...) TU_LOG(3, __VA_ARGS__) From e9089b993f32a5437614008ec14458ad577cc28f Mon Sep 17 00:00:00 2001 From: Maddy Date: Thu, 16 Jun 2022 16:22:55 -0700 Subject: [PATCH 377/504] Fix typo in audiod_rx_done_cb in audio_device.c --- src/class/audio/audio_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index dbd8ab54b..1e534b6a4 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -562,7 +562,7 @@ static bool audiod_rx_done_cb(uint8_t rhport, audiod_function_t* audio, uint16_t case AUDIO_FORMAT_TYPE_I: - switch (audio->format_type_I_tx) + switch (audio->format_type_I_rx) { case AUDIO_DATA_FORMAT_TYPE_I_PCM: TU_VERIFY(audiod_decode_type_I_pcm(rhport, audio, n_bytes_received)); From 05fc2fa7a64c32aa748c8c0f1fe119f417fed074 Mon Sep 17 00:00:00 2001 From: maddyaby <32046405+maddyaby@users.noreply.github.com> Date: Thu, 16 Jun 2022 16:57:20 -0700 Subject: [PATCH 378/504] Stub out dcd_edpt_close for samd Not having this prevents the device from finishing the mounting process. Tested on a SAMD51 and didn't seem to need to actually do anything in the close function. --- src/portable/microchip/samd/dcd_samd.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/portable/microchip/samd/dcd_samd.c b/src/portable/microchip/samd/dcd_samd.c index 5ae5a554b..20dbde0f4 100644 --- a/src/portable/microchip/samd/dcd_samd.c +++ b/src/portable/microchip/samd/dcd_samd.c @@ -250,6 +250,13 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) return true; } +void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) { + (void) rhport; + (void) ep_addr; + + // TODO: implement if necessary? +} + void dcd_edpt_close_all (uint8_t rhport) { (void) rhport; From 905a0b24576deab6a2b4214b1428c87e4cd703a5 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 17 Jun 2022 14:37:35 +0700 Subject: [PATCH 379/504] correct bulk size for highspeed endpoint in dynamic_configuration and usbtmc exmaples --- examples/device/dynamic_configuration/src/usb_descriptors.c | 2 +- src/class/usbtmc/usbtmc_device.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/device/dynamic_configuration/src/usb_descriptors.c b/examples/device/dynamic_configuration/src/usb_descriptors.c index 3352972a5..b88f20163 100644 --- a/examples/device/dynamic_configuration/src/usb_descriptors.c +++ b/examples/device/dynamic_configuration/src/usb_descriptors.c @@ -163,7 +163,7 @@ uint8_t const desc_configuration_0[] = TUD_CONFIG_DESCRIPTOR(1, ITF_0_NUM_TOTAL, 0, CONFIG_0_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP notification address and size, EP data address (out, in) and size. - TUD_CDC_DESCRIPTOR(ITF_0_NUM_CDC, 0, EPNUM_0_CDC_NOTIF, 8, EPNUM_0_CDC_OUT, EPNUM_0_CDC_IN, 64), + TUD_CDC_DESCRIPTOR(ITF_0_NUM_CDC, 0, EPNUM_0_CDC_NOTIF, 8, EPNUM_0_CDC_OUT, EPNUM_0_CDC_IN, TUD_OPT_HIGH_SPEED ? 512 : 64), // Interface number, string index, EP Out & EP In address, EP size TUD_MIDI_DESCRIPTOR(ITF_0_NUM_MIDI, 0, EPNUM_0_MIDI_OUT, EPNUM_0_MIDI_IN, TUD_OPT_HIGH_SPEED ? 512 : 64), diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index 0549a1569..5dc4d2dff 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -37,7 +37,7 @@ // USB spec says that full-speed must be 8,16,32, or 64. // However, this driver implementation requires it to be >=32 -#define USBTMCD_MAX_PACKET_SIZE (64u) +#define USBTMCD_MAX_PACKET_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) /*********************************************** * Functions to be implemeted by the class implementation From 1001d2da401bc9abb98207d8f4be239ac62d5c33 Mon Sep 17 00:00:00 2001 From: mingpepe Date: Fri, 17 Jun 2022 16:50:24 +0800 Subject: [PATCH 380/504] Fix typo for log format --- src/portable/raspberrypi/rp2040/rp2040_usb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index f93568f0c..49be90167 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -174,7 +174,7 @@ static void __tusb_irq_path_func(_hw_endpoint_start_next_buffer)(struct hw_endpo *ep->endpoint_control = ep_ctrl; - TU_LOG(3, " Prepare BufCtrl: [0] = 0x%04u [1] = 0x%04x\r\n", tu_u32_low16(buf_ctrl), tu_u32_high16(buf_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 @@ -247,7 +247,7 @@ static void __tusb_irq_path_func(_hw_endpoint_xfer_sync) (struct hw_endpoint *ep // after a buff status interrupt uint32_t __unused buf_ctrl = _hw_endpoint_buffer_control_get_value32(ep); - TU_LOG(3, " Sync BufCtrl: [0] = 0x%04u [1] = 0x%04x\r\n", tu_u32_low16(buf_ctrl), tu_u32_high16(buf_ctrl)); + 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); @@ -285,7 +285,7 @@ static void __tusb_irq_path_func(_hw_endpoint_xfer_sync) (struct hw_endpoint *ep usb_hw->abort &= ~TU_BIT(ep_id); TU_LOG(3, "----SHORT PACKET buffer0 on EP %02X:\r\n", ep->ep_addr); - TU_LOG(3, " BufCtrl: [0] = 0x%04u [1] = 0x%04x\r\n", tu_u32_low16(buf_ctrl), tu_u32_high16(buf_ctrl)); + TU_LOG(3, " BufCtrl: [0] = 0x%04x [1] = 0x%04x\r\n", tu_u32_low16(buf_ctrl), tu_u32_high16(buf_ctrl)); #endif } } From c45118dacf176b232e22c49ed68acf8c95a1dfc6 Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Fri, 17 Jun 2022 09:13:40 -0500 Subject: [PATCH 381/504] rp2040: use shared IRQ handlers, so user can also hook the USB IRQ --- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 2 +- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index 4c8084878..c6018c515 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -363,7 +363,7 @@ void dcd_init (uint8_t rhport) usb_hw->pwr = USB_USB_PWR_VBUS_DETECT_BITS | USB_USB_PWR_VBUS_DETECT_OVERRIDE_EN_BITS; #endif - irq_set_exclusive_handler(USBCTRL_IRQ, dcd_rp2040_irq); + irq_add_shared_handler(USBCTRL_IRQ, dcd_rp2040_irq, PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY); // Init control endpoints tu_memclr(hw_endpoints[0], 2*sizeof(hw_endpoint_t)); diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 346326cd0..67d2de254 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -369,7 +369,7 @@ bool hcd_init(uint8_t rhport) // 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; - irq_set_exclusive_handler(USBCTRL_IRQ, hcd_rp2040_irq); + irq_add_shared_handler(USBCTRL_IRQ, hcd_rp2040_irq, PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY); // clear epx and interrupt eps memset(&ep_pool, 0, sizeof(ep_pool)); From 2f7f3e604eb2641dd87a524ab282939bda6b3348 Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Fri, 17 Jun 2022 12:54:28 -0500 Subject: [PATCH 382/504] Re-add some warning suppression for rp2040 --- hw/bsp/rp2040/family.cmake | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index df3a6a91e..ed7041e4e 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -232,6 +232,25 @@ if (NOT TARGET _rp2040_family_inclusion_marker) # This method must be called from the project scope to suppress known warnings in TinyUSB source files function(suppress_tinyusb_warnings) - # there are currently no warnings to suppress, however this function must still exist + set_source_files_properties( + ${PICO_TINYUSB_PATH}/src/device/usbd.c + PROPERTIES + COMPILE_FLAGS "-Wno-conversion") + set_source_files_properties( + ${PICO_TINYUSB_PATH}/src/device/usbd_control.c + PROPERTIES + COMPILE_FLAGS "-Wno-conversion") + set_source_files_properties( + ${PICO_TINYUSB_PATH}/src/class/cdc/cdc_device.c + PROPERTIES + COMPILE_FLAGS "-Wno-conversion") + set_source_files_properties( + ${PICO_TINYUSB_PATH}/src/common/tusb_fifo.c + PROPERTIES + COMPILE_FLAGS "-Wno-conversion") + set_source_files_properties( + ${PICO_TINYUSB_PATH}/src/tusb.c + PROPERTIES + COMPILE_FLAGS "-Wno-conversion") endfunction() endif() From 2cc2a90215f94692f18e0a402470c58366bfca47 Mon Sep 17 00:00:00 2001 From: maddyaby <32046405+maddyaby@users.noreply.github.com> Date: Fri, 17 Jun 2022 16:07:32 -0700 Subject: [PATCH 383/504] Allow more endpoint packet sizes for SAMD Tested on SAMD51 - we can allow more packet sizes by checking that the set size value is greater than the requested packet size instead of exactly the same. --- src/portable/microchip/samd/dcd_samd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/portable/microchip/samd/dcd_samd.c b/src/portable/microchip/samd/dcd_samd.c index 5ae5a554b..2f40c8247 100644 --- a/src/portable/microchip/samd/dcd_samd.c +++ b/src/portable/microchip/samd/dcd_samd.c @@ -222,14 +222,14 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) UsbDeviceDescBank* bank = &sram_registers[epnum][dir]; uint32_t size_value = 0; while (size_value < 7) { - if (1 << (size_value + 3) == tu_edpt_packet_size(desc_edpt)) { + if (1 << (size_value + 3) >= tu_edpt_packet_size(desc_edpt)) { break; } size_value++; } // unsupported endpoint size - if ( size_value == 7 && tu_edpt_packet_size(desc_edpt) != 1023 ) return false; + if ( size_value == 7 && tu_edpt_packet_size(desc_edpt) > 1023 ) return false; bank->PCKSIZE.bit.SIZE = size_value; From 742b99f6894ae2b4643c96790e51726e4ba9dc58 Mon Sep 17 00:00:00 2001 From: caleb crome Date: Tue, 21 Jun 2022 11:12:39 -0700 Subject: [PATCH 384/504] Added The Teensy 4.1 board The Teensy 4.1 board has an 8MB W25Q64JV as opposed to the 2MB flash on the Teensy 4.0. This largely doensn't matter for TinyUsb, except when you attempt to access any memory in the flash above the 2MB boundary, when it fails with a hard fault. --- hw/bsp/imxrt/boards/teensy_41/board.h | 52 ++++ hw/bsp/imxrt/boards/teensy_41/board.mk | 10 + .../teensy_41/teensy41_flexspi_nor_config.c | 49 ++++ .../teensy_41/teensy41_flexspi_nor_config.h | 268 ++++++++++++++++++ 4 files changed, 379 insertions(+) create mode 100644 hw/bsp/imxrt/boards/teensy_41/board.h create mode 100644 hw/bsp/imxrt/boards/teensy_41/board.mk create mode 100644 hw/bsp/imxrt/boards/teensy_41/teensy41_flexspi_nor_config.c create mode 100644 hw/bsp/imxrt/boards/teensy_41/teensy41_flexspi_nor_config.h diff --git a/hw/bsp/imxrt/boards/teensy_41/board.h b/hw/bsp/imxrt/boards/teensy_41/board.h new file mode 100644 index 000000000..b0b4931c7 --- /dev/null +++ b/hw/bsp/imxrt/boards/teensy_41/board.h @@ -0,0 +1,52 @@ +/* + * 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 BOARD_H_ +#define BOARD_H_ + + +// required since iMX RT10xx SDK include this file for board size +#define BOARD_FLASH_SIZE (8 * 1024 * 1024) + +// LED +#define LED_PINMUX IOMUXC_GPIO_B0_03_GPIO2_IO03 // D13 +#define LED_PORT GPIO2 +#define LED_PIN 3 +#define LED_STATE_ON 0 + +// no button +#define BUTTON_PINMUX IOMUXC_GPIO_B0_01_GPIO2_IO01 // D12 +#define BUTTON_PORT GPIO2 +#define BUTTON_PIN 1 +#define BUTTON_STATE_ACTIVE 0 + +// UART +#define UART_PORT LPUART6 +#define UART_RX_PINMUX IOMUXC_GPIO_AD_B0_03_LPUART6_RX // D0 +#define UART_TX_PINMUX IOMUXC_GPIO_AD_B0_02_LPUART6_TX // D1 + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/imxrt/boards/teensy_41/board.mk b/hw/bsp/imxrt/boards/teensy_41/board.mk new file mode 100644 index 000000000..0ad5ea5c0 --- /dev/null +++ b/hw/bsp/imxrt/boards/teensy_41/board.mk @@ -0,0 +1,10 @@ +CFLAGS += -DCPU_MIMXRT1062DVL6A +MCU_VARIANT = MIMXRT1062 + +# For flash-jlink target +JLINK_DEVICE = MIMXRT1062xxx6A + +# flash by using teensy_loader_cli https://github.com/PaulStoffregen/teensy_loader_cli +# Make sure it is in your PATH +flash: $(BUILD)/$(PROJECT).hex + teensy_loader_cli --mcu=imxrt1062 -v -w $< diff --git a/hw/bsp/imxrt/boards/teensy_41/teensy41_flexspi_nor_config.c b/hw/bsp/imxrt/boards/teensy_41/teensy41_flexspi_nor_config.c new file mode 100644 index 000000000..2d2bf8f09 --- /dev/null +++ b/hw/bsp/imxrt/boards/teensy_41/teensy41_flexspi_nor_config.c @@ -0,0 +1,49 @@ +/* + * Copyright 2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.xip_board" +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ +#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) +__attribute__((section(".boot_hdr.conf"))) +#elif defined(__ICCARM__) +#pragma location = ".boot_hdr.conf" +#endif + +const flexspi_nor_config_t qspiflash_config = { + .memConfig = + { + .tag = FLEXSPI_CFG_BLK_TAG, + .version = FLEXSPI_CFG_BLK_VERSION, + .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .csHoldTime = 3u, + .csSetupTime = 3u, + // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock + .sflashPadType = kSerialFlash_4Pads, + .serialClkFreq = kFlexSpiSerialClk_100MHz, + .sflashA1Size = 8u * 1024u * 1024u, + .lookupTable = + { + // Read LUTs + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18), + FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), + }, + }, + .pageSize = 256u, + .sectorSize = 4u * 1024u, + .blockSize = 256u * 1024u, + .isUniformBlockSize = false, +}; +#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/hw/bsp/imxrt/boards/teensy_41/teensy41_flexspi_nor_config.h b/hw/bsp/imxrt/boards/teensy_41/teensy41_flexspi_nor_config.h new file mode 100644 index 000000000..56068ec6a --- /dev/null +++ b/hw/bsp/imxrt/boards/teensy_41/teensy41_flexspi_nor_config.h @@ -0,0 +1,268 @@ +/* + * Copyright 2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __TEENSY40_FLEXSPI_NOR_CONFIG__ +#define __TEENSY40_FLEXSPI_NOR_CONFIG__ + +#include +#include +#include "fsl_common.h" + +/*! @name Driver version */ +/*@{*/ +/*! @brief XIP_BOARD driver version 2.0.0. */ +#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/* FLEXSPI memory config block related defintions */ +#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian +#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 +#define FLEXSPI_CFG_BLK_SIZE (512) + +/* FLEXSPI Feature related definitions */ +#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 + +/* Lookup table related defintions */ +#define CMD_INDEX_READ 0 +#define CMD_INDEX_READSTATUS 1 +#define CMD_INDEX_WRITEENABLE 2 +#define CMD_INDEX_WRITE 4 + +#define CMD_LUT_SEQ_IDX_READ 0 +#define CMD_LUT_SEQ_IDX_READSTATUS 1 +#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define CMD_LUT_SEQ_IDX_WRITE 9 + +#define CMD_SDR 0x01 +#define CMD_DDR 0x21 +#define RADDR_SDR 0x02 +#define RADDR_DDR 0x22 +#define CADDR_SDR 0x03 +#define CADDR_DDR 0x23 +#define MODE1_SDR 0x04 +#define MODE1_DDR 0x24 +#define MODE2_SDR 0x05 +#define MODE2_DDR 0x25 +#define MODE4_SDR 0x06 +#define MODE4_DDR 0x26 +#define MODE8_SDR 0x07 +#define MODE8_DDR 0x27 +#define WRITE_SDR 0x08 +#define WRITE_DDR 0x28 +#define READ_SDR 0x09 +#define READ_DDR 0x29 +#define LEARN_SDR 0x0A +#define LEARN_DDR 0x2A +#define DATSZ_SDR 0x0B +#define DATSZ_DDR 0x2B +#define DUMMY_SDR 0x0C +#define DUMMY_DDR 0x2C +#define DUMMY_RWDS_SDR 0x0D +#define DUMMY_RWDS_DDR 0x2D +#define JMP_ON_CS 0x1F +#define STOP 0 + +#define FLEXSPI_1PAD 0 +#define FLEXSPI_2PAD 1 +#define FLEXSPI_4PAD 2 +#define FLEXSPI_8PAD 3 + +#define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \ + (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \ + FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1)) + +//!@brief Definitions for FlexSPI Serial Clock Frequency +typedef enum _FlexSpiSerialClockFreq +{ + kFlexSpiSerialClk_30MHz = 1, + kFlexSpiSerialClk_50MHz = 2, + kFlexSpiSerialClk_60MHz = 3, + kFlexSpiSerialClk_75MHz = 4, + kFlexSpiSerialClk_80MHz = 5, + kFlexSpiSerialClk_100MHz = 6, + kFlexSpiSerialClk_120MHz = 7, + kFlexSpiSerialClk_133MHz = 8, + kFlexSpiSerialClk_166MHz = 9, +} flexspi_serial_clk_freq_t; + +//!@brief FlexSPI clock configuration type +enum +{ + kFlexSpiClk_SDR, //!< Clock configure for SDR mode + kFlexSpiClk_DDR, //!< Clock configurat for DDR mode +}; + +//!@brief FlexSPI Read Sample Clock Source definition +typedef enum _FlashReadSampleClkSource +{ + kFlexSPIReadSampleClk_LoopbackInternally = 0, + kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, + kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, + kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, +} flexspi_read_sample_clk_t; + +//!@brief Misc feature bit definitions +enum +{ + kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable + kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable + kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable + kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable + kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable + kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable + kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. +}; + +//!@brief Flash Type Definition +enum +{ + kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR + kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND + kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH + kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND + kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs +}; + +//!@brief Flash Pad Definitions +enum +{ + kSerialFlash_1Pad = 1, + kSerialFlash_2Pads = 2, + kSerialFlash_4Pads = 4, + kSerialFlash_8Pads = 8, +}; + +//!@brief FlexSPI LUT Sequence structure +typedef struct _lut_sequence +{ + uint8_t seqNum; //!< Sequence Number, valid number: 1-16 + uint8_t seqId; //!< Sequence Index, valid number: 0-15 + uint16_t reserved; +} flexspi_lut_seq_t; + +//!@brief Flash Configuration Command Type +enum +{ + kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc + kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command + kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode + kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode + kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode + kDeviceConfigCmdType_Reset, //!< Reset device command +}; + +//!@brief FlexSPI Memory Configuration Block +typedef struct _FlexSPIConfig +{ + uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL + uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix + uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use + uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 + uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 + uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 + uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For + //! Serial NAND, need to refer to datasheet + uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable + uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, + //! Generic configuration, etc. + uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for + //! DPI/QPI/OPI switch or reset command + flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt + //! sequence number, [31:16] Reserved + uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration + uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable + uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe + flexspi_lut_seq_t + configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq + uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use + uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands + uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use + uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more + //! details + uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details + uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal + uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot + //! Chapter for more details + uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot + //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH + uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use + uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 + uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 + uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 + uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 + uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value + uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value + uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value + uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value + uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command + uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands + uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns + uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 + uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - + //! busy flag is 0 when flash device is busy + uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences + flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences + uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use +} flexspi_mem_config_t; + +/* */ +#define NOR_CMD_INDEX_READ CMD_INDEX_READ //!< 0 +#define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS //!< 1 +#define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE //!< 2 +#define NOR_CMD_INDEX_ERASESECTOR 3 //!< 3 +#define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE //!< 4 +#define NOR_CMD_INDEX_CHIPERASE 5 //!< 5 +#define NOR_CMD_INDEX_DUMMY 6 //!< 6 +#define NOR_CMD_INDEX_ERASEBLOCK 7 //!< 7 + +#define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ //!< 0 READ LUT sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS \ + CMD_LUT_SEQ_IDX_READSTATUS //!< 1 Read Status LUT sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \ + 2 //!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \ + CMD_LUT_SEQ_IDX_WRITEENABLE //!< 3 Write Enable sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \ + 4 //!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 //!< 5 Erase Sector sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 //!< 8 Erase Block sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \ + CMD_LUT_SEQ_IDX_WRITE //!< 9 Program sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 //!< 11 Chip Erase sequence in lookupTable id stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 //!< 13 Read SFDP sequence in lookupTable id stored in config block +#define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \ + 14 //!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \ + 15 //!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk + +/* + * Serial NOR configuration block + */ +typedef struct _flexspi_nor_config +{ + flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI + uint32_t pageSize; //!< Page size of Serial NOR + uint32_t sectorSize; //!< Sector size of Serial NOR + uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command + uint8_t isUniformBlockSize; //!< Sector/Block size is the same + uint8_t reserved0[2]; //!< Reserved for future use + uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 + uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command + uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false + uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP commmand execution + uint32_t blockSize; //!< Block size + uint32_t reserve2[11]; //!< Reserved for future use +} flexspi_nor_config_t; + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __EVKMIMXRT1060_FLEXSPI_NOR_CONFIG__ */ From e9c29e6a2d42f931ededbc3ad1467cdd5dc1ea33 Mon Sep 17 00:00:00 2001 From: NConrad Date: Tue, 21 Jun 2022 21:27:52 -0400 Subject: [PATCH 385/504] Update USBTMC driver to support dynamic packet sizes (based on descriptor). --- src/class/usbtmc/usbtmc_device.c | 36 +++++++++++++++++++------------- src/class/usbtmc/usbtmc_device.h | 4 ---- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index b02b07575..9608e4835 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -64,7 +64,8 @@ // USBTMC 3.2.2 error conditions not strictly followed // No local lock-out, REN, or GTL. // Clear message available status byte at the correct time? (488 4.3.1.3) - +// Ability to defer status byte transmission +// Transmission of status byte in response to USB488 SRQ condition #include "tusb_option.h" @@ -80,6 +81,11 @@ static char logMsg[150]; #endif +// Buffer size must be an exact multiple of the max packet size for both +// bulk (up to 64 bytes for FS, 512 bytes for HS). In addation, this driver +// imposes a minimum buffer size of 32 bytes. +#define USBTMCD_BUFFER_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) + /* * The state machine does not allow simultaneous reading and writing. This is * consistent with USBTMC. @@ -120,9 +126,12 @@ typedef struct uint8_t ep_int_in; // IN buffer is only used for first packet, not the remainder // in order to deal with prepending header - CFG_TUSB_MEM_ALIGN uint8_t ep_bulk_in_buf[USBTMCD_MAX_PACKET_SIZE]; + CFG_TUSB_MEM_ALIGN uint8_t ep_bulk_in_buf[USBTMCD_BUFFER_SIZE]; + uint32_t ep_bulk_in_wMaxPacketSize; // OUT buffer receives one packet at a time - CFG_TUSB_MEM_ALIGN uint8_t ep_bulk_out_buf[USBTMCD_MAX_PACKET_SIZE]; + CFG_TUSB_MEM_ALIGN uint8_t ep_bulk_out_buf[USBTMCD_BUFFER_SIZE]; + uint32_t ep_bulk_out_wMaxPacketSize; + uint32_t transfer_size_remaining; // also used for requested length for bulk IN. uint32_t transfer_size_sent; // To keep track of data bytes that have been queued in FIFO (not header bytes) @@ -139,11 +148,8 @@ CFG_TUSB_MEM_SECTION static usbtmc_interface_state_t usbtmc_state = .itf_id = 0xFF, }; -// We need all headers to fit in a single packet in this implementation. -TU_VERIFY_STATIC(USBTMCD_MAX_PACKET_SIZE >= 32u,"USBTMC dev EP packet size too small"); -TU_VERIFY_STATIC( - (sizeof(usbtmc_state.ep_bulk_in_buf) % USBTMCD_MAX_PACKET_SIZE) == 0, - "packet buffer must be a multiple of the packet size"); +// We need all headers to fit in a single packet in this implementation, 32 bytes will fit all standard USBTMC headers +TU_VERIFY_STATIC(USBTMCD_BUFFER_SIZE >= 32u,"USBTMC dev buffer size too small"); static bool handle_devMsgOutStart(uint8_t rhport, void *data, size_t len); static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len, size_t packetLen); @@ -151,7 +157,6 @@ static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len, size_t pack static uint8_t termChar; static uint8_t termCharRequested = false; - osal_mutex_def_t usbtmcLockBuffer; static osal_mutex_t usbtmcLock; @@ -282,12 +287,15 @@ uint16_t usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, tusb_desc_endpoint_t const *ep_desc = (tusb_desc_endpoint_t const *)p_desc; switch(ep_desc->bmAttributes.xfer) { case TUSB_XFER_BULK: - TU_ASSERT(tu_edpt_packet_size(ep_desc) == USBTMCD_MAX_PACKET_SIZE, 0); + // Ensure buffer is an exact multiple of the maxPacketSize + TU_ASSERT((USBTMCD_BUFFER_SIZE % tu_edpt_packet_size(ep_desc)) == 0, 0); if (tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN) { usbtmc_state.ep_bulk_in = ep_desc->bEndpointAddress; + usbtmc_state.ep_bulk_in_wMaxPacketSize = tu_edpt_packet_size(ep_desc); } else { usbtmc_state.ep_bulk_out = ep_desc->bEndpointAddress; + usbtmc_state.ep_bulk_out_wMaxPacketSize = tu_edpt_packet_size(ep_desc); } break; @@ -395,7 +403,7 @@ static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len, size_t pack // return true upon failure, as we can assume error is being handled elsewhere. TU_VERIFY(usbtmc_state.state == STATE_RCV,true); - bool shortPacket = (packetLen < USBTMCD_MAX_PACKET_SIZE); + bool shortPacket = (packetLen < usbtmc_state.ep_bulk_out_wMaxPacketSize); // Packet is to be considered complete when we get enough data or at a short packet. bool atEnd = false; @@ -522,7 +530,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint break; case STATE_TX_INITIATED: - if(usbtmc_state.transfer_size_remaining >=sizeof(usbtmc_state.ep_bulk_in_buf)) + if(usbtmc_state.transfer_size_remaining >= sizeof(usbtmc_state.ep_bulk_in_buf)) { // FIXME! This removes const below! TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, @@ -539,7 +547,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint usbtmc_state.transfer_size_remaining = 0; usbtmc_state.devInBuffer = NULL; TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf, (uint16_t)packetLen) ); - if(((packetLen % USBTMCD_MAX_PACKET_SIZE) != 0) || (packetLen == 0 )) + if(((packetLen % usbtmc_state.ep_bulk_in_wMaxPacketSize) != 0) || (packetLen == 0 )) { usbtmc_state.state = STATE_TX_SHORTED; } @@ -680,7 +688,7 @@ bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request usbtmc_state.transfer_size_remaining = 0u; // Check if we've queued a short packet criticalEnter(); - usbtmc_state.state = ((usbtmc_state.transfer_size_sent % USBTMCD_MAX_PACKET_SIZE) == 0) ? + usbtmc_state.state = ((usbtmc_state.transfer_size_sent % usbtmc_state.ep_bulk_in_wMaxPacketSize) == 0) ? STATE_ABORTING_BULK_IN : STATE_ABORTING_BULK_IN_SHORTED; criticalLeave(); if(usbtmc_state.transfer_size_sent == 0) diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index 5dc4d2dff..144b3315d 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -35,10 +35,6 @@ #define CFG_TUD_USBTMC_ENABLE_488 (1) #endif -// USB spec says that full-speed must be 8,16,32, or 64. -// However, this driver implementation requires it to be >=32 -#define USBTMCD_MAX_PACKET_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) - /*********************************************** * Functions to be implemeted by the class implementation */ From 4a9fe813a807a32bf41ba2ec266a59a443b35d6f Mon Sep 17 00:00:00 2001 From: NConrad Date: Tue, 21 Jun 2022 22:31:09 -0400 Subject: [PATCH 386/504] Update USBTMC descriptors to support high speed, set USB version to 2.0.0 for all cases. --- examples/device/usbtmc/src/usb_descriptors.c | 70 +++++++++++++++++--- 1 file changed, 59 insertions(+), 11 deletions(-) diff --git a/examples/device/usbtmc/src/usb_descriptors.c b/examples/device/usbtmc/src/usb_descriptors.c index 423482634..0946027e4 100644 --- a/examples/device/usbtmc/src/usb_descriptors.c +++ b/examples/device/usbtmc/src/usb_descriptors.c @@ -37,6 +37,9 @@ #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 //--------------------------------------------------------------------+ @@ -51,9 +54,9 @@ tusb_desc_device_t const desc_device = .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, - .idVendor = 0xCafe, + .idVendor = USB_VID, .idProduct = USB_PID, - .bcdDevice = 0x0100, + .bcdDevice = USB_BCD, .iManufacturer = 0x01, .iProduct = 0x02, @@ -75,22 +78,22 @@ uint8_t const * tud_descriptor_device_cb(void) #if defined(CFG_TUD_USBTMC) -# define TUD_USBTMC_DESC_MAIN(_itfnum,_bNumEndpoints) \ +# define TUD_USBTMC_DESC_MAIN(_itfnum,_bNumEndpoints, _bulkMaxPacketLength) \ TUD_USBTMC_IF_DESCRIPTOR(_itfnum, _bNumEndpoints, /*_stridx = */ 4u, TUD_USBTMC_PROTOCOL_USB488), \ - TUD_USBTMC_BULK_DESCRIPTORS(/* OUT = */0x01, /* IN = */ 0x81, /* packet size = */USBTMCD_MAX_PACKET_SIZE) + TUD_USBTMC_BULK_DESCRIPTORS(/* OUT = */0x01, /* IN = */ 0x81, /* packet size = */_bulkMaxPacketLength) #if CFG_TUD_USBTMC_ENABLE_INT_EP // USBTMC Interrupt xfer always has length of 2, but we use epMaxSize=8 for // compatibility with mcus that only allow 8, 16, 32 or 64 for FS endpoints -# define TUD_USBTMC_DESC(_itfnum) \ - TUD_USBTMC_DESC_MAIN(_itfnum, /* _epCount = */ 3), \ +# define TUD_USBTMC_DESC(_itfnum, _bulkMaxPacketLength) \ + TUD_USBTMC_DESC_MAIN(_itfnum, /* _epCount = */ 3, _bulkMaxPacketLength), \ TUD_USBTMC_INT_DESCRIPTOR(/* INT ep # */ 0x82, /* epMaxSize = */ 8, /* bInterval = */16u ) # define TUD_USBTMC_DESC_LEN (TUD_USBTMC_IF_DESCRIPTOR_LEN + TUD_USBTMC_BULK_DESCRIPTORS_LEN + TUD_USBTMC_INT_DESCRIPTOR_LEN) #else -# define TUD_USBTMC_DESC(_itfnum) \ - TUD_USBTMC_DESC_MAIN(_itfnum, /* _epCount = */ 2u) +# define TUD_USBTMC_DESC(_itfnum, _bulkMaxPacketLength) \ + TUD_USBTMC_DESC_MAIN(_itfnum, /* _epCount = */ 2u, _bulkMaxPacketLength) # define TUD_USBTMC_DESC_LEN (TUD_USBTMC_IF_DESCRIPTOR_LEN + TUD_USBTMC_BULK_DESCRIPTORS_LEN) #endif /* CFG_TUD_USBTMC_ENABLE_INT_EP */ @@ -119,21 +122,66 @@ enum #endif -uint8_t const desc_configuration[] = +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), - TUD_USBTMC_DESC(ITF_NUM_USBTMC), + TUD_USBTMC_DESC(ITF_NUM_USBTMC, /* _bulkMaxPacketLength = */ 64), }; +#if TUD_OPT_HIGH_SPEED + +uint8_t const desc_hs_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), + + TUD_USBTMC_DESC(ITF_NUM_USBTMC, /* _bulkMaxPacketLength = */ 512), +}; + +// other speed configuration +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 +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; +} + +#endif + // 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 - return desc_configuration; +#if TUD_OPT_HIGH_SPEED + // Although we are highspeed, host may be fullspeed. + return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration; +#else + return desc_fs_configuration; +#endif } //--------------------------------------------------------------------+ From 4f6e770eda9f8c605b238f35def1edaff93a8fb8 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 24 Jun 2022 19:45:49 +0700 Subject: [PATCH 387/504] add more warning option, also fix -Wconversion with rp2040 -Wuninitialized, -Wunused, -Wredundant-decls --- examples/device/cdc_msc/src/usb_descriptors.c | 2 +- examples/make.mk | 7 +++- hw/bsp/broadcom_32bit/family.mk | 2 +- hw/bsp/broadcom_64bit/family.mk | 2 +- hw/bsp/imxrt/family.mk | 2 +- .../boards/mm32f327x_mb39/mm32f327x_mb39.c | 1 - hw/bsp/nrf/family.mk | 3 ++ hw/bsp/rx/family.mk | 3 ++ hw/bsp/samd21/family.mk | 2 +- hw/bsp/saml2x/family.mk | 2 +- hw/mcu/raspberry_pi/Pico-PIO-USB | 2 +- src/class/cdc/cdc_device.c | 6 ++-- src/class/msc/msc_device.c | 33 ++++++++++--------- src/common/tusb_fifo.c | 12 +++---- src/device/usbd.c | 16 +++++---- src/device/usbd_control.c | 2 +- src/portable/synopsys/dwc2/dwc2_stm32.h | 3 +- 17 files changed, 58 insertions(+), 42 deletions(-) diff --git a/examples/device/cdc_msc/src/usb_descriptors.c b/examples/device/cdc_msc/src/usb_descriptors.c index 09894cf1b..6b59ed50f 100644 --- a/examples/device/cdc_msc/src/usb_descriptors.c +++ b/examples/device/cdc_msc/src/usb_descriptors.c @@ -282,7 +282,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/make.mk b/examples/make.mk index bed46d02b..26065c027 100644 --- a/examples/make.mk +++ b/examples/make.mk @@ -108,8 +108,13 @@ CFLAGS += \ -Wcast-align \ -Wcast-function-type \ -Wcast-qual \ - -Wnull-dereference + -Wnull-dereference \ + -Wuninitialized \ + -Wunused \ + -Wredundant-decls +# -Wconversion \ + # Debugging/Optimization ifeq ($(DEBUG), 1) CFLAGS += -Og diff --git a/hw/bsp/broadcom_32bit/family.mk b/hw/bsp/broadcom_32bit/family.mk index 98744c5d0..cf68e21ee 100644 --- a/hw/bsp/broadcom_32bit/family.mk +++ b/hw/bsp/broadcom_32bit/family.mk @@ -16,7 +16,7 @@ CFLAGS += \ CROSS_COMPILE = arm-none-eabi- # mcu driver cause following warnings -CFLAGS += -Wno-error=cast-qual +CFLAGS += -Wno-error=cast-qual -Wno-error=redundant-decls SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ diff --git a/hw/bsp/broadcom_64bit/family.mk b/hw/bsp/broadcom_64bit/family.mk index 723926734..97af6d64a 100644 --- a/hw/bsp/broadcom_64bit/family.mk +++ b/hw/bsp/broadcom_64bit/family.mk @@ -15,7 +15,7 @@ CFLAGS += \ CROSS_COMPILE = aarch64-none-elf- # mcu driver cause following warnings -CFLAGS += -Wno-error=cast-qual +CFLAGS += -Wno-error=cast-qual -Wno-error=redundant-decls SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ diff --git a/hw/bsp/imxrt/family.mk b/hw/bsp/imxrt/family.mk index c81e67eb6..0a55b740b 100644 --- a/hw/bsp/imxrt/family.mk +++ b/hw/bsp/imxrt/family.mk @@ -23,7 +23,7 @@ CFLAGS += -DBOARD_TUH_RHPORT=$(BOARD_TUH_RHPORT) endif # mcu driver cause following warnings -CFLAGS += -Wno-error=unused-parameter -Wno-error=implicit-fallthrough= +CFLAGS += -Wno-error=unused-parameter -Wno-error=implicit-fallthrough -Wno-error=redundant-decls MCU_DIR = $(SDK_DIR)/devices/$(MCU_VARIANT) diff --git a/hw/bsp/mm32/boards/mm32f327x_mb39/mm32f327x_mb39.c b/hw/bsp/mm32/boards/mm32f327x_mb39/mm32f327x_mb39.c index cff7bc15e..9793ba241 100644 --- a/hw/bsp/mm32/boards/mm32f327x_mb39/mm32f327x_mb39.c +++ b/hw/bsp/mm32/boards/mm32f327x_mb39/mm32f327x_mb39.c @@ -52,7 +52,6 @@ void USB_DeviceClockInit (void) //--------------------------------------------------------------------+ // LED -void board_led_write (bool state); extern u32 SystemCoreClock; const int baudrate = 115200; diff --git a/hw/bsp/nrf/family.mk b/hw/bsp/nrf/family.mk index d8283a9e6..609e2da0b 100644 --- a/hw/bsp/nrf/family.mk +++ b/hw/bsp/nrf/family.mk @@ -16,6 +16,9 @@ CFLAGS += \ # suppress warning caused by vendor mcu driver CFLAGS += -Wno-error=undef -Wno-error=unused-parameter -Wno-error=cast-align -Wno-error=cast-qual +# warning caused by dcd_nrf5x.c due to include of usbd.h and re-declare of dcd_int_handler() +CFLAGS += -Wno-error=redundant-decls + # All source paths should be relative to the top level. LD_FILE ?= hw/bsp/nrf/boards/$(BOARD)/nrf52840_s140_v6.ld diff --git a/hw/bsp/rx/family.mk b/hw/bsp/rx/family.mk index aba05812d..f4f8ae088 100644 --- a/hw/bsp/rx/family.mk +++ b/hw/bsp/rx/family.mk @@ -13,6 +13,9 @@ CFLAGS += \ -mlittle-endian-data \ -DSSIZE_MAX=__INT_MAX__ +# suppress warning caused by vendor mcu driver +CFLAGS += -Wno-error=redundant-decls + SRC_C += \ src/portable/renesas/usba/dcd_usba.c \ src/portable/renesas/usba/hcd_usba.c \ diff --git a/hw/bsp/samd21/family.mk b/hw/bsp/samd21/family.mk index 208f23789..95421e753 100644 --- a/hw/bsp/samd21/family.mk +++ b/hw/bsp/samd21/family.mk @@ -13,7 +13,7 @@ CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_SAMD21 # suppress warning caused by vendor mcu driver -CFLAGS += -Wno-error=cast-qual +CFLAGS += -Wno-error=cast-qual -Wno-error=redundant-decls SRC_C += \ src/portable/microchip/samd/dcd_samd.c \ diff --git a/hw/bsp/saml2x/family.mk b/hw/bsp/saml2x/family.mk index bb1faeb7f..afb0afc03 100644 --- a/hw/bsp/saml2x/family.mk +++ b/hw/bsp/saml2x/family.mk @@ -14,7 +14,7 @@ CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_SAML22 # suppress warning caused by vendor mcu driver -CFLAGS += -Wno-error=cast-qual +CFLAGS += -Wno-error=cast-qual -Wno-error=redundant-decls SRC_C += \ src/portable/microchip/samd/dcd_samd.c \ diff --git a/hw/mcu/raspberry_pi/Pico-PIO-USB b/hw/mcu/raspberry_pi/Pico-PIO-USB index 2a9fefd6c..92bd3b4c3 160000 --- a/hw/mcu/raspberry_pi/Pico-PIO-USB +++ b/hw/mcu/raspberry_pi/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit 2a9fefd6ccf42e5d8570ae83fdc54c9c875ebdd1 +Subproject commit 92bd3b4c3ad2fce36166e4a357749b6d4fe9013b diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 7aa7a4860..fab6f0035 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -145,7 +145,7 @@ uint32_t tud_cdc_n_available(uint8_t itf) uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - uint32_t num_read = tu_fifo_read_n(&p_cdc->rx_ff, buffer, bufsize); + uint32_t num_read = tu_fifo_read_n(&p_cdc->rx_ff, buffer, (uint16_t) bufsize); _prep_out_transaction(p_cdc); return num_read; } @@ -168,7 +168,7 @@ void tud_cdc_n_read_flush (uint8_t itf) uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - uint16_t ret = tu_fifo_write_n(&p_cdc->tx_ff, buffer, bufsize); + uint16_t ret = tu_fifo_write_n(&p_cdc->tx_ff, buffer, (uint16_t) bufsize); // flush if queue more than packet size if ( tu_fifo_count(&p_cdc->tx_ff) >= BULK_PACKET_SIZE ) @@ -435,7 +435,7 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ // Received new data if ( ep_addr == p_cdc->ep_out ) { - tu_fifo_write_n(&p_cdc->rx_ff, &p_cdc->epout_buf, xferred_bytes); + tu_fifo_write_n(&p_cdc->rx_ff, &p_cdc->epout_buf, (uint16_t) xferred_bytes); // Check for wanted char and invoke callback if needed if ( tud_cdc_rx_wanted_cb && (((signed char) p_cdc->wanted_char) != -1) ) diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 3facb76d6..33dd4ac37 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -463,7 +463,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t { // Didn't check for case 9 (Ho > Dn), which requires examining scsi command first // but it is OK to just receive data then responded with failed status - TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, p_msc->total_len) ); + TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, (uint16_t) p_msc->total_len) ); } }else { @@ -473,7 +473,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t // Invoke user callback if not built-in if ( (resplen < 0) && (p_msc->sense_key == 0) ) { - resplen = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_buf, p_msc->total_len); + resplen = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_buf, (uint16_t) p_msc->total_len); } if ( resplen < 0 ) @@ -506,7 +506,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t { // cannot return more than host expect p_msc->total_len = tu_min32((uint32_t) resplen, p_cbw->total_bytes); - TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, p_msc->total_len) ); + TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, (uint16_t) p_msc->total_len) ); } } } @@ -541,7 +541,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t // OUT transfer, invoke callback if needed if ( !is_data_in(p_cbw->dir) ) { - int32_t cb_result = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_buf, p_msc->total_len); + int32_t cb_result = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_buf, (uint16_t) p_msc->total_len); if ( cb_result < 0 ) { @@ -707,7 +707,7 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ read_capa10.block_size = tu_htonl(block_size); resplen = sizeof(read_capa10); - memcpy(buffer, &read_capa10, resplen); + memcpy(buffer, &read_capa10, (size_t) resplen); } } break; @@ -741,7 +741,7 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ read_fmt_capa.block_size_u16 = tu_htons(block_size); resplen = sizeof(read_fmt_capa); - memcpy(buffer, &read_fmt_capa, resplen); + memcpy(buffer, &read_fmt_capa, (size_t) resplen); } } break; @@ -764,7 +764,7 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ tud_msc_inquiry_cb(lun, inquiry_rsp.vendor_id, inquiry_rsp.product_id, inquiry_rsp.product_rev); resplen = sizeof(inquiry_rsp); - memcpy(buffer, &inquiry_rsp, resplen); + memcpy(buffer, &inquiry_rsp, (size_t) resplen); } break; @@ -788,7 +788,7 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ mode_resp.write_protected = !writable; resplen = sizeof(mode_resp); - memcpy(buffer, &mode_resp, resplen); + memcpy(buffer, &mode_resp, (size_t) resplen); } break; @@ -801,17 +801,17 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ }; sense_rsp.add_sense_len = sizeof(scsi_sense_fixed_resp_t) - 8; - sense_rsp.sense_key = p_msc->sense_key; + sense_rsp.sense_key = (uint8_t) (p_msc->sense_key & 0x0F); sense_rsp.add_sense_code = p_msc->add_sense_code; sense_rsp.add_sense_qualifier = p_msc->add_sense_qualifier; resplen = sizeof(sense_rsp); - memcpy(buffer, &sense_rsp, resplen); + memcpy(buffer, &sense_rsp, (size_t) resplen); // request sense callback could overwrite the sense data if (tud_msc_request_sense_cb) { - resplen = tud_msc_request_sense_cb(lun, buffer, bufsize); + resplen = tud_msc_request_sense_cb(lun, buffer, (uint16_t) bufsize); } // Clear sense data after copy @@ -859,7 +859,7 @@ static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc) } else { - TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, nbytes), ); + TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, (uint16_t) nbytes), ); } } @@ -883,7 +883,7 @@ static void proc_write10_cmd(uint8_t rhport, mscd_interface_t* p_msc) } // remaining bytes capped at class buffer - int32_t nbytes = (int32_t) tu_min32(sizeof(_mscd_buf), p_cbw->total_bytes-p_msc->xferred_len); + uint16_t nbytes = (uint16_t) tu_min32(sizeof(_mscd_buf), p_cbw->total_bytes-p_msc->xferred_len); // Write10 callback will be called later when usb transfer complete TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, nbytes), ); @@ -921,14 +921,15 @@ static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint3 // Application consume less than what we got (including zero) if ( (uint32_t) nbytes < xferred_bytes ) { + uint32_t const left_over = xferred_bytes - (uint32_t) nbytes; if ( nbytes > 0 ) { - p_msc->xferred_len += nbytes; - memmove(_mscd_buf, _mscd_buf+nbytes, xferred_bytes-nbytes); + p_msc->xferred_len += (uint16_t) nbytes; + memmove(_mscd_buf, _mscd_buf+nbytes, left_over); } // simulate an transfer complete with adjusted parameters --> callback will be invoked with adjusted parameter - dcd_event_xfer_complete(rhport, p_msc->ep_out, xferred_bytes-nbytes, XFER_RESULT_SUCCESS, false); + dcd_event_xfer_complete(rhport, p_msc->ep_out, left_over, XFER_RESULT_SUCCESS, false); } else { diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index 183c9c6fc..895b9208b 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -79,7 +79,7 @@ bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_si // Limit index space to 2*depth - this allows for a fast "modulo" calculation // but limits the maximum depth to 2^16/2 = 2^15 and buffer overflows are detectable // only if overflow happens once (important for unsupervised DMA applications) - f->max_pointer_idx = 2*depth - 1; + f->max_pointer_idx = (uint16_t) (2*depth - 1); f->non_used_index_space = UINT16_MAX - f->max_pointer_idx; f->rd_idx = f->wr_idx = 0; @@ -205,7 +205,7 @@ static void _ff_push_n(tu_fifo_t* f, void const * app_buf, uint16_t n, uint16_t uint8_t rem = nLin_bytes & 0x03; if (rem > 0) { - uint8_t remrem = tu_min16(nWrap_bytes, 4-rem); + uint8_t remrem = (uint8_t) tu_min16(nWrap_bytes, 4-rem); nWrap_bytes -= remrem; uint32_t tmp32 = *rx_fifo; @@ -288,7 +288,7 @@ static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rel, tu uint8_t rem = nLin_bytes & 0x03; if (rem > 0) { - uint8_t remrem = tu_min16(nWrap_bytes, 4-rem); + uint8_t remrem = (uint8_t) tu_min16(nWrap_bytes, 4-rem); nWrap_bytes -= remrem; uint32_t tmp32=0; @@ -325,7 +325,7 @@ static uint16_t advance_pointer(tu_fifo_t* f, uint16_t p, uint16_t offset) // We are exploiting the wrap around to the correct index if ((p > (uint16_t)(p + offset)) || ((uint16_t)(p + offset) > f->max_pointer_idx)) { - p = (p + offset) + f->non_used_index_space; + p = (uint16_t) ((p + offset) + f->non_used_index_space); } else { @@ -342,7 +342,7 @@ static uint16_t backward_pointer(tu_fifo_t* f, uint16_t p, uint16_t offset) // We are exploiting the wrap around to the correct index if ((p < (uint16_t)(p - offset)) || ((uint16_t)(p - offset) > f->max_pointer_idx)) { - p = (p - offset) - f->non_used_index_space; + p = (uint16_t) ((p - offset) - f->non_used_index_space); } else { @@ -818,7 +818,7 @@ bool tu_fifo_clear(tu_fifo_t *f) _ff_lock(f->mutex_rd); f->rd_idx = f->wr_idx = 0; - f->max_pointer_idx = 2*f->depth-1; + f->max_pointer_idx = (uint16_t) (2*f->depth-1); f->non_used_index_space = UINT16_MAX - f->max_pointer_idx; _ff_unlock(f->mutex_wr); diff --git a/src/device/usbd.c b/src/device/usbd.c index 1806281ff..fa894accc 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -409,6 +409,7 @@ bool tud_init (uint8_t rhport) for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { usbd_class_driver_t const * driver = get_driver(i); + TU_ASSERT(driver); TU_LOG2("%s init\r\n", driver->name); driver->init(); } @@ -426,7 +427,9 @@ static void configuration_reset(uint8_t rhport) { for ( uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++ ) { - get_driver(i)->reset(rhport); + usbd_class_driver_t const * driver = get_driver(i); + TU_ASSERT(driver, ); + driver->reset(rhport); } tu_varclr(&_usbd_dev); @@ -735,7 +738,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const // Device status bit mask // - Bit 0: Self Powered // - Bit 1: Remote Wakeup enabled - uint16_t status = (_usbd_dev.self_powered ? 1 : 0) | (_usbd_dev.remote_wakeup_en ? 2 : 0); + uint16_t status = (uint16_t) ((_usbd_dev.self_powered ? 1u : 0u) | (_usbd_dev.remote_wakeup_en ? 2u : 0u)); tud_control_xfer(rhport, p_request, &status, 2); } break; @@ -867,8 +870,8 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num) TU_ASSERT(desc_cfg != NULL && desc_cfg->bDescriptorType == TUSB_DESC_CONFIGURATION); // Parse configuration descriptor - _usbd_dev.remote_wakeup_support = (desc_cfg->bmAttributes & TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP) ? 1 : 0; - _usbd_dev.self_powered = (desc_cfg->bmAttributes & TUSB_DESC_CONFIG_ATT_SELF_POWERED ) ? 1 : 0; + _usbd_dev.remote_wakeup_support = (desc_cfg->bmAttributes & TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP) ? 1u : 0u; + _usbd_dev.self_powered = (desc_cfg->bmAttributes & TUSB_DESC_CONFIG_ATT_SELF_POWERED ) ? 1u : 0u; // Parse interface descriptor uint8_t const * p_desc = ((uint8_t const*) desc_cfg) + sizeof(tusb_desc_configuration_t); @@ -895,11 +898,12 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num) tusb_desc_interface_t const * desc_itf = (tusb_desc_interface_t const*) p_desc; // Find driver for this interface - uint16_t const remaining_len = desc_end-p_desc; + uint16_t const remaining_len = (uint16_t) (desc_end-p_desc); uint8_t drv_id; for (drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) { usbd_class_driver_t const *driver = get_driver(drv_id); + TU_ASSERT(driver); uint16_t const drv_len = driver->open(rhport, desc_itf, remaining_len); if ( (sizeof(tusb_desc_interface_t) <= drv_len) && (drv_len <= remaining_len) ) @@ -1101,7 +1105,7 @@ TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const * event, bool in_isr) for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { usbd_class_driver_t const * driver = get_driver(i); - if (driver->sof) + if (driver && driver->sof) { driver->sof(event->rhport, event->sof.frame_count); } diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index 4f4108090..94a952df7 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -189,7 +189,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result TU_LOG_MEM(2, _usbd_ctrl_buf, xferred_bytes, 2); } - _ctrl_xfer.total_xferred += xferred_bytes; + _ctrl_xfer.total_xferred += (uint16_t) xferred_bytes; _ctrl_xfer.buffer += xferred_bytes; // Data Stage is complete when all request's length are transferred or diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index b500ddc46..1d849541e 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -103,7 +103,8 @@ static const dwc2_controller_t _dwc2_controller[] = // //--------------------------------------------------------------------+ -extern uint32_t SystemCoreClock; +// SystemCoreClock is alrady included by family header +// extern uint32_t SystemCoreClock; TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_enable(uint8_t rhport) From 835ab01cab9ebe20eac46da1853eb158e1248f01 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 24 Jun 2022 21:52:51 +0700 Subject: [PATCH 388/504] fix stm32 g4 and wb build issue with freertos, also add them to ci build --- .github/workflows/build_arm.yml | 2 ++ hw/bsp/board_mcu.h | 8 +++++++- hw/bsp/stm32g4/family.c | 4 +++- hw/bsp/stm32wb/family.c | 3 ++- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml index 5a796a49b..6e4702735 100644 --- a/.github/workflows/build_arm.yml +++ b/.github/workflows/build_arm.yml @@ -57,8 +57,10 @@ jobs: - 'stm32f1' - 'stm32f4' - 'stm32f7' + - 'stm32g4' - 'stm32h7' - 'stm32l4' + - 'stm32wb' - 'tm4c123' - 'xmc4000' steps: diff --git a/hw/bsp/board_mcu.h b/hw/bsp/board_mcu.h index b911e1e53..8202479cb 100644 --- a/hw/bsp/board_mcu.h +++ b/hw/bsp/board_mcu.h @@ -31,7 +31,7 @@ #include "tusb_option.h" //--------------------------------------------------------------------+ -// Low Level MCU header include. TinyUSB stack and example should be +// Low Level MCU header include. Example should be // platform independent and mostly doesn't need to include this file. // However there are still certain situation where this file is needed: // - FreeRTOSConfig.h to set up correct clock and NVIC interrupts for ARM Cortex @@ -80,6 +80,9 @@ #elif CFG_TUSB_MCU == OPT_MCU_STM32F7 #include "stm32f7xx.h" +#elif CFG_TUSB_MCU == OPT_MCU_STM32G4 + #include "stm32g4xx.h" + #elif CFG_TUSB_MCU == OPT_MCU_STM32H7 #include "stm32h7xx.h" @@ -92,6 +95,9 @@ #elif CFG_TUSB_MCU == OPT_MCU_STM32L4 #include "stm32l4xx.h" +#elif CFG_TUSB_MCU == OPT_MCU_STM32WB + #include "stm32wbxx.h" + #elif CFG_TUSB_MCU == OPT_MCU_CXD56 // no header needed diff --git a/hw/bsp/stm32g4/family.c b/hw/bsp/stm32g4/family.c index 461dc61a1..a2312b0d8 100644 --- a/hw/bsp/stm32g4/family.c +++ b/hw/bsp/stm32g4/family.c @@ -73,7 +73,9 @@ void board_init(void) SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) - NVIC_SetPriority(OTG_FS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + NVIC_SetPriority(USB_HP_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); + NVIC_SetPriority(USB_LP_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); + NVIC_SetPriority(USBWakeUp_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif GPIO_InitTypeDef GPIO_InitStruct; diff --git a/hw/bsp/stm32wb/family.c b/hw/bsp/stm32wb/family.c index 1ed38308b..9f1f46f4d 100644 --- a/hw/bsp/stm32wb/family.c +++ b/hw/bsp/stm32wb/family.c @@ -67,7 +67,8 @@ void board_init(void) SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) - NVIC_SetPriority(OTG_FS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + NVIC_SetPriority(USB_HP_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); + NVIC_SetPriority(USB_LP_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif GPIO_InitTypeDef GPIO_InitStruct; From 1d6918ce419b7df13def76759ba804c46ea8024c Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 24 Jun 2022 21:53:46 +0700 Subject: [PATCH 389/504] suppress redundant-decls warnings for freertos examples --- examples/device/cdc_msc_freertos/Makefile | 2 +- .../device/cdc_msc_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h | 1 + examples/device/hid_composite_freertos/Makefile | 2 +- hw/bsp/samd11/family.mk | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/device/cdc_msc_freertos/Makefile b/examples/device/cdc_msc_freertos/Makefile index a155d6cb7..3352dd37d 100644 --- a/examples/device/cdc_msc_freertos/Makefile +++ b/examples/device/cdc_msc_freertos/Makefile @@ -30,7 +30,7 @@ SRC_C += \ $(subst ../../../,,$(wildcard ../../../$(FREERTOS_SRC)/portable/GCC/$(FREERTOS_PORT)/*.c)) # Suppress FreeRTOS warnings -CFLAGS += -Wno-error=cast-qual +CFLAGS += -Wno-error=cast-qual -Wno-error=redundant-decls # FreeRTOS (lto + Os) linker issue LDFLAGS += -Wl,--undefined=vTaskSwitchContext diff --git a/examples/device/cdc_msc_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h b/examples/device/cdc_msc_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h index ccb620720..6a3630dbc 100644 --- a/examples/device/cdc_msc_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h +++ b/examples/device/cdc_msc_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h @@ -53,6 +53,7 @@ #if CFG_TUSB_MCU == OPT_MCU_MM32F327X extern u32 SystemCoreClock; #else + // FIXME cause redundant-decls warnings extern uint32_t SystemCoreClock; #endif diff --git a/examples/device/hid_composite_freertos/Makefile b/examples/device/hid_composite_freertos/Makefile index c9b7abdf5..6c8c43ddd 100644 --- a/examples/device/hid_composite_freertos/Makefile +++ b/examples/device/hid_composite_freertos/Makefile @@ -29,7 +29,7 @@ SRC_C += \ $(subst ../../../,,$(wildcard ../../../$(FREERTOS_SRC)/portable/GCC/$(FREERTOS_PORT)/*.c)) # Suppress FreeRTOS warnings -CFLAGS += -Wno-error=cast-qual +CFLAGS += -Wno-error=cast-qual -Wno-error=redundant-decls # FreeRTOS (lto + Os) linker issue LDFLAGS += -Wl,--undefined=vTaskSwitchContext diff --git a/hw/bsp/samd11/family.mk b/hw/bsp/samd11/family.mk index ae55be75b..85cc136a6 100644 --- a/hw/bsp/samd11/family.mk +++ b/hw/bsp/samd11/family.mk @@ -12,7 +12,7 @@ CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_SAMD11 # suppress warning caused by vendor mcu driver -CFLAGS += -Wno-error=cast-qual +CFLAGS += -Wno-error=cast-qual -Wno-error=redundant-decls SRC_C += \ src/portable/microchip/samd/dcd_samd.c \ From 0042eccb3b2ff0f980f3a927a271364a2089ada5 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 24 Jun 2022 22:22:52 +0700 Subject: [PATCH 390/504] fix redundant-decls warnings by usbd/usbh --- examples/make.mk | 6 +++--- hw/bsp/nrf/family.mk | 3 --- src/class/msc/msc_device.c | 2 +- src/device/dcd.h | 7 ------- src/device/usbd.c | 2 +- src/device/usbd.h | 5 ++++- src/device/usbd_control.c | 2 +- src/host/hub.c | 1 + src/host/usbh.c | 3 +-- src/host/usbh.h | 6 ++++-- 10 files changed, 16 insertions(+), 21 deletions(-) diff --git a/examples/make.mk b/examples/make.mk index 26065c027..fa909ddca 100644 --- a/examples/make.mk +++ b/examples/make.mk @@ -90,13 +90,13 @@ CFLAGS += \ -ffunction-sections \ -fsingle-precision-constant \ -fno-strict-aliasing \ - -Wdouble-promotion \ - -Wstrict-prototypes \ - -Wstrict-overflow \ -Wall \ -Wextra \ -Werror \ -Wfatal-errors \ + -Wdouble-promotion \ + -Wstrict-prototypes \ + -Wstrict-overflow \ -Werror-implicit-function-declaration \ -Wfloat-equal \ -Wundef \ diff --git a/hw/bsp/nrf/family.mk b/hw/bsp/nrf/family.mk index 609e2da0b..d8283a9e6 100644 --- a/hw/bsp/nrf/family.mk +++ b/hw/bsp/nrf/family.mk @@ -16,9 +16,6 @@ CFLAGS += \ # suppress warning caused by vendor mcu driver CFLAGS += -Wno-error=undef -Wno-error=unused-parameter -Wno-error=cast-align -Wno-error=cast-qual -# warning caused by dcd_nrf5x.c due to include of usbd.h and re-declare of dcd_int_handler() -CFLAGS += -Wno-error=redundant-decls - # All source paths should be relative to the top level. LD_FILE ?= hw/bsp/nrf/boards/$(BOARD)/nrf52840_s140_v6.ld diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 33dd4ac37..00b0a1d06 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -28,9 +28,9 @@ #if (CFG_TUD_ENABLED && CFG_TUD_MSC) +#include "device/dcd.h" // for faking dcd_event_xfer_complete #include "device/usbd.h" #include "device/usbd_pvt.h" -#include "device/dcd.h" // for faking dcd_event_xfer_complete #include "msc_device.h" diff --git a/src/device/dcd.h b/src/device/dcd.h index 6b99734fe..c1780f656 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -110,14 +110,7 @@ typedef struct TU_ATTR_ALIGNED(4) void dcd_init (uint8_t rhport); // Interrupt Handler -#if __GNUC__ && !defined(__ARMCC_VERSION) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wredundant-decls" -#endif void dcd_int_handler(uint8_t rhport); -#if __GNUC__ && !defined(__ARMCC_VERSION) -#pragma GCC diagnostic pop -#endif // Enable device interrupt void dcd_int_enable (uint8_t rhport); diff --git a/src/device/usbd.c b/src/device/usbd.c index fa894accc..b2053174e 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -28,12 +28,12 @@ #if CFG_TUD_ENABLED +#include "device/dcd.h" #include "tusb.h" #include "common/tusb_private.h" #include "device/usbd.h" #include "device/usbd_pvt.h" -#include "device/dcd.h" //--------------------------------------------------------------------+ // USBD Configuration diff --git a/src/device/usbd.h b/src/device/usbd.h index 964cfb992..17b4d927b 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -58,8 +58,11 @@ void tud_task (void) // Check if there is pending events need processing by tud_task() bool tud_task_event_ready(void); -// Interrupt handler, name alias to DCD +#ifndef _TUSB_DCD_H_ extern void dcd_int_handler(uint8_t rhport); +#endif + +// Interrupt handler, name alias to DCD #define tud_int_handler dcd_int_handler // Get current bus speed diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index 94a952df7..0995ef669 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -28,9 +28,9 @@ #if CFG_TUD_ENABLED +#include "dcd.h" #include "tusb.h" #include "device/usbd_pvt.h" -#include "dcd.h" #if CFG_TUSB_DEBUG >= 2 extern void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback); diff --git a/src/host/hub.c b/src/host/hub.c index 5c0fd9166..3400b154a 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -28,6 +28,7 @@ #if (CFG_TUH_ENABLED && CFG_TUH_HUB) +#include "hcd.h" #include "usbh.h" #include "usbh_classdriver.h" #include "hub.h" diff --git a/src/host/usbh.c b/src/host/usbh.c index 4807d20b8..4c9b0b1ba 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -28,10 +28,9 @@ #if CFG_TUH_ENABLED +#include "host/hcd.h" #include "tusb.h" #include "common/tusb_private.h" - -#include "host/usbh.h" #include "host/usbh_classdriver.h" #include "hub.h" diff --git a/src/host/usbh.h b/src/host/usbh.h index 347c75b8c..560a1ea23 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -32,7 +32,6 @@ #endif #include "common/tusb_common.h" -#include "hcd.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF @@ -115,8 +114,11 @@ void tuh_task(void) tuh_task_ext(UINT32_MAX, false); } -// Interrupt handler, name alias to HCD +#ifndef _TUSB_HCD_H_ extern void hcd_int_handler(uint8_t rhport); +#endif + +// Interrupt handler, name alias to HCD #define tuh_int_handler hcd_int_handler bool tuh_vid_pid_get(uint8_t daddr, uint16_t* vid, uint16_t* pid); From 3d4d37375bbfb0bc88127be3aa79930e865f35b5 Mon Sep 17 00:00:00 2001 From: NConrad Date: Tue, 21 Jun 2022 23:17:50 -0400 Subject: [PATCH 391/504] USBTMC: Update test python code to use the new pyvisa namespace, and other misc fixes --- examples/device/usbtmc/visaQuery.py | 35 ++++++++++++++++------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/examples/device/usbtmc/visaQuery.py b/examples/device/usbtmc/visaQuery.py index 50a765a03..c4e5ad2b9 100644 --- a/examples/device/usbtmc/visaQuery.py +++ b/examples/device/usbtmc/visaQuery.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -import visa +import pyvisa import time import sys @@ -54,9 +54,9 @@ def test_srq(): assert (inst.read_stb() == 0) inst.write("123") - #inst.enable_event(visa.constants.VI_EVENT_SERVICE_REQ, visa.constants.VI_QUEUE) - #waitrsp = inst.wait_on_event(visa.constants.VI_EVENT_SERVICE_REQ, 5000) - #inst.discard_events(visa.constants.VI_EVENT_SERVICE_REQ, visa.constants.VI_QUEUE) + #inst.enable_event(pyvisa.constants.VI_EVENT_SERVICE_REQ, pyvisa.constants.VI_QUEUE) + #waitrsp = inst.wait_on_event(pyvisa.constants.VI_EVENT_SERVICE_REQ, 5000) + #inst.discard_events(pyvisa.constants.VI_EVENT_SERVICE_REQ, pyvisa.constants.VI_QUEUE) #inst.wait_for_srq() time.sleep(0.3) stb = inst.read_stb() @@ -77,8 +77,8 @@ def test_read_timeout(): t0 = time.monotonic() try: rsp = inst.read() - assert(false), "Read should have resulted in timeout" - except visa.VisaIOError: + assert(False), "Read should have resulted in timeout" + except pyvisa.VisaIOError: print(" Got expected exception") t = time.monotonic() - t0 assert ((t*1000.0) > (inst.timeout - 300)) @@ -99,23 +99,27 @@ def test_abort_in(): t0 = time.monotonic() try: rsp = inst.read() - assert(false), "Read should have resulted in timeout" - except visa.VisaIOError: + assert(False), "Read should have resulted in timeout" + except pyvisa.VisaIOError: print(" Got expected exception") t = time.monotonic() - t0 assert ((t*1000.0) > (inst.timeout - 300)) assert ((t*1000.0) < (inst.timeout + 300)) print(f" Delay was {t:0.3}") - # Response is still in queue, so send a clear (to be more helpful to the next test) + # Response is still in queue, so read it out (to be more helpful to the next test) inst.timeout = 800 y = inst.read() assert(y == "xxx\r\n") def test_indicate(): # perform indicator pulse - usb_iface = inst.get_visa_attribute(visa.constants.VI_ATTR_USB_INTFC_NUM) + usb_iface = inst.get_visa_attribute(pyvisa.constants.VI_ATTR_USB_INTFC_NUM) retv = inst.control_in(request_type_bitmap_field=0xA1, request_id=64, request_value=0x0000, index=usb_iface, length=0x0001) - assert((retv[1] == visa.constants.StatusCode(0)) and (retv[0] == b'\x01')), f"indicator pulse failed: retv={retv}" + # pyvisa used to return (statuscode,bytes), but now only returns bytes, so we need to handle both cases + if(isinstance(retv,bytes)): + assert(retv == b'\x01') + else: + assert((retv[1] == pyvisa.constants.StatusCode(0)) and (retv[0] == b'\x01')), f"indicator pulse failed: retv={retv}" def test_multi_read(): @@ -131,19 +135,19 @@ def test_multi_read(): #inst.chunk_size = old_chunk_size def test_stall_ep0(): - usb_iface = inst.get_visa_attribute(visa.constants.VI_ATTR_USB_INTFC_NUM) + usb_iface = inst.get_visa_attribute(pyvisa.constants.VI_ATTR_USB_INTFC_NUM) inst.read_stb() # This is an invalid request, should create stall. try: retv = inst.control_in(request_type_bitmap_field=0xA1, request_id=60, request_value=0x0000, index=usb_iface, length=0x0001) - assert false - except visa.VisaIOError: + assert(False) + except pyvisa.VisaIOError: pass assert (inst.read_stb() == 0) -rm = visa.ResourceManager() +rm = pyvisa.ResourceManager() reslist = rm.list_resources("USB?::?*::INSTR") print(reslist) @@ -167,7 +171,6 @@ inst.timeout = 2000 print("+ multi read") test_multi_read() - print("+ echo delay=0") inst.write("delay 0") test_echo(1,175) From 239b5d52790051949c281e60ba96ac674669f026 Mon Sep 17 00:00:00 2001 From: NConrad Date: Fri, 24 Jun 2022 23:06:32 -0400 Subject: [PATCH 392/504] USBTMC: Manually stall and unstall EP when clear(ENDPOINT_HALT) is received. --- src/class/usbtmc/usbtmc_device.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 9608e4835..b5232ab91 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -597,18 +597,31 @@ bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request { uint32_t ep_addr = (request->wIndex); + // At this point, a transfer MAY be in progress. Based on USB spec, when clearing bulk EP HALT, + // the EP transfer buffer needs to be cleared and DTOG needs to be reset, even if + // the EP is not halted. The only USBD API interface to do this is to stall and then unstall the EP. if(ep_addr == usbtmc_state.ep_bulk_out) { criticalEnter(); + usbd_edpt_stall(rhport, ep_addr); + usbd_edpt_clear_stall(rhport, ep_addr); usbtmc_state.state = STATE_NAK; // USBD core has placed EP in NAK state for us criticalLeave(); tud_usbtmc_bulkOut_clearFeature_cb(); } else if (ep_addr == usbtmc_state.ep_bulk_in) { + usbd_edpt_stall(rhport, ep_addr); + usbd_edpt_clear_stall(rhport, ep_addr); tud_usbtmc_bulkIn_clearFeature_cb(); } - else + else if ((usbtmc_state.ep_int_in != 0) && (ep_addr == usbtmc_state.ep_int_in)) + { + // Clearing interrupt in EP + usbd_edpt_stall(rhport, ep_addr); + usbd_edpt_clear_stall(rhport, ep_addr); + } + else { return false; } @@ -836,6 +849,7 @@ bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request }, .StatusByte = tud_usbtmc_get_stb_cb(&(rsp.USBTMC_status)) }; + // USB488 spec states that transfer must be queued before control request response sent. usbd_edpt_xfer(rhport, usbtmc_state.ep_int_in, (void*)&intMsg, sizeof(intMsg)); } else From c675debfb2dcff1697cb6643afb60c26309bdfcf Mon Sep 17 00:00:00 2001 From: NConrad Date: Sun, 26 Jun 2022 14:34:34 -0400 Subject: [PATCH 393/504] USBTMC: Handle busy interrupt in. --- src/class/usbtmc/usbtmc.h | 5 ++++- src/class/usbtmc/usbtmc_device.c | 32 +++++++++++++++++++------------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/class/usbtmc/usbtmc.h b/src/class/usbtmc/usbtmc.h index 7d7005c2e..e7016ae24 100644 --- a/src/class/usbtmc/usbtmc.h +++ b/src/class/usbtmc/usbtmc.h @@ -189,7 +189,10 @@ typedef enum { USBTMC_STATUS_FAILED = 0x80, USBTMC_STATUS_TRANSFER_NOT_IN_PROGRESS = 0x81, USBTMC_STATUS_SPLIT_NOT_IN_PROGRESS = 0x82, - USBTMC_STATUS_SPLIT_IN_PROGRESS = 0x83 + USBTMC_STATUS_SPLIT_IN_PROGRESS = 0x83, + + /****** USBTMC 488 *************/ + USB488_STATUS_INTERRUPT_IN_BUSY = 0x20 } usbtmc_status_enum; /************************************************************ diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index b5232ab91..c50ca65d5 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -831,26 +831,32 @@ bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request bTag = request->wValue & 0x7F; TU_VERIFY(request->bmRequestType == 0xA1); - TU_VERIFY((request->wValue & (~0x7F)) == 0u); // Other bits are required to be zero + TU_VERIFY((request->wValue & (~0x7F)) == 0u); // Other bits are required to be zero (USB488v1.0 Table 11) TU_VERIFY(bTag >= 0x02 && bTag <= 127); TU_VERIFY(request->wIndex == usbtmc_state.itf_id); TU_VERIFY(request->wLength == 0x0003); rsp.bTag = (uint8_t)bTag; if(usbtmc_state.ep_int_in != 0) { - rsp.USBTMC_status = USBTMC_STATUS_SUCCESS; - rsp.statusByte = 0x00; // Use interrupt endpoint, instead. - - usbtmc_read_stb_interrupt_488_t intMsg = + rsp.statusByte = 0x00; // Use interrupt endpoint, instead. Must be 0x00 (USB488v1.0 4.3.1.2) + if(usbd_edpt_busy(rhport, usbtmc_state.ep_int_in)) { - .bNotify1 = { - .one = 1, - .bTag = bTag & 0x7Fu, - }, - .StatusByte = tud_usbtmc_get_stb_cb(&(rsp.USBTMC_status)) - }; - // USB488 spec states that transfer must be queued before control request response sent. - usbd_edpt_xfer(rhport, usbtmc_state.ep_int_in, (void*)&intMsg, sizeof(intMsg)); + rsp.USBTMC_status = USB488_STATUS_INTERRUPT_IN_BUSY; + } + else + { + rsp.USBTMC_status = USBTMC_STATUS_SUCCESS; + usbtmc_read_stb_interrupt_488_t intMsg = + { + .bNotify1 = { + .one = 1, + .bTag = bTag & 0x7Fu, + }, + .StatusByte = tud_usbtmc_get_stb_cb(&(rsp.USBTMC_status)) + }; + // Must be queued before control request response sent (USB488v1.0 4.3.1.2) + usbd_edpt_xfer(rhport, usbtmc_state.ep_int_in, (void*)&intMsg, sizeof(intMsg)); + } } else { From b9dc9dbd78ee1890342429502d585f323c480fc2 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 27 Jun 2022 11:50:17 +0700 Subject: [PATCH 394/504] fix most warnings with rp2040 -wconversion --- .../device/audio_4_channel_mic/CMakeLists.txt | 3 +++ .../device/audio_4_channel_mic/src/main.c | 2 +- .../audio_4_channel_mic/src/usb_descriptors.c | 4 +-- examples/device/audio_test/CMakeLists.txt | 3 +++ examples/device/audio_test/src/main.c | 2 +- .../device/audio_test/src/usb_descriptors.c | 4 +-- examples/device/board_test/CMakeLists.txt | 3 +++ examples/device/cdc_dual_ports/CMakeLists.txt | 3 +++ .../cdc_dual_ports/src/usb_descriptors.c | 4 +-- examples/device/cdc_msc/CMakeLists.txt | 3 +++ .../cdc_msc_freertos/src/usb_descriptors.c | 4 +-- examples/device/dfu/CMakeLists.txt | 5 +++- examples/device/dfu/src/usb_descriptors.c | 2 +- examples/device/dfu_runtime/CMakeLists.txt | 3 +++ .../device/dfu_runtime/src/usb_descriptors.c | 4 +-- .../dynamic_configuration/CMakeLists.txt | 3 +++ .../device/dynamic_configuration/src/main.c | 2 +- .../dynamic_configuration/src/msc_disk.c | 6 ++--- .../src/usb_descriptors.c | 4 +-- .../device/hid_boot_interface/CMakeLists.txt | 3 +++ .../hid_boot_interface/src/usb_descriptors.c | 4 +-- examples/device/hid_composite/CMakeLists.txt | 3 +++ .../hid_composite/src/usb_descriptors.c | 4 +-- .../src/usb_descriptors.c | 4 +-- .../device/hid_generic_inout/CMakeLists.txt | 3 +++ .../hid_generic_inout/src/usb_descriptors.c | 4 +-- .../hid_multiple_interface/CMakeLists.txt | 3 +++ .../src/usb_descriptors.c | 4 +-- examples/device/midi_test/CMakeLists.txt | 3 +++ .../device/midi_test/src/usb_descriptors.c | 4 +-- examples/device/msc_dual_lun/CMakeLists.txt | 3 +++ .../device/msc_dual_lun/src/usb_descriptors.c | 4 +-- .../device/net_lwip_webserver/CMakeLists.txt | 3 +++ .../net_lwip_webserver/src/usb_descriptors.c | 4 +-- examples/device/uac2_headset/CMakeLists.txt | 3 +++ .../device/uac2_headset/src/usb_descriptors.c | 2 +- examples/device/usbtmc/CMakeLists.txt | 3 +++ examples/device/usbtmc/src/usb_descriptors.c | 2 +- examples/device/video_capture/CMakeLists.txt | 3 +++ .../video_capture/src/usb_descriptors.c | 4 +-- examples/device/webusb_serial/CMakeLists.txt | 3 +++ .../webusb_serial/src/usb_descriptors.c | 4 +-- .../src/usb_descriptors.c | 2 +- examples/example.cmake | 25 +++++++++++++++++++ hw/bsp/rp2040/family.c | 6 ++++- src/class/audio/audio_device.c | 2 +- src/class/hid/hid_device.c | 5 ++-- src/class/midi/midi_device.c | 12 ++++----- 48 files changed, 140 insertions(+), 53 deletions(-) create mode 100644 examples/example.cmake diff --git a/examples/device/audio_4_channel_mic/CMakeLists.txt b/examples/device/audio_4_channel_mic/CMakeLists.txt index f6e10e2ea..e6ce2813e 100644 --- a/examples/device/audio_4_channel_mic/CMakeLists.txt +++ b/examples/device/audio_4_channel_mic/CMakeLists.txt @@ -23,6 +23,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) diff --git a/examples/device/audio_4_channel_mic/src/main.c b/examples/device/audio_4_channel_mic/src/main.c index 9c94edd49..a6af5fd19 100644 --- a/examples/device/audio_4_channel_mic/src/main.c +++ b/examples/device/audio_4_channel_mic/src/main.c @@ -221,7 +221,7 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const * // Request uses format layout 2 TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_2_t)); - volume[channelNum] = ((audio_control_cur_2_t*) pBuff)->bCur; + volume[channelNum] = (uint16_t) ((audio_control_cur_2_t*) pBuff)->bCur; TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum); return true; diff --git a/examples/device/audio_4_channel_mic/src/usb_descriptors.c b/examples/device/audio_4_channel_mic/src/usb_descriptors.c index 93ae2ea47..8929f3057 100644 --- a/examples/device/audio_4_channel_mic/src/usb_descriptors.c +++ b/examples/device/audio_4_channel_mic/src/usb_descriptors.c @@ -149,7 +149,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) chr_count = 31; for(uint8_t i=0; iwLength == sizeof(audio_control_cur_2_t)); - volume[channelNum] = ((audio_control_cur_2_t*) pBuff)->bCur; + volume[channelNum] = (uint16_t) ((audio_control_cur_2_t*) pBuff)->bCur; TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum); return true; diff --git a/examples/device/audio_test/src/usb_descriptors.c b/examples/device/audio_test/src/usb_descriptors.c index 09b2a2d45..da3e203d7 100644 --- a/examples/device/audio_test/src/usb_descriptors.c +++ b/examples/device/audio_test/src/usb_descriptors.c @@ -149,7 +149,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) chr_count = 31; for(uint8_t i=0; i 31 ) chr_count = 31; // Convert ASCII string into UTF-16 @@ -247,7 +247,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/device/cdc_msc/CMakeLists.txt b/examples/device/cdc_msc/CMakeLists.txt index fa6e83b7e..04c7c1b26 100644 --- a/examples/device/cdc_msc/CMakeLists.txt +++ b/examples/device/cdc_msc/CMakeLists.txt @@ -24,6 +24,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/cdc_msc_freertos/src/usb_descriptors.c b/examples/device/cdc_msc_freertos/src/usb_descriptors.c index 9585822a3..30a712275 100644 --- a/examples/device/cdc_msc_freertos/src/usb_descriptors.c +++ b/examples/device/cdc_msc_freertos/src/usb_descriptors.c @@ -247,7 +247,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) chr_count = 31; // Convert ASCII string into UTF-16 @@ -258,7 +258,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/device/dfu/CMakeLists.txt b/examples/device/dfu/CMakeLists.txt index abc4d91da..121ab3852 100644 --- a/examples/device/dfu/CMakeLists.txt +++ b/examples/device/dfu/CMakeLists.txt @@ -23,6 +23,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. -family_configure_device_example(${PROJECT}) \ No newline at end of file +family_configure_device_example(${PROJECT}) diff --git a/examples/device/dfu/src/usb_descriptors.c b/examples/device/dfu/src/usb_descriptors.c index 350334aa5..51a0d09f5 100644 --- a/examples/device/dfu/src/usb_descriptors.c +++ b/examples/device/dfu/src/usb_descriptors.c @@ -152,7 +152,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) { chr_count = 31; } diff --git a/examples/device/dfu_runtime/CMakeLists.txt b/examples/device/dfu_runtime/CMakeLists.txt index abc4d91da..438635958 100644 --- a/examples/device/dfu_runtime/CMakeLists.txt +++ b/examples/device/dfu_runtime/CMakeLists.txt @@ -23,6 +23,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/dfu_runtime/src/usb_descriptors.c b/examples/device/dfu_runtime/src/usb_descriptors.c index 060943289..1b0a60551 100644 --- a/examples/device/dfu_runtime/src/usb_descriptors.c +++ b/examples/device/dfu_runtime/src/usb_descriptors.c @@ -147,7 +147,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) { chr_count = 31; } @@ -160,7 +160,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (uint16_t)((((uint16_t)TUSB_DESC_STRING) << 8 ) | (2u*chr_count + 2u)); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/device/dynamic_configuration/CMakeLists.txt b/examples/device/dynamic_configuration/CMakeLists.txt index fa6e83b7e..04c7c1b26 100644 --- a/examples/device/dynamic_configuration/CMakeLists.txt +++ b/examples/device/dynamic_configuration/CMakeLists.txt @@ -24,6 +24,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/dynamic_configuration/src/main.c b/examples/device/dynamic_configuration/src/main.c index 95f8b8286..33a603343 100644 --- a/examples/device/dynamic_configuration/src/main.c +++ b/examples/device/dynamic_configuration/src/main.c @@ -181,7 +181,7 @@ void midi_task(void) start_ms += 286; // Previous positions in the note sequence. - int previous = note_pos - 1; + int previous = (int) (note_pos - 1); // If we currently are at position 0, set the // previous position to the last note in the sequence. diff --git a/examples/device/dynamic_configuration/src/msc_disk.c b/examples/device/dynamic_configuration/src/msc_disk.c index a895f4738..e8cb03fdd 100644 --- a/examples/device/dynamic_configuration/src/msc_disk.c +++ b/examples/device/dynamic_configuration/src/msc_disk.c @@ -184,7 +184,7 @@ int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buff uint8_t const* addr = msc_disk[lba] + offset; memcpy(buffer, addr, bufsize); - return bufsize; + return (int32_t) bufsize; } // Callback invoked when received WRITE10 command. @@ -203,7 +203,7 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* (void) lba; (void) offset; (void) buffer; #endif - return bufsize; + return (int32_t) bufsize; } // Callback invoked when received an SCSI command not in built-in list below @@ -237,7 +237,7 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, { if(in_xfer) { - memcpy(buffer, response, resplen); + memcpy(buffer, response, (size_t) resplen); }else { // SCSI output diff --git a/examples/device/dynamic_configuration/src/usb_descriptors.c b/examples/device/dynamic_configuration/src/usb_descriptors.c index b88f20163..457f774d0 100644 --- a/examples/device/dynamic_configuration/src/usb_descriptors.c +++ b/examples/device/dynamic_configuration/src/usb_descriptors.c @@ -226,7 +226,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) chr_count = 31; // Convert ASCII string into UTF-16 @@ -237,7 +237,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/device/hid_boot_interface/CMakeLists.txt b/examples/device/hid_boot_interface/CMakeLists.txt index abc4d91da..438635958 100644 --- a/examples/device/hid_boot_interface/CMakeLists.txt +++ b/examples/device/hid_boot_interface/CMakeLists.txt @@ -23,6 +23,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/hid_boot_interface/src/usb_descriptors.c b/examples/device/hid_boot_interface/src/usb_descriptors.c index 3fa48d98d..a0d7e9f15 100644 --- a/examples/device/hid_boot_interface/src/usb_descriptors.c +++ b/examples/device/hid_boot_interface/src/usb_descriptors.c @@ -163,7 +163,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) chr_count = 31; // Convert ASCII string into UTF-16 @@ -174,7 +174,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/device/hid_composite/CMakeLists.txt b/examples/device/hid_composite/CMakeLists.txt index abc4d91da..438635958 100644 --- a/examples/device/hid_composite/CMakeLists.txt +++ b/examples/device/hid_composite/CMakeLists.txt @@ -23,6 +23,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/hid_composite/src/usb_descriptors.c b/examples/device/hid_composite/src/usb_descriptors.c index e760b20ba..2988baee2 100644 --- a/examples/device/hid_composite/src/usb_descriptors.c +++ b/examples/device/hid_composite/src/usb_descriptors.c @@ -210,7 +210,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) chr_count = 31; // Convert ASCII string into UTF-16 @@ -221,7 +221,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/device/hid_composite_freertos/src/usb_descriptors.c b/examples/device/hid_composite_freertos/src/usb_descriptors.c index 791813fdf..4df12d3db 100644 --- a/examples/device/hid_composite_freertos/src/usb_descriptors.c +++ b/examples/device/hid_composite_freertos/src/usb_descriptors.c @@ -208,7 +208,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) chr_count = 31; // Convert ASCII string into UTF-16 @@ -219,7 +219,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/device/hid_generic_inout/CMakeLists.txt b/examples/device/hid_generic_inout/CMakeLists.txt index abc4d91da..438635958 100644 --- a/examples/device/hid_generic_inout/CMakeLists.txt +++ b/examples/device/hid_generic_inout/CMakeLists.txt @@ -23,6 +23,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/hid_generic_inout/src/usb_descriptors.c b/examples/device/hid_generic_inout/src/usb_descriptors.c index 5dabf42a3..c2b4792c8 100644 --- a/examples/device/hid_generic_inout/src/usb_descriptors.c +++ b/examples/device/hid_generic_inout/src/usb_descriptors.c @@ -153,7 +153,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) chr_count = 31; // Convert ASCII string into UTF-16 @@ -164,7 +164,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/device/hid_multiple_interface/CMakeLists.txt b/examples/device/hid_multiple_interface/CMakeLists.txt index abc4d91da..438635958 100644 --- a/examples/device/hid_multiple_interface/CMakeLists.txt +++ b/examples/device/hid_multiple_interface/CMakeLists.txt @@ -23,6 +23,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/hid_multiple_interface/src/usb_descriptors.c b/examples/device/hid_multiple_interface/src/usb_descriptors.c index 9eef21504..42471a961 100644 --- a/examples/device/hid_multiple_interface/src/usb_descriptors.c +++ b/examples/device/hid_multiple_interface/src/usb_descriptors.c @@ -171,7 +171,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) chr_count = 31; // Convert ASCII string into UTF-16 @@ -182,7 +182,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/device/midi_test/CMakeLists.txt b/examples/device/midi_test/CMakeLists.txt index abc4d91da..438635958 100644 --- a/examples/device/midi_test/CMakeLists.txt +++ b/examples/device/midi_test/CMakeLists.txt @@ -23,6 +23,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/midi_test/src/usb_descriptors.c b/examples/device/midi_test/src/usb_descriptors.c index 8444237c6..c84a873b1 100644 --- a/examples/device/midi_test/src/usb_descriptors.c +++ b/examples/device/midi_test/src/usb_descriptors.c @@ -166,7 +166,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) chr_count = 31; // Convert ASCII string into UTF-16 @@ -177,7 +177,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/device/msc_dual_lun/CMakeLists.txt b/examples/device/msc_dual_lun/CMakeLists.txt index 9e834ae21..518eac3ad 100644 --- a/examples/device/msc_dual_lun/CMakeLists.txt +++ b/examples/device/msc_dual_lun/CMakeLists.txt @@ -24,6 +24,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/msc_dual_lun/src/usb_descriptors.c b/examples/device/msc_dual_lun/src/usb_descriptors.c index 2afd391af..68a671c91 100644 --- a/examples/device/msc_dual_lun/src/usb_descriptors.c +++ b/examples/device/msc_dual_lun/src/usb_descriptors.c @@ -168,7 +168,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) chr_count = 31; // Convert ASCII string into UTF-16 @@ -179,7 +179,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/device/net_lwip_webserver/CMakeLists.txt b/examples/device/net_lwip_webserver/CMakeLists.txt index 8e3f0f5a8..5bb091a4f 100644 --- a/examples/device/net_lwip_webserver/CMakeLists.txt +++ b/examples/device/net_lwip_webserver/CMakeLists.txt @@ -69,6 +69,9 @@ if (EXISTS ${TOP}/lib/lwip/src) ${TOP}/lib/networking/rndis_reports.c ) + # Example common such as compiler warnings + include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) diff --git a/examples/device/net_lwip_webserver/src/usb_descriptors.c b/examples/device/net_lwip_webserver/src/usb_descriptors.c index 2b4b2a0c3..bee51790a 100644 --- a/examples/device/net_lwip_webserver/src/usb_descriptors.c +++ b/examples/device/net_lwip_webserver/src/usb_descriptors.c @@ -231,7 +231,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > (TU_ARRAY_SIZE(_desc_str) - 1)) chr_count = TU_ARRAY_SIZE(_desc_str) - 1; // Convert ASCII string into UTF-16 @@ -242,7 +242,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/device/uac2_headset/CMakeLists.txt b/examples/device/uac2_headset/CMakeLists.txt index abc4d91da..438635958 100644 --- a/examples/device/uac2_headset/CMakeLists.txt +++ b/examples/device/uac2_headset/CMakeLists.txt @@ -23,6 +23,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/uac2_headset/src/usb_descriptors.c b/examples/device/uac2_headset/src/usb_descriptors.c index 9e97845b8..a2d6368bf 100644 --- a/examples/device/uac2_headset/src/usb_descriptors.c +++ b/examples/device/uac2_headset/src/usb_descriptors.c @@ -155,7 +155,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if (chr_count > 31) chr_count = 31; for (uint8_t i = 0; i < chr_count; i++) diff --git a/examples/device/usbtmc/CMakeLists.txt b/examples/device/usbtmc/CMakeLists.txt index c49603c26..74f81b24f 100644 --- a/examples/device/usbtmc/CMakeLists.txt +++ b/examples/device/usbtmc/CMakeLists.txt @@ -24,6 +24,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/usbtmc/src/usb_descriptors.c b/examples/device/usbtmc/src/usb_descriptors.c index 423482634..770a97436 100644 --- a/examples/device/usbtmc/src/usb_descriptors.c +++ b/examples/device/usbtmc/src/usb_descriptors.c @@ -175,7 +175,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) { chr_count = 31; } diff --git a/examples/device/video_capture/CMakeLists.txt b/examples/device/video_capture/CMakeLists.txt index cb321f9a8..416b91665 100644 --- a/examples/device/video_capture/CMakeLists.txt +++ b/examples/device/video_capture/CMakeLists.txt @@ -23,6 +23,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/video_capture/src/usb_descriptors.c b/examples/device/video_capture/src/usb_descriptors.c index da8ec8e89..5c97f4fe1 100644 --- a/examples/device/video_capture/src/usb_descriptors.c +++ b/examples/device/video_capture/src/usb_descriptors.c @@ -149,7 +149,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) chr_count = 31; // Convert ASCII string into UTF-16 @@ -160,7 +160,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/device/webusb_serial/CMakeLists.txt b/examples/device/webusb_serial/CMakeLists.txt index abc4d91da..438635958 100644 --- a/examples/device/webusb_serial/CMakeLists.txt +++ b/examples/device/webusb_serial/CMakeLists.txt @@ -23,6 +23,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/webusb_serial/src/usb_descriptors.c b/examples/device/webusb_serial/src/usb_descriptors.c index 93e802a90..cafe2c22b 100644 --- a/examples/device/webusb_serial/src/usb_descriptors.c +++ b/examples/device/webusb_serial/src/usb_descriptors.c @@ -235,7 +235,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) const char* str = string_desc_arr[index]; // Cap at max char - chr_count = strlen(str); + chr_count = (uint8_t) strlen(str); if ( chr_count > 31 ) chr_count = 31; // Convert ASCII string into UTF-16 @@ -246,7 +246,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/dual/host_hid_to_device_cdc/src/usb_descriptors.c b/examples/dual/host_hid_to_device_cdc/src/usb_descriptors.c index e55899f65..6b0a89127 100644 --- a/examples/dual/host_hid_to_device_cdc/src/usb_descriptors.c +++ b/examples/dual/host_hid_to_device_cdc/src/usb_descriptors.c @@ -259,7 +259,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/examples/example.cmake b/examples/example.cmake new file mode 100644 index 000000000..6bb82a56d --- /dev/null +++ b/examples/example.cmake @@ -0,0 +1,25 @@ +target_compile_options(${PROJECT} PUBLIC + -Wall + -Wextra + -Werror + -Wfatal-errors + -Wdouble-promotion + #-Wstrict-prototypes + -Wstrict-overflow + #-Werror-implicit-function-declaration + -Wfloat-equal + #-Wundef + -Wshadow + -Wwrite-strings + -Wsign-compare + -Wmissing-format-attribute + -Wunreachable-code + -Wcast-align + -Wcast-function-type + -Wcast-qual + -Wnull-dereference + -Wuninitialized + -Wunused + -Wredundant-decls + -Wconversion + ) diff --git a/hw/bsp/rp2040/family.c b/hw/bsp/rp2040/family.c index 68c9e2d52..90e2192c0 100644 --- a/hw/bsp/rp2040/family.c +++ b/hw/bsp/rp2040/family.c @@ -53,7 +53,7 @@ // // This doesn't work if others are trying to access flash at the same time, // e.g. XIP streamer, or the other core. -bool __no_inline_not_in_flash_func(get_bootsel_button)() { +bool __no_inline_not_in_flash_func(get_bootsel_button)(void) { const uint CS_PIN_INDEX = 1; // Must disable interrupts, as interrupt handlers may be in flash, and we @@ -170,6 +170,8 @@ void board_init(void) void board_led_write(bool state) { + (void) state; + #ifdef LED_PIN gpio_put(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); #endif @@ -192,6 +194,7 @@ int board_uart_read(uint8_t* buf, int len) } return len; #else + (void) buf; (void) len; return 0; #endif } @@ -205,6 +208,7 @@ int board_uart_write(void const * buf, int len) } return len; #else + (void) buf; (void) len; return 0; #endif } diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index dbd8ab54b..e13e4a46c 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -1619,7 +1619,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * // Reconfigure size of support FIFOs - this is necessary to avoid samples to get split in case of a wrap #if CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING - const uint16_t active_fifo_depth = (audio->tx_supp_ff_sz_max / audio->n_bytes_per_sampe_tx) * audio->n_bytes_per_sampe_tx; + const uint16_t active_fifo_depth = (uint16_t) ((audio->tx_supp_ff_sz_max / audio->n_bytes_per_sampe_tx) * audio->n_bytes_per_sampe_tx); for (uint8_t cnt = 0; cnt < audio->n_tx_supp_ff; cnt++) { tu_fifo_config(&audio->tx_supp_ff[cnt], audio->tx_supp_ff[cnt].buffer, active_fifo_depth, 1, true); diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index cdf155e1c..d15d44838 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -187,7 +187,8 @@ uint16_t hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint1 TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass, 0); // len = interface + hid + n*endpoints - uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); + uint16_t const drv_len = (uint16_t) (sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); TU_ASSERT(max_len >= drv_len, 0); // Find available interface @@ -408,7 +409,7 @@ bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ // Received report else if (ep_addr == p_hid->ep_out) { - tud_hid_set_report_cb(instance, 0, HID_REPORT_TYPE_INVALID, p_hid->epout_buf, xferred_bytes); + tud_hid_set_report_cb(instance, 0, HID_REPORT_TYPE_INVALID, p_hid->epout_buf, (uint16_t) xferred_bytes); TU_ASSERT(usbd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf))); } diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index 28e6a92d2..de41706e8 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -127,7 +127,7 @@ uint32_t tud_midi_n_available(uint8_t itf, uint8_t cable_num) midid_stream_t const* stream = &midi->stream_read; // when using with packet API stream total & index are both zero - return tu_fifo_count(&midi->rx_ff) + (stream->total - stream->index); + return tu_fifo_count(&midi->rx_ff) + (uint8_t) (stream->total - stream->index); } uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void* buffer, uint32_t bufsize) @@ -179,7 +179,7 @@ uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void* buffer, ui } // Copy data up to bufsize - uint32_t const count = tu_min32(stream->total - stream->index, bufsize); + uint8_t const count = (uint8_t) tu_min32(stream->total - stream->index, bufsize); // Skip the header (1st byte) in the buffer memcpy(buf8, stream->buffer + 1 + stream->index, count); @@ -276,13 +276,13 @@ uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, uint8_t const* else if ( (msg >= 0x8 && msg <= 0xB) || msg == 0xE ) { // Channel Voice Messages - stream->buffer[0] = (cable_num << 4) | msg; + stream->buffer[0] = (uint8_t) ((cable_num << 4) | msg); stream->total = 4; } else if ( msg == 0xC || msg == 0xD) { // Channel Voice Messages, two-byte variants (Program Change and Channel Pressure) - stream->buffer[0] = (cable_num << 4) | msg; + stream->buffer[0] = (uint8_t) ((cable_num << 4) | msg); stream->total = 3; } else if ( msg == 0xf ) @@ -312,7 +312,7 @@ uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, uint8_t const* else { // Pack individual bytes if we don't support packing them into words. - stream->buffer[0] = cable_num << 4 | 0xf; + stream->buffer[0] = (uint8_t) (cable_num << 4 | 0xf); stream->buffer[2] = 0; stream->buffer[3] = 0; stream->index = 2; @@ -513,7 +513,7 @@ bool midid_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32 // receive new data if ( ep_addr == p_midi->ep_out ) { - tu_fifo_write_n(&p_midi->rx_ff, p_midi->epout_buf, xferred_bytes); + tu_fifo_write_n(&p_midi->rx_ff, p_midi->epout_buf, (uint16_t) xferred_bytes); // invoke receive callback if available if (tud_midi_rx_cb) tud_midi_rx_cb(itf); From 0b3503cb33e6a269e573a75b6ed67d69aee12dbb Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 16 Jun 2022 12:01:19 +0700 Subject: [PATCH 395/504] clean up usbd log level --- examples/host/bare_api/src/main.c | 4 +- src/device/usbd.c | 68 +++++++++++++++---------------- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index 2cc05d34d..9ccd856d4 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -84,8 +84,8 @@ void tuh_mount_cb (uint8_t daddr) { printf("Device attached, address = %d\r\n", daddr); - // Get Device Descriptor sync API - // TODO: invoking control trannsfer now has issue with mounting hub with multiple devices attached, fix later + // Get Device Descriptor + // TODO: invoking control transfer now has issue with mounting hub with multiple devices attached, fix later tuh_descriptor_get_device(daddr, &desc_device, 18, print_device_descriptor, 0); } diff --git a/src/device/usbd.c b/src/device/usbd.c index 1806281ff..59d0e86e3 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -318,7 +318,7 @@ void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback) usbd_class_driver_t const * driver = get_driver(i); if ( driver->control_xfer_cb == callback ) { - TU_LOG2(" %s control complete\r\n", driver->name); + TU_LOG(USBD_DBG, " %s control complete\r\n", driver->name); return; } } @@ -384,8 +384,8 @@ bool tud_init (uint8_t rhport) // skip if already initialized if ( tud_inited() ) return true; - TU_LOG2("USBD init on controller %u\r\n", rhport); - TU_LOG2_INT(sizeof(usbd_device_t)); + TU_LOG(USBD_DBG, "USBD init on controller %u\r\n", rhport); + TU_LOG_INT(USBD_DBG, sizeof(usbd_device_t)); tu_varclr(&_usbd_dev); @@ -409,7 +409,7 @@ bool tud_init (uint8_t rhport) for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { usbd_class_driver_t const * driver = get_driver(i); - TU_LOG2("%s init\r\n", driver->name); + TU_LOG(USBD_DBG, "%s init\r\n", driver->name); driver->init(); } @@ -480,20 +480,20 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) if ( !osal_queue_receive(_usbd_q, &event, timeout_ms) ) return; #if CFG_TUSB_DEBUG >= 2 - if (event.event_id == DCD_EVENT_SETUP_RECEIVED) TU_LOG2("\r\n"); // extra line for setup - TU_LOG2("USBD %s ", event.event_id < DCD_EVENT_COUNT ? _usbd_event_str[event.event_id] : "CORRUPTED"); + if (event.event_id == DCD_EVENT_SETUP_RECEIVED) TU_LOG(USBD_DBG, "\r\n"); // extra line for setup + TU_LOG(USBD_DBG, "USBD %s ", event.event_id < DCD_EVENT_COUNT ? _usbd_event_str[event.event_id] : "CORRUPTED"); #endif switch ( event.event_id ) { case DCD_EVENT_BUS_RESET: - TU_LOG2(": %s Speed\r\n", tu_str_speed[event.bus_reset.speed]); + TU_LOG(USBD_DBG, ": %s Speed\r\n", tu_str_speed[event.bus_reset.speed]); usbd_reset(event.rhport); _usbd_dev.speed = event.bus_reset.speed; break; case DCD_EVENT_UNPLUGGED: - TU_LOG2("\r\n"); + TU_LOG(USBD_DBG, "\r\n"); usbd_reset(event.rhport); // invoke callback @@ -501,8 +501,8 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) break; case DCD_EVENT_SETUP_RECEIVED: - TU_LOG2_VAR(&event.setup_received); - TU_LOG2("\r\n"); + TU_LOG_VAR(USBD_DBG, &event.setup_received); + TU_LOG(USBD_DBG, "\r\n"); // Mark as connected after receiving 1st setup packet. // But it is easier to set it every time instead of wasting time to check then set @@ -517,7 +517,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) // Process control request if ( !process_control_request(event.rhport, &event.setup_received) ) { - TU_LOG2(" Stall EP0\r\n"); + TU_LOG(USBD_DBG, " Stall EP0\r\n"); // Failed -> stall both control endpoint IN and OUT dcd_edpt_stall(event.rhport, 0); dcd_edpt_stall(event.rhport, 0 | TUSB_DIR_IN_MASK); @@ -531,7 +531,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const ep_dir = tu_edpt_dir(ep_addr); - TU_LOG2("on EP %02X with %u bytes\r\n", ep_addr, (unsigned int) event.xfer_complete.len); + TU_LOG(USBD_DBG, "on EP %02X with %u bytes\r\n", ep_addr, (unsigned int) event.xfer_complete.len); _usbd_dev.ep_status[epnum][ep_dir].busy = false; _usbd_dev.ep_status[epnum][ep_dir].claimed = 0; @@ -545,7 +545,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) usbd_class_driver_t const * driver = get_driver( _usbd_dev.ep2drv[epnum][ep_dir] ); TU_ASSERT(driver, ); - TU_LOG2(" %s xfer callback\r\n", driver->name); + TU_LOG(USBD_DBG, " %s xfer callback\r\n", driver->name); driver->xfer_cb(event.rhport, ep_addr, (xfer_result_t)event.xfer_complete.result, event.xfer_complete.len); } } @@ -557,27 +557,27 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) // e.g suspend -> resume -> unplug/plug. Skip suspend/resume if not connected if ( _usbd_dev.connected ) { - TU_LOG2(": Remote Wakeup = %u\r\n", _usbd_dev.remote_wakeup_en); + TU_LOG(USBD_DBG, ": Remote Wakeup = %u\r\n", _usbd_dev.remote_wakeup_en); if (tud_suspend_cb) tud_suspend_cb(_usbd_dev.remote_wakeup_en); }else { - TU_LOG2(" Skipped\r\n"); + TU_LOG(USBD_DBG, " Skipped\r\n"); } break; case DCD_EVENT_RESUME: if ( _usbd_dev.connected ) { - TU_LOG2("\r\n"); + TU_LOG(USBD_DBG, "\r\n"); if (tud_resume_cb) tud_resume_cb(); }else { - TU_LOG2(" Skipped\r\n"); + TU_LOG(USBD_DBG, " Skipped\r\n"); } break; case USBD_EVENT_FUNC_CALL: - TU_LOG2("\r\n"); + TU_LOG(USBD_DBG, "\r\n"); if ( event.func_call.func ) event.func_call.func(event.func_call.param); break; @@ -602,7 +602,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) static bool invoke_class_control(uint8_t rhport, usbd_class_driver_t const * driver, tusb_control_request_t const * request) { usbd_control_set_complete_callback(driver->control_xfer_cb); - TU_LOG2(" %s control request\r\n", driver->name); + TU_LOG(USBD_DBG, " %s control request\r\n", driver->name); return driver->control_xfer_cb(rhport, CONTROL_STAGE_SETUP, request); } @@ -626,8 +626,8 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const #if CFG_TUSB_DEBUG >= 2 if (TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type && p_request->bRequest <= TUSB_REQ_SYNCH_FRAME) { - TU_LOG2(" %s", tu_str_std_request[p_request->bRequest]); - if (TUSB_REQ_GET_DESCRIPTOR != p_request->bRequest) TU_LOG2("\r\n"); + TU_LOG(USBD_DBG, " %s", tu_str_std_request[p_request->bRequest]); + if (TUSB_REQ_GET_DESCRIPTOR != p_request->bRequest) TU_LOG(USBD_DBG, "\r\n"); } #endif @@ -905,7 +905,7 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num) if ( (sizeof(tusb_desc_interface_t) <= drv_len) && (drv_len <= remaining_len) ) { // Open successfully - TU_LOG2(" %s opened\r\n", driver->name); + TU_LOG(USBD_DBG, " %s opened\r\n", driver->name); // Some drivers use 2 or more interfaces but may not have IAD e.g MIDI (always) or // BTH (even CDC) with class in device descriptor (single interface) @@ -964,7 +964,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const { case TUSB_DESC_DEVICE: { - TU_LOG2(" Device\r\n"); + TU_LOG(USBD_DBG, " Device\r\n"); void* desc_device = (void*) (uintptr_t) tud_descriptor_device_cb(); @@ -988,7 +988,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const case TUSB_DESC_BOS: { - TU_LOG2(" BOS\r\n"); + TU_LOG(USBD_DBG, " BOS\r\n"); // requested by host if USB > 2.0 ( i.e 2.1 or 3.x ) if (!tud_descriptor_bos_cb) return false; @@ -1010,12 +1010,12 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const if ( desc_type == TUSB_DESC_CONFIGURATION ) { - TU_LOG2(" Configuration[%u]\r\n", desc_index); + TU_LOG(USBD_DBG, " Configuration[%u]\r\n", desc_index); desc_config = (uintptr_t) tud_descriptor_configuration_cb(desc_index); }else { // Host only request this after getting Device Qualifier descriptor - TU_LOG2(" Other Speed Configuration\r\n"); + TU_LOG(USBD_DBG, " Other Speed Configuration\r\n"); TU_VERIFY( tud_descriptor_other_speed_configuration_cb ); desc_config = (uintptr_t) tud_descriptor_other_speed_configuration_cb(desc_index); } @@ -1031,7 +1031,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const case TUSB_DESC_STRING: { - TU_LOG2(" String[%u]\r\n", desc_index); + TU_LOG(USBD_DBG, " String[%u]\r\n", desc_index); // String Descriptor always uses the desc set from user uint8_t const* desc_str = (uint8_t const*) tud_descriptor_string_cb(desc_index, tu_le16toh(p_request->wIndex)); @@ -1044,7 +1044,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const case TUSB_DESC_DEVICE_QUALIFIER: { - TU_LOG2(" Device Qualifier\r\n"); + TU_LOG(USBD_DBG, " Device Qualifier\r\n"); TU_VERIFY( tud_descriptor_device_qualifier_cb ); @@ -1237,7 +1237,7 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t // TODO skip ready() check for now since enumeration also use this API // TU_VERIFY(tud_ready()); - TU_LOG2(" Queue EP %02X with %u bytes ...\r\n", ep_addr, total_bytes); + TU_LOG(USBD_DBG, " Queue EP %02X with %u bytes ...\r\n", ep_addr, total_bytes); // Attempt to transfer on a busy endpoint, sound like an race condition ! TU_ASSERT(_usbd_dev.ep_status[epnum][dir].busy == 0); @@ -1254,7 +1254,7 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t // DCD error, mark endpoint as ready to allow next transfer _usbd_dev.ep_status[epnum][dir].busy = false; _usbd_dev.ep_status[epnum][dir].claimed = 0; - TU_LOG2("FAILED\r\n"); + TU_LOG(USBD_DBG, "FAILED\r\n"); TU_BREAKPOINT(); return false; } @@ -1271,7 +1271,7 @@ bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16 uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); - TU_LOG2(" Queue ISO EP %02X with %u bytes ... ", ep_addr, total_bytes); + TU_LOG(USBD_DBG, " Queue ISO EP %02X with %u bytes ... ", ep_addr, total_bytes); // Attempt to transfer on a busy endpoint, sound like an race condition ! TU_ASSERT(_usbd_dev.ep_status[epnum][dir].busy == 0); @@ -1282,14 +1282,14 @@ bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16 if (dcd_edpt_xfer_fifo(rhport, ep_addr, ff, total_bytes)) { - TU_LOG2("OK\r\n"); + TU_LOG(USBD_DBG, "OK\r\n"); return true; }else { // DCD error, mark endpoint as ready to allow next transfer _usbd_dev.ep_status[epnum][dir].busy = false; _usbd_dev.ep_status[epnum][dir].claimed = 0; - TU_LOG2("failed\r\n"); + TU_LOG(USBD_DBG, "failed\r\n"); TU_BREAKPOINT(); return false; } @@ -1360,7 +1360,7 @@ void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr) rhport = _usbd_rhport; TU_ASSERT(dcd_edpt_close, /**/); - TU_LOG2(" CLOSING Endpoint: 0x%02X\r\n", ep_addr); + TU_LOG(USBD_DBG, " CLOSING Endpoint: 0x%02X\r\n", ep_addr); uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); From 556b5d5044bd02e89d6b6c6f21e95d46f5fcdfc1 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 27 Jun 2022 12:22:36 +0700 Subject: [PATCH 396/504] change report len in hid API from uint8_t to uint16_t since HS interrupt endpoint can be up to 1024, 8-bit is not enough. affected APIs are: - tud_hid_n_report() / tud_hid_report() - tud_hid_report_complete_cb() --- examples/device/hid_boot_interface/src/main.c | 2 +- examples/device/hid_composite/src/main.c | 2 +- examples/device/hid_composite_freertos/src/main.c | 2 +- src/class/hid/hid_device.c | 8 ++++---- src/class/hid/hid_device.h | 8 ++++---- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/device/hid_boot_interface/src/main.c b/examples/device/hid_boot_interface/src/main.c index 21cdb383d..1958d614d 100644 --- a/examples/device/hid_boot_interface/src/main.c +++ b/examples/device/hid_boot_interface/src/main.c @@ -181,7 +181,7 @@ void tud_hid_set_protocol_cb(uint8_t instance, uint8_t protocol) // Invoked when sent REPORT successfully to host // Application can use this to send the next report // Note: For composite reports, report[0] is report ID -void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint8_t len) +void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len) { (void) instance; (void) report; diff --git a/examples/device/hid_composite/src/main.c b/examples/device/hid_composite/src/main.c index bc2347ab8..3c088b7c2 100644 --- a/examples/device/hid_composite/src/main.c +++ b/examples/device/hid_composite/src/main.c @@ -225,7 +225,7 @@ void hid_task(void) // Invoked when sent REPORT successfully to host // Application can use this to send the next report // Note: For composite reports, report[0] is report ID -void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint8_t len) +void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len) { (void) instance; (void) len; diff --git a/examples/device/hid_composite_freertos/src/main.c b/examples/device/hid_composite_freertos/src/main.c index 1030f3d05..ea8d917fe 100644 --- a/examples/device/hid_composite_freertos/src/main.c +++ b/examples/device/hid_composite_freertos/src/main.c @@ -294,7 +294,7 @@ void hid_task(void* param) // Invoked when sent REPORT successfully to host // Application can use this to send the next report // Note: For composite reports, report[0] is report ID -void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint8_t len) +void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len) { (void) instance; (void) len; diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index cdf155e1c..210050858 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -81,7 +81,7 @@ bool tud_hid_n_ready(uint8_t instance) return tud_ready() && (ep_in != 0) && !usbd_edpt_busy(rhport, ep_in); } -bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, uint8_t len) +bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, uint16_t len) { uint8_t const rhport = 0; hidd_interface_t * p_hid = &_hidd_itf[instance]; @@ -92,7 +92,7 @@ bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, u // prepare data if (report_id) { - len = tu_min8(len, CFG_TUD_HID_EP_BUFSIZE-1); + len = tu_min16(len, CFG_TUD_HID_EP_BUFSIZE-1); p_hid->epin_buf[0] = report_id; memcpy(p_hid->epin_buf+1, report, len); @@ -100,7 +100,7 @@ bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, u }else { // If report id = 0, skip ID field - len = tu_min8(len, CFG_TUD_HID_EP_BUFSIZE); + len = tu_min16(len, CFG_TUD_HID_EP_BUFSIZE); memcpy(p_hid->epin_buf, report, len); } @@ -402,7 +402,7 @@ bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ { if (tud_hid_report_complete_cb) { - tud_hid_report_complete_cb(instance, p_hid->epin_buf, (uint8_t) xferred_bytes); + tud_hid_report_complete_cb(instance, p_hid->epin_buf, (uint16_t) xferred_bytes); } } // Received report diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index 078b67349..3714d2769 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -62,7 +62,7 @@ uint8_t tud_hid_n_interface_protocol(uint8_t instance); uint8_t tud_hid_n_get_protocol(uint8_t instance); // Send report to host -bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, uint8_t len); +bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, uint16_t len); // KEYBOARD: convenient helper to send keyboard report if application // use template layout report as defined by hid_keyboard_report_t @@ -82,7 +82,7 @@ bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, int8_t x, int static inline bool tud_hid_ready(void); static inline uint8_t tud_hid_interface_protocol(void); static inline uint8_t tud_hid_get_protocol(void); -static inline bool tud_hid_report(uint8_t report_id, void const* report, uint8_t len); +static inline bool tud_hid_report(uint8_t report_id, void const* report, uint16_t len); static inline bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycode[6]); static inline bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal); static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons); @@ -116,7 +116,7 @@ TU_ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t instance, uint8_t idle_rate); // Invoked when sent REPORT successfully to host // Application can use this to send the next report // Note: For composite reports, report[0] is report ID -TU_ATTR_WEAK void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint8_t len); +TU_ATTR_WEAK void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len); //--------------------------------------------------------------------+ @@ -137,7 +137,7 @@ static inline uint8_t tud_hid_get_protocol(void) return tud_hid_n_get_protocol(0); } -static inline bool tud_hid_report(uint8_t report_id, void const* report, uint8_t len) +static inline bool tud_hid_report(uint8_t report_id, void const* report, uint16_t len) { return tud_hid_n_report(0, report_id, report, len); } From 6522a8150e22d47bacabd2f1f027452db2254984 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 27 Jun 2022 13:48:47 +0700 Subject: [PATCH 397/504] fix all device examples warnings --- examples/device/midi_test/src/main.c | 2 +- .../device/msc_dual_lun/src/msc_disk_dual.c | 6 +-- examples/device/uac2_headset/src/main.c | 16 ++++---- .../device/uac2_headset/src/usb_descriptors.c | 2 +- src/class/audio/audio_device.c | 12 ++++-- src/class/vendor/vendor_device.c | 10 ++--- src/class/video/video_device.c | 38 ++++++++++--------- 7 files changed, 47 insertions(+), 39 deletions(-) diff --git a/examples/device/midi_test/src/main.c b/examples/device/midi_test/src/main.c index b47d1af76..3310348bd 100644 --- a/examples/device/midi_test/src/main.c +++ b/examples/device/midi_test/src/main.c @@ -140,7 +140,7 @@ void midi_task(void) start_ms += 286; // Previous positions in the note sequence. - int previous = note_pos - 1; + int previous = (int) (note_pos - 1); // If we currently are at position 0, set the // previous position to the last note in the sequence. diff --git a/examples/device/msc_dual_lun/src/msc_disk_dual.c b/examples/device/msc_dual_lun/src/msc_disk_dual.c index 37446ebc3..2b773b43b 100644 --- a/examples/device/msc_dual_lun/src/msc_disk_dual.c +++ b/examples/device/msc_dual_lun/src/msc_disk_dual.c @@ -277,7 +277,7 @@ int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buff uint8_t const* addr = (lun ? msc_disk1[lba] : msc_disk0[lba]) + offset; memcpy(buffer, addr, bufsize); - return bufsize; + return (int32_t) bufsize; } bool tud_msc_is_writable_cb (uint8_t lun) @@ -305,7 +305,7 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* (void) lun; (void) lba; (void) offset; (void) buffer; #endif - return bufsize; + return (int32_t) bufsize; } // Callback invoked when received an SCSI command not in built-in list below @@ -339,7 +339,7 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, { if(in_xfer) { - memcpy(buffer, response, resplen); + memcpy(buffer, response, (size_t) resplen); }else { // SCSI output diff --git a/examples/device/uac2_headset/src/main.c b/examples/device/uac2_headset/src/main.c index a8d204eaa..003dc2a74 100644 --- a/examples/device/uac2_headset/src/main.c +++ b/examples/device/uac2_headset/src/main.c @@ -159,7 +159,7 @@ static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t { TU_LOG1("Clock get current freq %lu\r\n", current_sample_rate); - audio_control_cur_4_t curf = { tu_htole32(current_sample_rate) }; + audio_control_cur_4_t curf = { (int32_t) tu_htole32(current_sample_rate) }; return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &curf, sizeof(curf)); } else if (request->bRequest == AUDIO_CS_REQ_RANGE) @@ -171,8 +171,8 @@ static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t TU_LOG1("Clock get %d freq ranges\r\n", N_SAMPLE_RATES); for(uint8_t i = 0; i < N_SAMPLE_RATES; i++) { - rangef.subrange[i].bMin = sample_rates[i]; - rangef.subrange[i].bMax = sample_rates[i]; + rangef.subrange[i].bMin = (int32_t) sample_rates[i]; + rangef.subrange[i].bMax = (int32_t) sample_rates[i]; rangef.subrange[i].bRes = 0; TU_LOG1("Range %d (%d, %d, %d)\r\n", i, (int)rangef.subrange[i].bMin, (int)rangef.subrange[i].bMax, (int)rangef.subrange[i].bRes); } @@ -204,7 +204,7 @@ static bool tud_audio_clock_set_request(uint8_t rhport, audio_control_request_t { TU_VERIFY(request->wLength == sizeof(audio_control_cur_4_t)); - current_sample_rate = ((audio_control_cur_4_t const *)buf)->bCur; + current_sample_rate = (uint32_t) ((audio_control_cur_4_t const *)buf)->bCur; TU_LOG1("Clock set current freq: %ld\r\n", current_sample_rate); @@ -403,9 +403,9 @@ void audio_task(void) // Combine two channels into one int32_t left = *src++; int32_t right = *src++; - *dst++ = (left >> 1) + (right >> 1); + *dst++ = (int16_t) ((left >> 1) + (right >> 1)); } - tud_audio_write((uint8_t *)mic_buf, spk_data_size / 2); + tud_audio_write((uint8_t *)mic_buf, (uint16_t) (spk_data_size / 2)); spk_data_size = 0; } else if (current_resolution == 24) @@ -418,9 +418,9 @@ void audio_task(void) // Combine two channels into one int32_t left = *src++; int32_t right = *src++; - *dst++ = ((left >> 1) + (right >> 1)) & 0xffffff00; + *dst++ = (int32_t) ((uint32_t) ((left >> 1) + (right >> 1)) & 0xffffff00ul); } - tud_audio_write((uint8_t *)mic_buf, spk_data_size / 2); + tud_audio_write((uint8_t *)mic_buf, (uint16_t) (spk_data_size / 2)); spk_data_size = 0; } } diff --git a/examples/device/uac2_headset/src/usb_descriptors.c b/examples/device/uac2_headset/src/usb_descriptors.c index a2d6368bf..10f5cbd27 100644 --- a/examples/device/uac2_headset/src/usb_descriptors.c +++ b/examples/device/uac2_headset/src/usb_descriptors.c @@ -165,7 +165,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2 * chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); return _desc_str; } diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index e13e4a46c..6df68c559 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -537,7 +537,7 @@ tu_fifo_t* tud_audio_n_get_rx_support_ff(uint8_t func_id, uint8_t ff_idx) static bool audiod_rx_done_cb(uint8_t rhport, audiod_function_t* audio, uint16_t n_bytes_received) { - uint8_t idxItf; + uint8_t idxItf = 0; uint8_t const *dummy2; uint8_t idx_audio_fct = 0; @@ -548,7 +548,10 @@ static bool audiod_rx_done_cb(uint8_t rhport, audiod_function_t* audio, uint16_t } // Call a weak callback here - a possibility for user to get informed an audio packet was received and data gets now loaded into EP FIFO (or decoded into support RX software FIFO) - if (tud_audio_rx_done_pre_read_cb) TU_VERIFY(tud_audio_rx_done_pre_read_cb(rhport, n_bytes_received, idx_audio_fct, audio->ep_out, audio->alt_setting[idxItf])); + if (tud_audio_rx_done_pre_read_cb) + { + TU_VERIFY(tud_audio_rx_done_pre_read_cb(rhport, n_bytes_received, idx_audio_fct, audio->ep_out, audio->alt_setting[idxItf])); + } #if CFG_TUD_AUDIO_ENABLE_DECODING && CFG_TUD_AUDIO_ENABLE_EP_OUT @@ -602,7 +605,10 @@ static bool audiod_rx_done_cb(uint8_t rhport, audiod_function_t* audio, uint16_t #endif // Call a weak callback here - a possibility for user to get informed decoding was completed - if (tud_audio_rx_done_post_read_cb) TU_VERIFY(tud_audio_rx_done_post_read_cb(rhport, n_bytes_received, idx_audio_fct, audio->ep_out, audio->alt_setting[idxItf])); + if (tud_audio_rx_done_post_read_cb) + { + TU_VERIFY(tud_audio_rx_done_post_read_cb(rhport, n_bytes_received, idx_audio_fct, audio->ep_out, audio->alt_setting[idxItf])); + } return true; } diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index c7dfa0062..3b81a108f 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -100,7 +100,7 @@ static void _prep_out_transaction (vendord_interface_t* p_itf) uint32_t tud_vendor_n_read (uint8_t itf, void* buffer, uint32_t bufsize) { vendord_interface_t* p_itf = &_vendord_itf[itf]; - uint32_t num_read = tu_fifo_read_n(&p_itf->rx_ff, buffer, bufsize); + uint32_t num_read = tu_fifo_read_n(&p_itf->rx_ff, buffer, (uint16_t) bufsize); _prep_out_transaction(p_itf); return num_read; } @@ -133,7 +133,7 @@ static uint16_t maybe_transmit(vendord_interface_t* p_itf) uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize) { vendord_interface_t* p_itf = &_vendord_itf[itf]; - uint16_t ret = tu_fifo_write_n(&p_itf->tx_ff, buffer, bufsize); + uint16_t ret = tu_fifo_write_n(&p_itf->tx_ff, buffer, (uint16_t) bufsize); if (tu_fifo_count(&p_itf->tx_ff) >= CFG_TUD_VENDOR_EPSIZE) { maybe_transmit(p_itf); } @@ -231,7 +231,7 @@ uint16_t vendord_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, ui if ( p_vendor->ep_in ) maybe_transmit(p_vendor); } - return (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) @@ -252,7 +252,7 @@ bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint if ( ep_addr == p_itf->ep_out ) { // Receive new data - tu_fifo_write_n(&p_itf->rx_ff, p_itf->epout_buf, xferred_bytes); + tu_fifo_write_n(&p_itf->rx_ff, p_itf->epout_buf, (uint16_t) xferred_bytes); // Invoked callback if any if (tud_vendor_rx_cb) tud_vendor_rx_cb(itf); @@ -261,7 +261,7 @@ bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint } else if ( ep_addr == p_itf->ep_in ) { - if (tud_vendor_tx_cb) tud_vendor_tx_cb(itf, xferred_bytes); + if (tud_vendor_tx_cb) tud_vendor_tx_cb(itf, (uint16_t) xferred_bytes); // Send complete, try to send more if possible maybe_transmit(p_itf); } diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 91718f205..7636db5fe 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -297,7 +297,7 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm { tusb_desc_vs_itf_t const *vs = _get_desc_vs(stm); uint_fast8_t fmtnum = param->bFormatIndex; - TU_ASSERT(fmtnum <= vs->stm.bNumFormats); + TU_ASSERT(vs && fmtnum <= vs->stm.bNumFormats); if (!fmtnum) { if (1 < vs->stm.bNumFormats) return true; /* Need to negotiate all variables. */ fmtnum = 1; @@ -393,6 +393,7 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * uint_fast8_t frmnum = param->bFrameIndex; if (!frmnum) { tusb_desc_vs_itf_t const *vs = _get_desc_vs(stm); + TU_ASSERT(vs); void const *end = _end_of_streaming_descriptor(vs); tusb_desc_cs_video_fmt_uncompressed_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); switch (request) { @@ -407,15 +408,16 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * break; default: return false; } - param->bFrameIndex = frmnum; + param->bFrameIndex = (uint8_t) frmnum; /* Set the parameters determined by the frame */ tusb_desc_cs_video_frm_uncompressed_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); - param->dwMaxVideoFrameSize = frm->wWidth * frm->wHeight * fmt->bBitsPerPixel / 8; + param->dwMaxVideoFrameSize = (uint32_t) (frm->wWidth * frm->wHeight * fmt->bBitsPerPixel / 8); return true; } if (!param->dwFrameInterval) { tusb_desc_vs_itf_t const *vs = _get_desc_vs(stm); + TU_ASSERT(vs); void const *end = _end_of_streaming_descriptor(vs); tusb_desc_cs_video_fmt_uncompressed_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); tusb_desc_cs_video_frm_uncompressed_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); @@ -532,7 +534,7 @@ static bool _open_vc_itf(uint8_t rhport, videod_interface_t *self, uint_fast8_t /* Open the notification endpoint */ TU_ASSERT(usbd_edpt_open(rhport, notif)); } - self->cur = (void const*)vc - beg; + self->cur = (uint16_t) ((void const*)vc - beg); return true; } @@ -550,7 +552,7 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint for (i = 0; i < TU_ARRAY_SIZE(stm->desc.ep); ++i) { uint_fast16_t ofs_ep = stm->desc.ep[i]; if (!ofs_ep) break; - uint_fast8_t ep_adr = _desc_ep_addr(desc + ofs_ep); + uint8_t ep_adr = _desc_ep_addr(desc + ofs_ep); usbd_edpt_close(rhport, ep_adr); stm->desc.ep[i] = 0; TU_LOG2(" close EP%02x\n", ep_adr); @@ -567,7 +569,7 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint TU_VERIFY(cur < end); uint_fast8_t numeps = ((tusb_desc_interface_t const *)cur)->bNumEndpoints; TU_ASSERT(numeps <= TU_ARRAY_SIZE(stm->desc.ep)); - stm->desc.cur = cur - desc; /* Save the offset of the new settings */ + stm->desc.cur = (uint16_t) (cur - desc); /* Save the offset of the new settings */ if (!altnum) { /* initialize streaming settings */ stm->max_payload_transfer_size = 0; @@ -594,7 +596,7 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint stm->max_payload_transfer_size = max_size; } TU_ASSERT(usbd_edpt_open(rhport, ep)); - stm->desc.ep[i] = cur - desc; + stm->desc.ep[i] = (uint16_t) (cur - desc); TU_LOG2(" open EP%02x\n", _desc_ep_addr(cur)); } /* initialize payload header */ @@ -976,7 +978,7 @@ bool tud_video_n_frame_xfer(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, void *bu /* Find EP address */ void const *desc = _videod_itf[stm->index_vc].beg; - uint_fast8_t ep_addr = 0; + uint8_t ep_addr = 0; for (uint_fast8_t i = 0; i < CFG_TUD_VIDEO_STREAMING; ++i) { uint_fast16_t ofs_ep = stm->desc.ep[i]; if (!ofs_ep) continue; @@ -985,7 +987,7 @@ bool tud_video_n_frame_xfer(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, void *bu } if (!ep_addr) return false; - TU_VERIFY( usbd_edpt_claim(0, ep_addr)); + TU_VERIFY( usbd_edpt_claim(0, ep_addr) ); /* update the packet header */ tusb_video_payload_header_t *hdr = (tusb_video_payload_header_t*)stm->ep_buf; hdr->FrameID ^= 1; @@ -994,7 +996,7 @@ bool tud_video_n_frame_xfer(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, void *bu stm->buffer = (uint8_t*)buffer; stm->bufsize = bufsize; uint_fast16_t pkt_len = _prepare_in_payload(stm); - TU_ASSERT( usbd_edpt_xfer(0, ep_addr, stm->ep_buf, pkt_len), 0); + TU_ASSERT( usbd_edpt_xfer(0, ep_addr, stm->ep_buf, (uint16_t) pkt_len), 0); return true; } @@ -1034,7 +1036,7 @@ uint16_t videod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin /* Find available interface */ videod_interface_t *self = NULL; - uint_fast8_t ctl_idx; + uint8_t ctl_idx; for (ctl_idx = 0; ctl_idx < CFG_TUD_VIDEO; ++ctl_idx) { if (_videod_itf[ctl_idx].beg) continue; self = &_videod_itf[ctl_idx]; @@ -1051,10 +1053,10 @@ uint16_t videod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin uint_fast8_t bInCollection = vc->ctl.bInCollection; /* Find the end of the video interface descriptor */ void const *cur = _next_desc_itf(itf_desc, end); - for (uint_fast8_t stm_idx = 0; stm_idx < bInCollection; ++stm_idx) { + for (uint8_t stm_idx = 0; stm_idx < bInCollection; ++stm_idx) { videod_streaming_interface_t *stm = NULL; /* find free streaming interface handle */ - for (uint_fast8_t i = 0; i < CFG_TUD_VIDEO_STREAMING; ++i) { + for (uint8_t i = 0; i < CFG_TUD_VIDEO_STREAMING; ++i) { if (_videod_streaming_itf[i].desc.beg) continue; stm = &_videod_streaming_itf[i]; self->stm[stm_idx] = i; @@ -1063,12 +1065,12 @@ uint16_t videod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin TU_ASSERT(stm, 0); stm->index_vc = ctl_idx; stm->index_vs = stm_idx; - stm->desc.beg = (uintptr_t)cur - (uintptr_t)itf_desc; + stm->desc.beg = (uint16_t) ((uintptr_t)cur - (uintptr_t)itf_desc); cur = _next_desc_itf(cur, end); - stm->desc.end = (uintptr_t)cur - (uintptr_t)itf_desc; + stm->desc.end = (uint16_t) ((uintptr_t)cur - (uintptr_t)itf_desc); } - self->len = (uintptr_t)cur - (uintptr_t)itf_desc; - return (uintptr_t)cur - (uintptr_t)itf_desc; + self->len = (uint16_t) ((uintptr_t)cur - (uintptr_t)itf_desc); + return (uint16_t) ((uintptr_t)cur - (uintptr_t)itf_desc); } // Invoked when a control transfer occurred on an interface of this class @@ -1134,7 +1136,7 @@ bool videod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 /* Claim the endpoint */ TU_VERIFY( usbd_edpt_claim(rhport, ep_addr), 0); uint_fast16_t pkt_len = _prepare_in_payload(stm); - TU_ASSERT( usbd_edpt_xfer(rhport, ep_addr, stm->ep_buf, pkt_len), 0); + TU_ASSERT( usbd_edpt_xfer(rhport, ep_addr, stm->ep_buf, (uint16_t) pkt_len), 0); } else { stm->buffer = NULL; stm->bufsize = 0; From a0ef4898906a5985deae11e5539a942885398ca1 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 27 Jun 2022 17:11:24 +0700 Subject: [PATCH 398/504] fix all warnings with host rp2040 --- .../host_hid_to_device_cdc/CMakeLists.txt | 4 + .../dual/host_hid_to_device_cdc/src/main.c | 6 +- examples/host/bare_api/CMakeLists.txt | 3 + examples/host/bare_api/src/main.c | 11 +- examples/host/cdc_msc_hid/CMakeLists.txt | 3 + examples/host/hid_controller/CMakeLists.txt | 3 + src/class/cdc/cdc_host.c | 8 +- src/class/hid/hid_host.c | 7 +- src/class/msc/msc_host.c | 8 +- src/host/usbh.c | 6 +- src/osal/osal_pico.h | 5 - src/portable/raspberrypi/rp2040/hcd_rp2040.c | 111 ++++++++++-------- 12 files changed, 98 insertions(+), 77 deletions(-) diff --git a/examples/dual/host_hid_to_device_cdc/CMakeLists.txt b/examples/dual/host_hid_to_device_cdc/CMakeLists.txt index ea4e087e3..cd6f16339 100644 --- a/examples/dual/host_hid_to_device_cdc/CMakeLists.txt +++ b/examples/dual/host_hid_to_device_cdc/CMakeLists.txt @@ -23,6 +23,10 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +# skip extra warnings since pio-usb still has some warnings to fix +#include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_dual_usb_example(${PROJECT}) 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 6a25a28da..bd7870274 100644 --- a/examples/dual/host_hid_to_device_cdc/src/main.c +++ b/examples/dual/host_hid_to_device_cdc/src/main.c @@ -160,7 +160,7 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re char tempbuf[256]; int count = sprintf(tempbuf, "[%04x:%04x][%u] HID Interface%u, Protocol = %s\r\n", vid, pid, dev_addr, instance, protocol_str[itf_protocol]); - tud_cdc_write(tempbuf, count); + tud_cdc_write(tempbuf, (uint32_t) count); tud_cdc_write_flush(); // Receive report from boot keyboard & mouse only @@ -179,7 +179,7 @@ void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) { char tempbuf[256]; int count = sprintf(tempbuf, "[%u] HID Interface%u is unmounted\r\n", dev_addr, instance); - tud_cdc_write(tempbuf, count); + tud_cdc_write(tempbuf, (uint32_t) count); tud_cdc_write_flush(); } @@ -251,7 +251,7 @@ static void process_mouse_report(uint8_t dev_addr, hid_mouse_report_t const * re char tempbuf[32]; int count = sprintf(tempbuf, "[%u] %c%c%c %d %d %d\r\n", dev_addr, l, m, r, report->x, report->y, report->wheel); - tud_cdc_write(tempbuf, count); + tud_cdc_write(tempbuf, (uint32_t) count); tud_cdc_write_flush(); } diff --git a/examples/host/bare_api/CMakeLists.txt b/examples/host/bare_api/CMakeLists.txt index bc04b01a7..98540ffb0 100644 --- a/examples/host/bare_api/CMakeLists.txt +++ b/examples/host/bare_api/CMakeLists.txt @@ -22,6 +22,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_host_example(${PROJECT}) diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index 9ccd856d4..51cab2de0 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -189,7 +189,7 @@ void parse_config_descriptor(uint8_t dev_addr, tusb_desc_configuration_t const* if( TUSB_DESC_INTERFACE != tu_desc_type(p_desc) ) return; tusb_desc_interface_t const* desc_itf = (tusb_desc_interface_t const*) p_desc; - uint16_t const drv_len = count_interface_total_len(desc_itf, assoc_itf_count, desc_end-p_desc); + uint16_t const drv_len = count_interface_total_len(desc_itf, assoc_itf_count, (uint16_t) (desc_end-p_desc)); // probably corrupted descriptor if(drv_len < sizeof(tusb_desc_interface_t)) return; @@ -244,7 +244,8 @@ void hid_report_received(tuh_xfer_t* xfer); void open_hid_interface(uint8_t daddr, tusb_desc_interface_t const *desc_itf, uint16_t max_len) { // len = interface + hid + n*endpoints - uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); + uint16_t const drv_len = (uint16_t) (sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); // corrupted descriptor if (max_len < drv_len) return; @@ -377,7 +378,7 @@ static void _convert_utf16le_to_utf8(const uint16_t *utf16, size_t utf16_len, ui for (size_t i = 0; i < utf16_len; i++) { uint16_t chr = utf16[i]; if (chr < 0x80) { - *utf8++ = chr & 0xff; + *utf8++ = chr & 0xffu; } else if (chr < 0x800) { *utf8++ = (uint8_t)(0xC0 | (chr >> 6 & 0x1F)); *utf8++ = (uint8_t)(0x80 | (chr >> 0 & 0x3F)); @@ -405,12 +406,12 @@ static int _count_utf8_bytes(const uint16_t *buf, size_t len) { } // TODO: Handle UTF-16 code points that take two entries. } - return total_bytes; + return (int) total_bytes; } static void print_utf16(uint16_t *temp_buf, size_t buf_len) { size_t utf16_len = ((temp_buf[0] & 0xff) - 2) / sizeof(uint16_t); - size_t utf8_len = _count_utf8_bytes(temp_buf + 1, utf16_len); + 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'; diff --git a/examples/host/cdc_msc_hid/CMakeLists.txt b/examples/host/cdc_msc_hid/CMakeLists.txt index c4a4d8e63..6990e957b 100644 --- a/examples/host/cdc_msc_hid/CMakeLists.txt +++ b/examples/host/cdc_msc_hid/CMakeLists.txt @@ -24,6 +24,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_host_example(${PROJECT}) diff --git a/examples/host/hid_controller/CMakeLists.txt b/examples/host/hid_controller/CMakeLists.txt index 6153d399a..eefeb4a49 100644 --- a/examples/host/hid_controller/CMakeLists.txt +++ b/examples/host/hid_controller/CMakeLists.txt @@ -23,6 +23,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Example common such as compiler warnings +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_host_example(${PROJECT}) diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 044085e81..ee824cb4e 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -105,7 +105,7 @@ bool tuh_cdc_send(uint8_t dev_addr, void const * p_data, uint32_t length, bool i uint8_t const ep_out = cdch_data[dev_addr-1].ep_out; if ( usbh_edpt_busy(dev_addr, ep_out) ) return false; - return usbh_edpt_xfer(dev_addr, ep_out, (void*)(uintptr_t) p_data, length); + return usbh_edpt_xfer(dev_addr, ep_out, (void*)(uintptr_t) p_data, (uint16_t) length); } bool tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is_notify) @@ -117,7 +117,7 @@ bool tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is uint8_t const ep_in = cdch_data[dev_addr-1].ep_in; if ( usbh_edpt_busy(dev_addr, ep_in) ) return false; - return usbh_edpt_xfer(dev_addr, ep_in, p_buffer, length); + return usbh_edpt_xfer(dev_addr, ep_in, p_buffer, (uint16_t) length); } bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_xfer_cb_t complete_cb) @@ -133,8 +133,8 @@ bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_xf .direction = TUSB_DIR_OUT }, .bRequest = CDC_REQUEST_SET_CONTROL_LINE_STATE, - .wValue = (rts ? 2 : 0) | (dtr ? 1 : 0), - .wIndex = p_cdc->itf_num, + .wValue = tu_htole16((uint16_t) ((dtr ? 1u : 0u) | (rts ? 2u : 0u))), + .wIndex = tu_htole16(p_cdc->itf_num), .wLength = 0 }; diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 2573f5a6b..ca745464c 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -295,10 +295,10 @@ bool hidh_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint3 { TU_LOG2(" Get Report callback (%u, %u)\r\n", dev_addr, instance); TU_LOG3_MEM(hid_itf->epin_buf, xferred_bytes, 2); - tuh_hid_report_received_cb(dev_addr, instance, hid_itf->epin_buf, xferred_bytes); + tuh_hid_report_received_cb(dev_addr, instance, hid_itf->epin_buf, (uint16_t) xferred_bytes); }else { - if (tuh_hid_report_sent_cb) tuh_hid_report_sent_cb(dev_addr, instance, hid_itf->epout_buf, xferred_bytes); + if (tuh_hid_report_sent_cb) tuh_hid_report_sent_cb(dev_addr, instance, hid_itf->epout_buf, (uint16_t) xferred_bytes); } return true; @@ -332,7 +332,8 @@ bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *de TU_LOG2("[%u] HID opening Interface %u\r\n", dev_addr, desc_itf->bInterfaceNumber); // len = interface + hid + n*endpoints - uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); + uint16_t const drv_len = (uint16_t) (sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); TU_ASSERT(max_len >= drv_len); uint8_t const *p_desc = (uint8_t const *) desc_itf; diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index c54a63f37..934f79ff7 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -325,19 +325,19 @@ bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32 p_msc->stage = MSC_STAGE_DATA; uint8_t const ep_data = (cbw->dir & TUSB_DIR_IN_MASK) ? p_msc->ep_in : p_msc->ep_out; - TU_ASSERT(usbh_edpt_xfer(dev_addr, ep_data, p_msc->buffer, cbw->total_bytes)); + TU_ASSERT(usbh_edpt_xfer(dev_addr, ep_data, p_msc->buffer, (uint16_t) cbw->total_bytes)); }else { // Status stage p_msc->stage = MSC_STAGE_STATUS; - TU_ASSERT(usbh_edpt_xfer(dev_addr, p_msc->ep_in, (uint8_t*) &p_msc->csw, sizeof(msc_csw_t))); + TU_ASSERT(usbh_edpt_xfer(dev_addr, p_msc->ep_in, (uint8_t*) &p_msc->csw, (uint16_t) sizeof(msc_csw_t))); } break; case MSC_STAGE_DATA: // Status stage p_msc->stage = MSC_STAGE_STATUS; - TU_ASSERT(usbh_edpt_xfer(dev_addr, p_msc->ep_in, (uint8_t*) &p_msc->csw, sizeof(msc_csw_t))); + TU_ASSERT(usbh_edpt_xfer(dev_addr, p_msc->ep_in, (uint8_t*) &p_msc->csw, (uint16_t) sizeof(msc_csw_t))); break; case MSC_STAGE_STATUS: @@ -370,7 +370,7 @@ bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *de MSC_PROTOCOL_BOT == desc_itf->bInterfaceProtocol); // msc driver length is fixed - uint16_t const drv_len = sizeof(tusb_desc_interface_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); + uint16_t const drv_len = (uint16_t) (sizeof(tusb_desc_interface_t) + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); TU_ASSERT(drv_len <= max_len); msch_interface_t* p_msc = get_itf(dev_addr); diff --git a/src/host/usbh.c b/src/host/usbh.c index 4c9b0b1ba..b6a03b82e 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -665,7 +665,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result TU_LOG2_MEM(_ctrl_xfer.buffer, xferred_bytes, 2); } - _ctrl_xfer.actual_len = xferred_bytes; + _ctrl_xfer.actual_len = (uint16_t) xferred_bytes; // ACK stage: toggle is always 1 _set_control_xfer_stage(CONTROL_STAGE_ACK); @@ -696,7 +696,7 @@ bool tuh_edpt_xfer(tuh_xfer_t* xfer) TU_VERIFY(usbh_edpt_claim(daddr, ep_addr)); - if ( !usbh_edpt_xfer_with_callback(daddr, ep_addr, xfer->buffer, xfer->buflen, xfer->complete_cb, xfer->user_data) ) + if ( !usbh_edpt_xfer_with_callback(daddr, ep_addr, xfer->buffer, (uint16_t) xfer->buflen, xfer->complete_cb, xfer->user_data) ) { usbh_edpt_release(daddr, ep_addr); return false; @@ -1525,7 +1525,7 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur } #endif - uint16_t const drv_len = tu_desc_get_interface_total_len(desc_itf, assoc_itf_count, desc_end-p_desc); + 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 diff --git a/src/osal/osal_pico.h b/src/osal/osal_pico.h index abef286b4..8b428d642 100644 --- a/src/osal/osal_pico.h +++ b/src/osal/osal_pico.h @@ -100,11 +100,6 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hd //--------------------------------------------------------------------+ #include "common/tusb_fifo.h" -#if CFG_TUH_ENABLED -extern void hcd_int_disable(uint8_t rhport); -extern void hcd_int_enable(uint8_t rhport); -#endif - typedef struct { tu_fifo_t ff; diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 93c764caf..13e7778ea 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -262,7 +262,7 @@ static struct hw_endpoint *_next_free_interrupt_ep(void) if (!ep->configured) { // Will be configured by _hw_endpoint_init / _hw_endpoint_allocate - ep->interrupt_num = i - 1; + ep->interrupt_num = (uint8_t) (i - 1); return ep; } } @@ -297,7 +297,7 @@ static struct hw_endpoint *_hw_endpoint_allocate(uint8_t transfer_type) return ep; } -static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t ep_addr, uint 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->endpoint_control); @@ -329,7 +329,10 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t | EP_CTRL_INTERRUPT_PER_BUFFER | (ep->transfer_type << EP_CTRL_BUFFER_TYPE_LSB) | dpram_offset; - ep_reg |= bmInterval ? (bmInterval - 1) << EP_CTRL_HOST_INTERRUPT_INTERVAL_LSB : 0; + if (bmInterval) + { + ep_reg |= (uint32_t) ((bmInterval - 1) << EP_CTRL_HOST_INTERRUPT_INTERVAL_LSB); + } *ep->endpoint_control = ep_reg; pico_trace("endpoint control (0x%p) <- 0x%x\n", ep->endpoint_control, ep_reg); ep->configured = true; @@ -341,7 +344,7 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t // device address // endpoint number / direction // preamble - uint32_t reg = 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) { @@ -367,39 +370,41 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t //--------------------------------------------------------------------+ bool hcd_init(uint8_t rhport) { - pico_trace("hcd_init %d\n", rhport); - assert(rhport == 0); + (void) rhport; + pico_trace("hcd_init %d\n", rhport); + assert(rhport == 0); - // Reset any previous state - rp2040_usb_init(); + // Reset any previous state + rp2040_usb_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; + // 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; - irq_add_shared_handler(USBCTRL_IRQ, hcd_rp2040_irq, PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY); + irq_add_shared_handler(USBCTRL_IRQ, hcd_rp2040_irq, PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY); - // clear epx and interrupt eps - memset(&ep_pool, 0, sizeof(ep_pool)); + // clear epx and interrupt eps + memset(&ep_pool, 0, sizeof(ep_pool)); - // Enable in host mode with SOF / Keep alive on - usb_hw->main_ctrl = USB_MAIN_CTRL_CONTROLLER_EN_BITS | USB_MAIN_CTRL_HOST_NDEVICE_BITS; - usb_hw->sie_ctrl = SIE_CTRL_BASE; - usb_hw->inte = USB_INTE_BUFF_STATUS_BITS | - USB_INTE_HOST_CONN_DIS_BITS | - USB_INTE_HOST_RESUME_BITS | - USB_INTE_STALL_BITS | - USB_INTE_TRANS_COMPLETE_BITS | - USB_INTE_ERROR_RX_TIMEOUT_BITS | - USB_INTE_ERROR_DATA_SEQ_BITS ; + // Enable in host mode with SOF / Keep alive on + usb_hw->main_ctrl = USB_MAIN_CTRL_CONTROLLER_EN_BITS | USB_MAIN_CTRL_HOST_NDEVICE_BITS; + usb_hw->sie_ctrl = SIE_CTRL_BASE; + usb_hw->inte = USB_INTE_BUFF_STATUS_BITS | + USB_INTE_HOST_CONN_DIS_BITS | + USB_INTE_HOST_RESUME_BITS | + USB_INTE_STALL_BITS | + USB_INTE_TRANS_COMPLETE_BITS | + USB_INTE_ERROR_RX_TIMEOUT_BITS | + USB_INTE_ERROR_DATA_SEQ_BITS ; - return true; + return true; } void hcd_port_reset(uint8_t rhport) { - pico_trace("hcd_port_reset\n"); - assert(rhport == 0); - // TODO: Nothing to do here yet. Perhaps need to reset some state? + (void) rhport; + pico_trace("hcd_port_reset\n"); + assert(rhport == 0); + // TODO: Nothing to do here yet. Perhaps need to reset some state? } void hcd_port_reset_end(uint8_t rhport) @@ -409,25 +414,27 @@ void hcd_port_reset_end(uint8_t rhport) bool hcd_port_connect_status(uint8_t rhport) { - pico_trace("hcd_port_connect_status\n"); - assert(rhport == 0); - return usb_hw->sie_status & USB_SIE_STATUS_SPEED_BITS; + (void) rhport; + pico_trace("hcd_port_connect_status\n"); + assert(rhport == 0); + return usb_hw->sie_status & USB_SIE_STATUS_SPEED_BITS; } tusb_speed_t hcd_port_speed_get(uint8_t rhport) { - assert(rhport == 0); - // TODO: Should enumval this register - switch (dev_speed()) - { - case 1: - return TUSB_SPEED_LOW; - case 2: - return TUSB_SPEED_FULL; - default: - panic("Invalid speed\n"); - return TUSB_SPEED_INVALID; - } + (void) rhport; + assert(rhport == 0); + // TODO: Should enumval this register + switch (dev_speed()) + { + case 1: + return TUSB_SPEED_LOW; + case 2: + return TUSB_SPEED_FULL; + default: + panic("Invalid speed\n"); + return TUSB_SPEED_INVALID; + } } // Close all opened endpoint belong to this device @@ -465,15 +472,17 @@ uint32_t hcd_frame_number(uint8_t rhport) void hcd_int_enable(uint8_t rhport) { - assert(rhport == 0); - irq_set_enabled(USBCTRL_IRQ, true); + (void) rhport; + assert(rhport == 0); + irq_set_enabled(USBCTRL_IRQ, true); } void hcd_int_disable(uint8_t 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); + (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); } //--------------------------------------------------------------------+ @@ -488,6 +497,7 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const // Allocated differently based on if it's an interrupt endpoint or not struct hw_endpoint *ep = _hw_endpoint_allocate(ep_desc->bmAttributes.xfer); + TU_ASSERT(ep); _hw_endpoint_init(ep, dev_addr, @@ -510,7 +520,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * // Get appropriate ep. Either EPX or interrupt endpoint struct hw_endpoint *ep = get_dev_ep(dev_addr, ep_addr); - assert(ep); + TU_ASSERT(ep); // EP should be inactive assert(!ep->active); @@ -532,7 +542,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * // That has set up buffer control, endpoint control etc // for host we have to initiate the transfer - usb_hw->dev_addr_ctrl = dev_addr | (ep_num << USB_ADDR_ENDP_ENDPOINT_LSB); + usb_hw->dev_addr_ctrl = (uint32_t) (dev_addr | (ep_num << USB_ADDR_ENDP_ENDPOINT_LSB)); uint32_t flags = USB_SIE_CTRL_START_TRANS_BITS | SIE_CTRL_BASE | (ep_dir ? USB_SIE_CTRL_RECEIVE_DATA_BITS : USB_SIE_CTRL_SEND_DATA_BITS); @@ -556,11 +566,12 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warray-bounds" #pragma GCC diagnostic ignored "-Wstringop-overflow" - memcpy((void*)&usbh_dpram->setup_packet[0], setup_packet, 8); + memcpy((void*) (uintptr_t) &usbh_dpram->setup_packet[0], setup_packet, 8); #pragma GCC diagnostic pop // Configure EP0 struct with setup info for the trans complete struct hw_endpoint *ep = _hw_endpoint_allocate(0); + TU_ASSERT(ep); // EPX should be inactive assert(!ep->active); From dd7a17c34511e79bc259634f4fa157e7ddf98fd1 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 27 Jun 2022 17:53:42 +0700 Subject: [PATCH 399/504] prevent error on specific warnings for net lwip & dual example for rp2040 --- examples/device/net_lwip_webserver/CMakeLists.txt | 6 ++++++ .../dual/host_hid_to_device_cdc/CMakeLists.txt | 15 +++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/examples/device/net_lwip_webserver/CMakeLists.txt b/examples/device/net_lwip_webserver/CMakeLists.txt index 5bb091a4f..beaa9ad99 100644 --- a/examples/device/net_lwip_webserver/CMakeLists.txt +++ b/examples/device/net_lwip_webserver/CMakeLists.txt @@ -72,6 +72,12 @@ if (EXISTS ${TOP}/lib/lwip/src) # Example common such as compiler warnings include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + # due to warnings from other net source, we need to prevent error from some of the warnings options + target_compile_options(${PROJECT} PUBLIC + -Wno-error=null-dereference + -Wno-error=conversion + ) + # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) diff --git a/examples/dual/host_hid_to_device_cdc/CMakeLists.txt b/examples/dual/host_hid_to_device_cdc/CMakeLists.txt index cd6f16339..909ee423f 100644 --- a/examples/dual/host_hid_to_device_cdc/CMakeLists.txt +++ b/examples/dual/host_hid_to_device_cdc/CMakeLists.txt @@ -24,8 +24,19 @@ target_include_directories(${PROJECT} PUBLIC ) # Example common such as compiler warnings -# skip extra warnings since pio-usb still has some warnings to fix -#include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) +include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) + +# due to warnings from other net source, we need to prevent error from some of the warnings options +target_compile_options(${PROJECT} PUBLIC + -Wno-error=shadow + -Wno-error=cast-align + -Wno-error=cast-qual + -Wno-error=redundant-decls + -Wno-error=sign-conversion + -Wno-error=conversion + -Wno-error=sign-compare + -Wno-error=unused-function + ) # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. From 9c56f7011171ff649a821fe87a3ee477299fa860 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 27 Jun 2022 20:30:47 +0700 Subject: [PATCH 400/504] suppress error with net example --- examples/device/net_lwip_webserver/CMakeLists.txt | 2 ++ examples/make.mk | 3 ++- src/class/net/ecm_rndis_device.c | 6 +++--- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/examples/device/net_lwip_webserver/CMakeLists.txt b/examples/device/net_lwip_webserver/CMakeLists.txt index beaa9ad99..0f41b888a 100644 --- a/examples/device/net_lwip_webserver/CMakeLists.txt +++ b/examples/device/net_lwip_webserver/CMakeLists.txt @@ -76,6 +76,8 @@ if (EXISTS ${TOP}/lib/lwip/src) target_compile_options(${PROJECT} PUBLIC -Wno-error=null-dereference -Wno-error=conversion + -Wno-error=sign-conversion + -Wno-error=sign-compare ) # Configure compilation flags and libraries for the example... see the corresponding function diff --git a/examples/make.mk b/examples/make.mk index fa909ddca..27e1db38c 100644 --- a/examples/make.mk +++ b/examples/make.mk @@ -113,7 +113,8 @@ CFLAGS += \ -Wunused \ -Wredundant-decls -# -Wconversion \ +# conversion is too strict for most mcu driver, may be disable sign/int/arith-conversion +# -Wconversion # Debugging/Optimization ifeq ($(DEBUG), 1) diff --git a/src/class/net/ecm_rndis_device.c b/src/class/net/ecm_rndis_device.c index d85a3f778..5f316762f 100644 --- a/src/class/net/ecm_rndis_device.c +++ b/src/class/net/ecm_rndis_device.c @@ -318,11 +318,11 @@ bool netd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t rndis_generic_msg_t *rndis_msg = (rndis_generic_msg_t *) ((void*) notify.rndis_buf); uint32_t msglen = tu_le32toh(rndis_msg->MessageLength); TU_ASSERT(msglen <= sizeof(notify.rndis_buf)); - tud_control_xfer(rhport, request, notify.rndis_buf, msglen); + tud_control_xfer(rhport, request, notify.rndis_buf, (uint16_t) msglen); } else { - tud_control_xfer(rhport, request, notify.rndis_buf, sizeof(notify.rndis_buf)); + tud_control_xfer(rhport, request, notify.rndis_buf, (uint16_t) sizeof(notify.rndis_buf)); } } break; @@ -369,7 +369,7 @@ static void handle_incoming_packet(uint32_t len) } } - if (!tud_network_recv_cb(pnt, size)) + if (!tud_network_recv_cb(pnt, (uint16_t) size)) { /* if a buffer was never handled by user code, we must renew on the user's behalf */ tud_network_recv_renew(); From 25580b4fe9acd1d9f9f12cbfdd29037669376a8d Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 27 Jun 2022 21:05:41 +0700 Subject: [PATCH 401/504] use forloop to avoid -Warray-bounds with host setup packet --- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 13e7778ea..e9118c6a3 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -563,11 +563,10 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet (void) rhport; // Copy data into setup packet buffer -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Warray-bounds" -#pragma GCC diagnostic ignored "-Wstringop-overflow" - memcpy((void*) (uintptr_t) &usbh_dpram->setup_packet[0], setup_packet, 8); -#pragma GCC diagnostic pop + for(uint8_t i=0; i<8; i++) + { + usbh_dpram->setup_packet[i] = setup_packet[i]; + } // Configure EP0 struct with setup info for the trans complete struct hw_endpoint *ep = _hw_endpoint_allocate(0); From bc4da2047bf73f81cfcd6daa9bd07901dcdff3c9 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Mon, 27 Jun 2022 20:31:44 +0200 Subject: [PATCH 402/504] samd: Fix a lock-up situation at high traffic. This PR fixes a transmit lock-up, which happens, when data is received and sent at the sime time at moderate to high speeds, like code which just echoes incoming data. In my case, an issue was reported here: https://github.com/micropython/micropython/issues/8521 --- src/portable/microchip/samd/dcd_samd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/portable/microchip/samd/dcd_samd.c b/src/portable/microchip/samd/dcd_samd.c index 20dbde0f4..22fe32407 100644 --- a/src/portable/microchip/samd/dcd_samd.c +++ b/src/portable/microchip/samd/dcd_samd.c @@ -286,14 +286,14 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t { bank->PCKSIZE.bit.MULTI_PACKET_SIZE = total_bytes; bank->PCKSIZE.bit.BYTE_COUNT = 0; - ep->EPSTATUSCLR.reg |= USB_DEVICE_EPSTATUSCLR_BK0RDY; - ep->EPINTFLAG.reg |= USB_DEVICE_EPINTFLAG_TRFAIL0; + ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK0RDY; + ep->EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRFAIL0; } else { bank->PCKSIZE.bit.MULTI_PACKET_SIZE = 0; bank->PCKSIZE.bit.BYTE_COUNT = total_bytes; - ep->EPSTATUSSET.reg |= USB_DEVICE_EPSTATUSSET_BK1RDY; - ep->EPINTFLAG.reg |= USB_DEVICE_EPINTFLAG_TRFAIL1; + ep->EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK1RDY; + ep->EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRFAIL1; } return true; From 4057c2d8d96a364329d14d3a4b2c237f388cfdc2 Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Mon, 27 Jun 2022 22:39:10 +0100 Subject: [PATCH 403/504] rework suppress_tinyusb_warnings * gcc 9.2.1 has some spurious -Wconversion warnings * cmake 3.18 and above require set_target_properties to be added from the target directory (so added it to all examples) * fixed a few warnings in a couple of examples --- examples/device/cdc_dual_ports/src/main.c | 4 +- examples/device/hid_composite/src/main.c | 2 +- hw/bsp/rp2040/family.cmake | 46 ++++++++++++++--------- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/examples/device/cdc_dual_ports/src/main.c b/examples/device/cdc_dual_ports/src/main.c index 6053a3b81..d4d07dcd6 100644 --- a/examples/device/cdc_dual_ports/src/main.c +++ b/examples/device/cdc_dual_ports/src/main.c @@ -60,12 +60,12 @@ static void echo_serial_port(uint8_t itf, uint8_t buf[], uint32_t count) if (itf == 0) { // echo back 1st port as lower case - if (isupper(buf[i])) buf[i] += 'a' - 'A'; + if (isupper(buf[i])) buf[i] = (uint8_t) (buf[i] + 'a' - 'A'); } else { // echo back 2nd port as upper case - if (islower(buf[i])) buf[i] -= 'a' - 'A'; + if (islower(buf[i])) buf[i] = (uint8_t) (buf[i] - 'a' - 'A'); } tud_cdc_n_write_char(itf, buf[i]); diff --git a/examples/device/hid_composite/src/main.c b/examples/device/hid_composite/src/main.c index bc2347ab8..cc3566ac1 100644 --- a/examples/device/hid_composite/src/main.c +++ b/examples/device/hid_composite/src/main.c @@ -230,7 +230,7 @@ void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint8_t (void) instance; (void) len; - uint8_t next_report_id = report[0] + 1; + uint8_t next_report_id = (uint8_t)(report[0] + 1); if (next_report_id < REPORT_ID_COUNT) { diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index ed7041e4e..794d02325 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -150,11 +150,13 @@ if (NOT TARGET _rp2040_family_inclusion_marker) function(family_configure_device_example TARGET) family_configure_target(${TARGET}) target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_device) + suppress_tinyusb_warnings() endfunction() function(family_configure_host_example TARGET) family_configure_target(${TARGET}) target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_host) + suppress_tinyusb_warnings() endfunction() function(family_add_pico_pio_usb TARGET) @@ -165,6 +167,7 @@ if (NOT TARGET _rp2040_family_inclusion_marker) family_configure_target(${TARGET}) # require tinyusb_pico_pio_usb target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_device tinyusb_host tinyusb_pico_pio_usb ) + suppress_tinyusb_warnings() endfunction() function(check_and_add_pico_pio_usb_support) @@ -232,25 +235,34 @@ if (NOT TARGET _rp2040_family_inclusion_marker) # This method must be called from the project scope to suppress known warnings in TinyUSB source files function(suppress_tinyusb_warnings) - set_source_files_properties( - ${PICO_TINYUSB_PATH}/src/device/usbd.c + # some of these are pretty silly warnings only occurring in some older GCC versions + set(CONVERSION_WARNING_FILES + ${PICO_TINYUSB_PATH}/src/tusb.c + ${PICO_TINYUSB_PATH}/src/common/tusb_fifo.c + ${PICO_TINYUSB_PATH}/src/device/usbd.c + ${PICO_TINYUSB_PATH}/src/device/usbd_control.c + ${PICO_TINYUSB_PATH}/src/host/usbh.c + ${PICO_TINYUSB_PATH}/src/class/cdc/cdc_device.c + ${PICO_TINYUSB_PATH}/src/class/cdc/cdc_host.c + ${PICO_TINYUSB_PATH}/src/class/hid/hid_device.c + ${PICO_TINYUSB_PATH}/src/class/hid/hid_host.c + ${PICO_TINYUSB_PATH}/src/class/audio/audio_device.c + ${PICO_TINYUSB_PATH}/src/class/dfu/dfu_device.c + ${PICO_TINYUSB_PATH}/src/class/dfu/dfu_rt_device.c + ${PICO_TINYUSB_PATH}/src/class/midi/midi_device.c + ${PICO_TINYUSB_PATH}/src/class/usbtmc/usbtmc_device.c + ${PICO_TINYUSB_PATH}/src/portable/raspberrypi/rp2040/hcd_rp2040.c + ) + foreach(SOURCE_FILE IN LISTS CONVERSION_WARNING_FILES) + set_source_files_properties( + ${SOURCE_FILE} PROPERTIES COMPILE_FLAGS "-Wno-conversion") + endforeach() set_source_files_properties( - ${PICO_TINYUSB_PATH}/src/device/usbd_control.c - PROPERTIES - COMPILE_FLAGS "-Wno-conversion") - set_source_files_properties( - ${PICO_TINYUSB_PATH}/src/class/cdc/cdc_device.c - PROPERTIES - COMPILE_FLAGS "-Wno-conversion") - set_source_files_properties( - ${PICO_TINYUSB_PATH}/src/common/tusb_fifo.c - PROPERTIES - COMPILE_FLAGS "-Wno-conversion") - set_source_files_properties( - ${PICO_TINYUSB_PATH}/src/tusb.c - PROPERTIES - COMPILE_FLAGS "-Wno-conversion") + ${PICO_TINYUSB_PATH}/src/portable/raspberrypi/rp2040/rp2040_usb.c + PROPERTIES + COMPILE_FLAGS "-Wno-stringop-overflow -Wno-array-bounds" + ) endfunction() endif() From 898b52be45f476d7062d50fed722d92f0dccf4ae Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 28 Jun 2022 16:27:44 +0700 Subject: [PATCH 404/504] update rp2040 warnings - remove "-Wno-stringop-overflow -Wno-array-bounds" - skip -Wconversion for gcc 9 and prior - suppress_tinyusb_warnings only when building with gcc 9 and below --- examples/device/cdc_dual_ports/src/main.c | 6 ++- examples/device/hid_composite/src/main.c | 2 +- examples/example.cmake | 6 +++ hw/bsp/rp2040/family.cmake | 55 +++++++++++------------ 4 files changed, 37 insertions(+), 32 deletions(-) diff --git a/examples/device/cdc_dual_ports/src/main.c b/examples/device/cdc_dual_ports/src/main.c index d4d07dcd6..0264f0566 100644 --- a/examples/device/cdc_dual_ports/src/main.c +++ b/examples/device/cdc_dual_ports/src/main.c @@ -55,17 +55,19 @@ int main(void) // with Serial0 as all lower case, Serial1 as all upper case static void echo_serial_port(uint8_t itf, uint8_t buf[], uint32_t count) { + uint8_t const case_diff = 'a' - 'A'; + for(uint32_t i=0; i Date: Wed, 29 Jun 2022 07:28:35 +0100 Subject: [PATCH 405/504] Fix actual compiler warning on gcc 10.3.1 --- src/tusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tusb.c b/src/tusb.c index 709bb7d48..c3787ff8f 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -295,7 +295,7 @@ void tu_print_mem(void const *buf, uint32_t count, uint8_t indent) // fill up last row to 16 for printing ascii const uint32_t remain = count%16; - uint8_t nback = (remain ? remain : 16); + uint8_t nback = (uint8_t)(remain ? remain : 16); if ( remain ) { From 8fe9022a6e6dea785092f4e0dff8180f1f0d4d86 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 29 Jun 2022 14:06:44 +0700 Subject: [PATCH 406/504] fix buid_board.py script --- hw/bsp/ea4088qs/ea4088qs.c | 4 +-- hw/bsp/frdm_k32l2b/board.mk | 2 +- hw/bsp/frdm_kl25z/board.mk | 2 +- hw/bsp/kuiic/kuiic.c | 2 +- hw/bsp/lpcxpresso11u37/board.mk | 2 +- hw/bsp/lpcxpresso1347/board.mk | 2 +- hw/bsp/nutiny_nuc121s/board.mk | 3 ++ hw/bsp/nutiny_nuc125s/board.mk | 3 ++ hw/bsp/nutiny_nuc126v/board.mk | 3 ++ hw/bsp/nutiny_sdk_nuc505/board.mk | 3 ++ hw/bsp/same70_qmtech/board.mk | 2 +- hw/bsp/same70_xplained/board.mk | 2 +- hw/bsp/samg55xplained/board.mk | 2 +- hw/bsp/spresense/board.mk | 3 +- hw/bsp/stm32l0538disco/board.mk | 2 +- src/portable/synopsys/dwc2/dwc2_stm32.h | 3 ++ tools/build_family.py | 2 +- tools/build_utils.py | 44 +++++++++++++++---------- 18 files changed, 55 insertions(+), 31 deletions(-) diff --git a/hw/bsp/ea4088qs/ea4088qs.c b/hw/bsp/ea4088qs/ea4088qs.c index fa905b2f9..7150ed393 100644 --- a/hw/bsp/ea4088qs/ea4088qs.c +++ b/hw/bsp/ea4088qs/ea4088qs.c @@ -33,11 +33,11 @@ void USB_IRQHandler(void) { #if CFG_TUD_ENABLED - tuh_int_handler(0); + tud_int_handler(0); #endif #if CFG_TUH_ENABLED - tud_int_handler(0); + tuh_int_handler(0); #endif } diff --git a/hw/bsp/frdm_k32l2b/board.mk b/hw/bsp/frdm_k32l2b/board.mk index 56df553da..a737eb360 100644 --- a/hw/bsp/frdm_k32l2b/board.mk +++ b/hw/bsp/frdm_k32l2b/board.mk @@ -9,7 +9,7 @@ CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_K32L2BXX # mcu driver cause following warnings -CFLAGS += -Wno-error=unused-parameter +CFLAGS += -Wno-error=unused-parameter -Wno-error=redundant-decls MCU_DIR = $(SDK_DIR)/devices/K32L2B31A diff --git a/hw/bsp/frdm_kl25z/board.mk b/hw/bsp/frdm_kl25z/board.mk index 3585b8b03..6a72d516b 100644 --- a/hw/bsp/frdm_kl25z/board.mk +++ b/hw/bsp/frdm_kl25z/board.mk @@ -14,7 +14,7 @@ LDFLAGS += \ -Wl,--defsym,__heap_size__=0 # mcu driver cause following warnings -CFLAGS += -Wno-error=unused-parameter -Wno-error=format +CFLAGS += -Wno-error=unused-parameter -Wno-error=format -Wno-error=redundant-decls MCU_DIR = $(SDK_DIR)/devices/MKL25Z4 diff --git a/hw/bsp/kuiic/kuiic.c b/hw/bsp/kuiic/kuiic.c index 737ef3f5c..7aaa9e03c 100644 --- a/hw/bsp/kuiic/kuiic.c +++ b/hw/bsp/kuiic/kuiic.c @@ -45,7 +45,7 @@ * Variables ******************************************************************************/ /* System clock frequency. */ -extern uint32_t SystemCoreClock; +// extern uint32_t SystemCoreClock; /******************************************************************************* * Variables for BOARD_BootClockRUN configuration diff --git a/hw/bsp/lpcxpresso11u37/board.mk b/hw/bsp/lpcxpresso11u37/board.mk index b736eebe1..be6d2ed52 100644 --- a/hw/bsp/lpcxpresso11u37/board.mk +++ b/hw/bsp/lpcxpresso11u37/board.mk @@ -15,7 +15,7 @@ CFLAGS += \ -DCFG_TUSB_MEM_ALIGN='__attribute__((aligned(64)))' # mcu driver cause following warnings -CFLAGS += -Wno-error=strict-prototypes -Wno-error=unused-parameter +CFLAGS += -Wno-error=strict-prototypes -Wno-error=unused-parameter -Wno-error=redundant-decls MCU_DIR = hw/mcu/nxp/lpcopen/lpc11uxx/lpc_chip_11uxx diff --git a/hw/bsp/lpcxpresso1347/board.mk b/hw/bsp/lpcxpresso1347/board.mk index 62135c274..bf9c97c82 100644 --- a/hw/bsp/lpcxpresso1347/board.mk +++ b/hw/bsp/lpcxpresso1347/board.mk @@ -15,7 +15,7 @@ CFLAGS += \ -DCFG_TUSB_MEM_ALIGN='__attribute__((aligned(64)))' # startup.c and lpc_types.h cause following errors -CFLAGS += -Wno-error=strict-prototypes +CFLAGS += -Wno-error=strict-prototypes -Wno-error=redundant-decls MCU_DIR = hw/mcu/nxp/lpcopen/lpc13xx/lpc_chip_13xx diff --git a/hw/bsp/nutiny_nuc121s/board.mk b/hw/bsp/nutiny_nuc121s/board.mk index ff1d5aa3a..ad2ee1ea0 100644 --- a/hw/bsp/nutiny_nuc121s/board.mk +++ b/hw/bsp/nutiny_nuc121s/board.mk @@ -10,6 +10,9 @@ CFLAGS += \ -DCFG_EXAMPLE_MSC_READONLY \ -DCFG_TUSB_MCU=OPT_MCU_NUC121 +# mcu driver cause following warnings +CFLAGS += -Wno-error=redundant-decls + # All source paths should be relative to the top level. LD_FILE = hw/bsp/$(BOARD)/nuc121_flash.ld diff --git a/hw/bsp/nutiny_nuc125s/board.mk b/hw/bsp/nutiny_nuc125s/board.mk index bb56e42ab..000c8cd95 100644 --- a/hw/bsp/nutiny_nuc125s/board.mk +++ b/hw/bsp/nutiny_nuc125s/board.mk @@ -10,6 +10,9 @@ CFLAGS += \ -DCFG_EXAMPLE_MSC_READONLY \ -DCFG_TUSB_MCU=OPT_MCU_NUC121 +# mcu driver cause following warnings +CFLAGS += -Wno-error=redundant-decls + # All source paths should be relative to the top level. LD_FILE = hw/bsp/$(BOARD)/nuc125_flash.ld diff --git a/hw/bsp/nutiny_nuc126v/board.mk b/hw/bsp/nutiny_nuc126v/board.mk index 4f0ebf201..0dcd897cb 100644 --- a/hw/bsp/nutiny_nuc126v/board.mk +++ b/hw/bsp/nutiny_nuc126v/board.mk @@ -11,6 +11,9 @@ CFLAGS += \ -D__CORTEX_SC=0 \ -DCFG_TUSB_MCU=OPT_MCU_NUC126 +# mcu driver cause following warnings +CFLAGS += -Wno-error=redundant-decls + # All source paths should be relative to the top level. LD_FILE = hw/bsp/$(BOARD)/nuc126_flash.ld diff --git a/hw/bsp/nutiny_sdk_nuc505/board.mk b/hw/bsp/nutiny_sdk_nuc505/board.mk index e8514347e..f27577e36 100644 --- a/hw/bsp/nutiny_sdk_nuc505/board.mk +++ b/hw/bsp/nutiny_sdk_nuc505/board.mk @@ -9,6 +9,9 @@ CFLAGS += \ -mfpu=fpv4-sp-d16 \ -DCFG_TUSB_MCU=OPT_MCU_NUC505 +# mcu driver cause following warnings +CFLAGS += -Wno-error=redundant-decls + # All source paths should be relative to the top level. LD_FILE = hw/bsp/$(BOARD)/nuc505_flashtoram.ld diff --git a/hw/bsp/same70_qmtech/board.mk b/hw/bsp/same70_qmtech/board.mk index ba7088e44..2aa09f5dd 100644 --- a/hw/bsp/same70_qmtech/board.mk +++ b/hw/bsp/same70_qmtech/board.mk @@ -11,7 +11,7 @@ CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_SAMX7X # suppress following warnings from mcu driver -CFLAGS += -Wno-error=unused-parameter -Wno-error=cast-align -Wno-error=cast-qual +CFLAGS += -Wno-error=unused-parameter -Wno-error=cast-align -Wno-error=cast-qual -Wno-error=redundant-decls ASF_DIR = hw/mcu/microchip/same70 diff --git a/hw/bsp/same70_xplained/board.mk b/hw/bsp/same70_xplained/board.mk index cb2decf50..cbc51e6b0 100644 --- a/hw/bsp/same70_xplained/board.mk +++ b/hw/bsp/same70_xplained/board.mk @@ -11,7 +11,7 @@ CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_SAMX7X # suppress following warnings from mcu driver -CFLAGS += -Wno-error=unused-parameter -Wno-error=cast-align -Wno-error=cast-qual +CFLAGS += -Wno-error=unused-parameter -Wno-error=cast-align -Wno-error=cast-qual -Wno-error=redundant-decls ASF_DIR = hw/mcu/microchip/same70 diff --git a/hw/bsp/samg55xplained/board.mk b/hw/bsp/samg55xplained/board.mk index deff6944c..d0d0ade01 100644 --- a/hw/bsp/samg55xplained/board.mk +++ b/hw/bsp/samg55xplained/board.mk @@ -12,7 +12,7 @@ CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_SAMG # suppress following warnings from mcu driver -CFLAGS += -Wno-error=undef -Wno-error=cast-qual -Wno-error=null-dereference +CFLAGS += -Wno-error=undef -Wno-error=cast-qual -Wno-error=null-dereference -Wno-error=redundant-decls ASF_DIR = hw/mcu/microchip/samg55 diff --git a/hw/bsp/spresense/board.mk b/hw/bsp/spresense/board.mk index ba291e817..78d7f6a66 100644 --- a/hw/bsp/spresense/board.mk +++ b/hw/bsp/spresense/board.mk @@ -34,8 +34,9 @@ CFLAGS += \ -Wno-error=unused-parameter \ -DCFG_TUSB_MCU=OPT_MCU_CXD56 \ +# suppress following warnings from mcu driver # lwip/src/core/raw.c:334:43: error: declaration of 'recv' shadows a global declaration -CFLAGS += -Wno-error=shadow +CFLAGS += -Wno-error=shadow -Wno-error=redundant-decls SPRESENSE_SDK = $(TOP)/hw/mcu/sony/cxd56/spresense-exported-sdk diff --git a/hw/bsp/stm32l0538disco/board.mk b/hw/bsp/stm32l0538disco/board.mk index e19101d64..69f09075a 100644 --- a/hw/bsp/stm32l0538disco/board.mk +++ b/hw/bsp/stm32l0538disco/board.mk @@ -17,7 +17,7 @@ CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_STM32L0 # mcu driver cause following warnings -CFLAGS += -Wno-error=unused-parameter -Wno-error=maybe-uninitialized +CFLAGS += -Wno-error=unused-parameter -Wno-error=maybe-uninitialized -Wno-error=redundant-decls # All source paths should be relative to the top level. LD_FILE = hw/bsp/$(BOARD)/STM32L053C8Tx_FLASH.ld diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index 1d849541e..1187e0d6e 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -43,6 +43,9 @@ #define EP_MAX_FS USB_OTG_FS_MAX_IN_ENDPOINTS #define EP_FIFO_SIZE_FS USB_OTG_FS_TOTAL_FIFO_SIZE + #define EP_MAX_HS USB_OTG_HS_MAX_IN_ENDPOINTS + #define EP_FIFO_SIZE_HS USB_OTG_HS_TOTAL_FIFO_SIZE + #elif CFG_TUSB_MCU == OPT_MCU_STM32F4 #include "stm32f4xx.h" #define EP_MAX_FS USB_OTG_FS_MAX_IN_ENDPOINTS diff --git a/tools/build_family.py b/tools/build_family.py index 095ca4ff7..680411eab 100644 --- a/tools/build_family.py +++ b/tools/build_family.py @@ -48,7 +48,7 @@ all_families.sort() def build_family(example, family): all_boards = [] for entry in os.scandir("hw/bsp/{}/boards".format(family)): - if entry.is_dir(): + if entry.is_dir() and entry.name != 'pico_sdk': all_boards.append(entry.name) filter_with_input(all_boards) all_boards.sort() diff --git a/tools/build_utils.py b/tools/build_utils.py index 299fffa4d..68c2ed98b 100644 --- a/tools/build_utils.py +++ b/tools/build_utils.py @@ -4,26 +4,34 @@ def skip_example(example, board): ex_dir = pathlib.Path('examples/') / example bsp = pathlib.Path("hw/bsp") - board_dir = list(bsp.glob("*/boards/" + board)) - if not board_dir: - # Skip unknown boards - return True - - board_dir = list(board_dir)[0] + # board without family + board_dir = bsp / board - family_dir = board_dir.parent.parent - family = family_dir.name + if board_dir.exists(): + family = "" + mk_contents = "" + else: + # otherwise look into family + board_dir = list(bsp.glob("*/boards/" + board)) + if not board_dir: + # Skip unknown boards + return True + + board_dir = list(board_dir)[0] + + family_dir = board_dir.parent.parent + family = family_dir.name + + # family CMake + family_mk = family_dir / "family.cmake" + + # family.mk + if not family_mk.exists(): + family_mk = family_dir / "family.mk" + + mk_contents = family_mk.read_text() - # family CMake - family_mk = family_dir / "family.cmake" - - # family.mk - if not family_mk.exists(): - family_mk = family_dir / "family.mk" - - mk_contents = family_mk.read_text() - - # Find the mcu + # Find the mcu, first in family mk then board mk if "CFG_TUSB_MCU=OPT_MCU_" not in mk_contents: board_mk = board_dir / "board.cmake" if not board_mk.exists(): From 1e00fe78c7271ecc1b813b10efaf929f4172054e Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 29 Jun 2022 14:07:00 +0700 Subject: [PATCH 407/504] use action gcc --- .github/workflows/build_arm.yml | 48 +++++++-------------------------- 1 file changed, 9 insertions(+), 39 deletions(-) diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml index 6e4702735..27cb9f1f7 100644 --- a/.github/workflows/build_arm.yml +++ b/.github/workflows/build_arm.yml @@ -65,7 +65,7 @@ jobs: - 'xmc4000' steps: - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 - name: Checkout TinyUSB uses: actions/checkout@v3 @@ -79,32 +79,17 @@ jobs: repository: hathach/linkermap path: linkermap - - name: Checkout pico-sdk + - name: Checkout pico-sdk for rp2040 if: matrix.family == 'rp2040' run: | git clone --depth 1 -b develop https://github.com/raspberrypi/pico-sdk ~/pico-sdk echo >> $GITHUB_ENV PICO_SDK_PATH=~/pico-sdk git submodule update --init hw/mcu/raspberry_pi/Pico-PIO-USB - - name: Set Toolchain URL - run: echo >> $GITHUB_ENV TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v10.2.1-1.1/xpack-arm-none-eabi-gcc-10.2.1-1.1-linux-x64.tar.gz - - - name: Cache Toolchain - uses: actions/cache@v2 - id: cache-toolchain + - name: Install ARM GCC + uses: carlosperate/arm-none-eabi-gcc-action@v1 with: - path: ~/cache/ - key: ${{ runner.os }}-21-03-04-${{ env.TOOLCHAIN_URL }} - - - name: Install Toolchain - if: steps.cache-toolchain.outputs.cache-hit != 'true' - run: | - mkdir -p ~/cache/toolchain - wget --progress=dot:mega $TOOLCHAIN_URL -O toolchain.tar.gz - tar -C ~/cache/toolchain -xaf toolchain.tar.gz - - - name: Set Toolchain Path - run: echo >> $GITHUB_PATH `echo ~/cache/toolchain/*/bin` + release: '11.2-2022.02' - name: Build run: python3 tools/build_family.py ${{ matrix.family }} @@ -135,7 +120,7 @@ jobs: steps: - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 - name: Checkout TinyUSB uses: actions/checkout@v3 @@ -143,25 +128,10 @@ jobs: - name: Checkout common submodules in lib run: git submodule update --init lib/FreeRTOS-Kernel lib/lwip - - name: Set Toolchain URL - run: echo >> $GITHUB_ENV TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v10.2.1-1.1/xpack-arm-none-eabi-gcc-10.2.1-1.1-linux-x64.tar.gz - - - name: Cache Toolchain - uses: actions/cache@v2 - id: cache-toolchain + - name: Install ARM GCC + uses: carlosperate/arm-none-eabi-gcc-action@v1 with: - path: ~/cache/ - key: ${{ runner.os }}-21-03-04-${{ env.TOOLCHAIN_URL }} - - - name: Install Toolchain - if: steps.cache-toolchain.outputs.cache-hit != 'true' - run: | - mkdir -p ~/cache/toolchain - wget --progress=dot:mega $TOOLCHAIN_URL -O toolchain.tar.gz - tar -C ~/cache/toolchain -xaf toolchain.tar.gz - - - name: Set Toolchain Path - run: echo >> $GITHUB_PATH `echo ~/cache/toolchain/*/bin` + release: '11.2-2022.02' - name: Build run: python3 tools/build_board.py ${{ matrix.example }} From a62c2640b5217e416ba48aa2011d997cfa7d81a5 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 29 Jun 2022 14:08:01 +0700 Subject: [PATCH 408/504] remove redundant rp2040 boards, all boards supported by pico-sdk already supported --- hw/bsp/rp2040/boards/adafruit_feather_rp2040/board.cmake | 1 - hw/bsp/rp2040/boards/adafruit_itsybitsy_rp2040/board.cmake | 1 - hw/bsp/rp2040/boards/adafruit_qtpy_rp2040/board.cmake | 1 - 3 files changed, 3 deletions(-) delete mode 100644 hw/bsp/rp2040/boards/adafruit_feather_rp2040/board.cmake delete mode 100644 hw/bsp/rp2040/boards/adafruit_itsybitsy_rp2040/board.cmake delete mode 100644 hw/bsp/rp2040/boards/adafruit_qtpy_rp2040/board.cmake diff --git a/hw/bsp/rp2040/boards/adafruit_feather_rp2040/board.cmake b/hw/bsp/rp2040/boards/adafruit_feather_rp2040/board.cmake deleted file mode 100644 index e527a8ce3..000000000 --- a/hw/bsp/rp2040/boards/adafruit_feather_rp2040/board.cmake +++ /dev/null @@ -1 +0,0 @@ -set(PICO_BOARD adafruit_feather_rp2040) \ No newline at end of file diff --git a/hw/bsp/rp2040/boards/adafruit_itsybitsy_rp2040/board.cmake b/hw/bsp/rp2040/boards/adafruit_itsybitsy_rp2040/board.cmake deleted file mode 100644 index 3fd2dd06b..000000000 --- a/hw/bsp/rp2040/boards/adafruit_itsybitsy_rp2040/board.cmake +++ /dev/null @@ -1 +0,0 @@ -set(PICO_BOARD adafruit_itsybitsy_rp2040) \ No newline at end of file diff --git a/hw/bsp/rp2040/boards/adafruit_qtpy_rp2040/board.cmake b/hw/bsp/rp2040/boards/adafruit_qtpy_rp2040/board.cmake deleted file mode 100644 index 469929c51..000000000 --- a/hw/bsp/rp2040/boards/adafruit_qtpy_rp2040/board.cmake +++ /dev/null @@ -1 +0,0 @@ -set(PICO_BOARD adafruit_qtpy_rp2040) \ No newline at end of file From 7949a4ec7c7e9ccc487068a01b84979d02f94875 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 29 Jun 2022 14:12:58 +0700 Subject: [PATCH 409/504] skip freertos example for F1C100S --- .../device/cdc_msc_freertos/.skip.MCU_F1C100S | 0 examples/device/cdc_msc_freertos/skip.txt | 17 +++++++++-------- .../hid_composite_freertos/.skip.MCU_F1C100S | 0 examples/device/hid_composite_freertos/skip.txt | 16 +++++++++------- 4 files changed, 18 insertions(+), 15 deletions(-) delete mode 100644 examples/device/cdc_msc_freertos/.skip.MCU_F1C100S delete mode 100644 examples/device/hid_composite_freertos/.skip.MCU_F1C100S diff --git a/examples/device/cdc_msc_freertos/.skip.MCU_F1C100S b/examples/device/cdc_msc_freertos/.skip.MCU_F1C100S deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/cdc_msc_freertos/skip.txt b/examples/device/cdc_msc_freertos/skip.txt index 7137b78af..1ee51a9d4 100644 --- a/examples/device/cdc_msc_freertos/skip.txt +++ b/examples/device/cdc_msc_freertos/skip.txt @@ -1,10 +1,11 @@ mcu:CXD56 -mcu:MSP430x5xx -mcu:SAMD11 -mcu:VALENTYUSB_EPTRI -mcu:MKL25ZXX -mcu:RP2040 -mcu:SAMX7X +mcu:F1C100S mcu:GD32VF103 -family:broadcom_64bit -family:broadcom_32bit \ No newline at end of file +mcu:MKL25ZXX +mcu:MSP430x5xx +mcu:RP2040 +mcu:SAMD11 +mcu:SAMX7X +mcu:VALENTYUSB_EPTRI +family:broadcom_32bit +family:broadcom_64bit \ No newline at end of file diff --git a/examples/device/hid_composite_freertos/.skip.MCU_F1C100S b/examples/device/hid_composite_freertos/.skip.MCU_F1C100S deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/hid_composite_freertos/skip.txt b/examples/device/hid_composite_freertos/skip.txt index e64187fd4..1ee51a9d4 100644 --- a/examples/device/hid_composite_freertos/skip.txt +++ b/examples/device/hid_composite_freertos/skip.txt @@ -1,9 +1,11 @@ mcu:CXD56 -mcu:MSP430x5xx -mcu:SAMD11 -mcu:VALENTYUSB_EPTRI -mcu:RP2040 -mcu:SAMX7X +mcu:F1C100S mcu:GD32VF103 -family:broadcom_64bit -family:broadcom_32bit \ No newline at end of file +mcu:MKL25ZXX +mcu:MSP430x5xx +mcu:RP2040 +mcu:SAMD11 +mcu:SAMX7X +mcu:VALENTYUSB_EPTRI +family:broadcom_32bit +family:broadcom_64bit \ No newline at end of file From 5a378703fbc30d8e7481abec81bc70a9e25761e6 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 29 Jun 2022 15:05:09 +0700 Subject: [PATCH 410/504] fix end symbol for samx7x and same5x --- examples/device/video_capture/skip.txt | 3 ++- hw/bsp/d5035_01/same51j19a_flash.ld | 1 + hw/mcu/microchip | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/device/video_capture/skip.txt b/examples/device/video_capture/skip.txt index 892a8c6a7..5898664a2 100644 --- a/examples/device/video_capture/skip.txt +++ b/examples/device/video_capture/skip.txt @@ -1,2 +1,3 @@ mcu:MSP430x5xx -mcu:SAMD11 \ No newline at end of file +mcu:NUC121 +mcu:SAMD11 diff --git a/hw/bsp/d5035_01/same51j19a_flash.ld b/hw/bsp/d5035_01/same51j19a_flash.ld index 328d1c72f..a8dd44336 100644 --- a/hw/bsp/d5035_01/same51j19a_flash.ld +++ b/hw/bsp/d5035_01/same51j19a_flash.ld @@ -160,4 +160,5 @@ SECTIONS . = ALIGN(4); _end = . ; + end = .; } diff --git a/hw/mcu/microchip b/hw/mcu/microchip index 58eb37632..9e8b37e30 160000 --- a/hw/mcu/microchip +++ b/hw/mcu/microchip @@ -1 +1 @@ -Subproject commit 58eb3763200ff51a998be5f537acf67299add227 +Subproject commit 9e8b37e307d8404033bb881623a113931e1edf27 From 4da1a9359d7fa9813a01f133f919533184753064 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 29 Jun 2022 15:12:01 +0700 Subject: [PATCH 411/504] fix build with fomu/fomu --- tools/build_utils.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tools/build_utils.py b/tools/build_utils.py index 68c2ed98b..d570d20e3 100644 --- a/tools/build_utils.py +++ b/tools/build_utils.py @@ -3,15 +3,14 @@ import pathlib def skip_example(example, board): ex_dir = pathlib.Path('examples/') / example bsp = pathlib.Path("hw/bsp") - - # board without family - board_dir = bsp / board - if board_dir.exists(): + if (bsp / board / "board.mk").exists(): + # board without family + board_dir = bsp / board family = "" mk_contents = "" else: - # otherwise look into family + # board within family board_dir = list(bsp.glob("*/boards/" + board)) if not board_dir: # Skip unknown boards From 158b3d761d4c0f1da8d60b63d43664e1f52a286d Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 29 Jun 2022 15:27:24 +0700 Subject: [PATCH 412/504] fix xmc4000 build --- hw/bsp/xmc4000/boards/xmc4500_relax/board.mk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hw/bsp/xmc4000/boards/xmc4500_relax/board.mk b/hw/bsp/xmc4000/boards/xmc4500_relax/board.mk index a2c2c5aaf..371adff91 100644 --- a/hw/bsp/xmc4000/boards/xmc4500_relax/board.mk +++ b/hw/bsp/xmc4000/boards/xmc4500_relax/board.mk @@ -2,6 +2,9 @@ MCU_VARIANT = XMC4500 CFLAGS += \ -DXMC4500_F100x1024 \ +# mcu driver cause following warnings +CFLAGS += -Wno-error=stringop-overread + LD_FILE = $(MCU_DIR)/CMSIS/Infineon/COMPONENT_$(MCU_VARIANT)/Source/TOOLCHAIN_GCC_ARM/XMC4500x1024.ld JLINK_DEVICE = XMC4500-1024 From 8d07ea7ce560f2a938c573a0f0487ad3776402c4 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 29 Jun 2022 16:39:19 +0700 Subject: [PATCH 413/504] build_family.py in parallel --- tools/build_family.py | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/tools/build_family.py b/tools/build_family.py index 680411eab..5f03bfc87 100644 --- a/tools/build_family.py +++ b/tools/build_family.py @@ -3,6 +3,7 @@ import glob import sys import subprocess import time +from multiprocessing import Process import build_utils @@ -52,9 +53,15 @@ def build_family(example, family): all_boards.append(entry.name) filter_with_input(all_boards) all_boards.sort() - + + plist = [] for board in all_boards: - build_board(example, board) + p = Process(target=build_board, args=(example, board)) + plist.append(p) + p.start() + + for p in plist: + p.join() def build_board(example, board): global success_count, fail_count, skip_count, exit_status @@ -88,7 +95,6 @@ def build_board(example, board): print(build_result.stdout.decode("utf-8")) def build_size(example, board): - #elf_file = 'examples/device/{}/_build/{}/{}-firmware.elf'.format(example, board, board) elf_file = 'examples/{}/_build/{}/*.elf'.format(example, board) size_output = subprocess.run('size {}'.format(elf_file), shell=True, stdout=subprocess.PIPE).stdout.decode("utf-8") size_list = size_output.split('\n')[1].split('\t') @@ -96,17 +102,18 @@ def build_size(example, board): sram_size = int(size_list[1]) + int(size_list[2]) return (flash_size, sram_size) -print(build_separator) -print(build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) - -for example in all_examples: +if __name__ == '__main__': print(build_separator) - for family in all_families: - build_family(example, family) + print(build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) -total_time = time.monotonic() - total_time -print(build_separator) -print("Build Summary: {} {}, {} {}, {} {} and took {:.2f}s".format(success_count, SUCCEEDED, fail_count, FAILED, skip_count, SKIPPED, total_time)) -print(build_separator) + for example in all_examples: + print(build_separator) + for family in all_families: + build_family(example, family) -sys.exit(exit_status) + total_time = time.monotonic() - total_time + print(build_separator) + print("Build Summary: {} {}, {} {}, {} {} and took {:.2f}s".format(success_count, SUCCEEDED, fail_count, FAILED, skip_count, SKIPPED, total_time)) + print(build_separator) + + sys.exit(exit_status) From d5d5a6437cd73d2ad7b35e73b3ffc9d65aaa9ad3 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 29 Jun 2022 18:23:45 +0700 Subject: [PATCH 414/504] more parallel ci --- tools/build_family.py | 55 ++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/tools/build_family.py b/tools/build_family.py index 5f03bfc87..57a6c4d17 100644 --- a/tools/build_family.py +++ b/tools/build_family.py @@ -3,7 +3,7 @@ import glob import sys import subprocess import time -from multiprocessing import Process +from multiprocessing import Pool import build_utils @@ -11,13 +11,6 @@ SUCCEEDED = "\033[32msucceeded\033[0m" FAILED = "\033[31mfailed\033[0m" SKIPPED = "\033[33mskipped\033[0m" -success_count = 0 -fail_count = 0 -skip_count = 0 -exit_status = 0 - -total_time = time.monotonic() - build_format = '| {:29} | {:30} | {:18} | {:7} | {:6} | {:6} |' build_separator = '-' * 106 @@ -54,46 +47,45 @@ def build_family(example, family): filter_with_input(all_boards) all_boards.sort() - plist = [] - for board in all_boards: - p = Process(target=build_board, args=(example, board)) - plist.append(p) - p.start() - - for p in plist: - p.join() + with Pool(processes=len(all_boards)) as pool: + pool_args = list((map(lambda b, e=example: [e, b], all_boards))) + result = pool.starmap(build_board, pool_args) + return list(map(sum, list(zip(*result)))) def build_board(example, board): - global success_count, fail_count, skip_count, exit_status start_time = time.monotonic() flash_size = "-" sram_size = "-" + # succeeded, failed, skipped + ret = [0, 0, 0] + # Check if board is skipped if build_utils.skip_example(example, board): - success = SKIPPED - skip_count += 1 - print(build_format.format(example, board, success, '-', flash_size, sram_size)) + status = SKIPPED + ret[2] = 1 + print(build_format.format(example, board, status, '-', flash_size, sram_size)) else: #subprocess.run("make -C examples/{} BOARD={} clean".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) build_result = subprocess.run("make -j -C examples/{} BOARD={} all".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) if build_result.returncode == 0: - success = SUCCEEDED - success_count += 1 + status = SUCCEEDED + ret[0] = 1 (flash_size, sram_size) = build_size(example, board) subprocess.run("make -j -C examples/{} BOARD={} copy-artifact".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) else: - exit_status = build_result.returncode - success = FAILED - fail_count += 1 + status = FAILED + ret[1] = 1 build_duration = time.monotonic() - start_time - print(build_format.format(example, board, success, "{:.2f}s".format(build_duration), flash_size, sram_size)) + print(build_format.format(example, board, status, "{:.2f}s".format(build_duration), flash_size, sram_size)) if build_result.returncode != 0: print(build_result.stdout.decode("utf-8")) + return ret + def build_size(example, board): elf_file = 'examples/{}/_build/{}/*.elf'.format(example, board) size_output = subprocess.run('size {}'.format(elf_file), shell=True, stdout=subprocess.PIPE).stdout.decode("utf-8") @@ -103,17 +95,22 @@ def build_size(example, board): return (flash_size, sram_size) if __name__ == '__main__': + # succeeded, failed, skipped + total_result = [0, 0, 0] + print(build_separator) print(build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) + total_time = time.monotonic() for example in all_examples: print(build_separator) for family in all_families: - build_family(example, family) + fret = build_family(example, family) + total_result = list(map(lambda x, y: x+y, total_result, fret)) total_time = time.monotonic() - total_time print(build_separator) - print("Build Summary: {} {}, {} {}, {} {} and took {:.2f}s".format(success_count, SUCCEEDED, fail_count, FAILED, skip_count, SKIPPED, total_time)) + print("Build Summary: {} {}, {} {}, {} {} and took {:.2f}s".format(total_result[0], SUCCEEDED, total_result[1], FAILED, total_result[2], SKIPPED, total_time)) print(build_separator) - sys.exit(exit_status) + sys.exit(total_result[1]) From 8f9ecace4d9fecb14fbf8e8563d2f19334805d4d Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 29 Jun 2022 21:06:02 +0700 Subject: [PATCH 415/504] update build_board.py to parallel build --- tools/build_board.py | 115 +++++++++++++++--------------------------- tools/build_family.py | 96 ++++++++++------------------------- tools/build_utils.py | 66 +++++++++++++++++++++--- 3 files changed, 127 insertions(+), 150 deletions(-) diff --git a/tools/build_board.py b/tools/build_board.py index 4d895329a..62a4ea82f 100644 --- a/tools/build_board.py +++ b/tools/build_board.py @@ -1,8 +1,7 @@ import os -import glob import sys -import subprocess import time +from multiprocessing import Pool import build_utils @@ -10,90 +9,56 @@ SUCCEEDED = "\033[32msucceeded\033[0m" FAILED = "\033[31mfailed\033[0m" SKIPPED = "\033[33mskipped\033[0m" -success_count = 0 -fail_count = 0 -skip_count = 0 -exit_status = 0 - -total_time = time.monotonic() - -build_format = '| {:29} | {:30} | {:18} | {:7} | {:6} | {:6} |' build_separator = '-' * 106 + def filter_with_input(mylist): if len(sys.argv) > 1: input_args = list(set(mylist).intersection(sys.argv)) if len(input_args) > 0: mylist[:] = input_args -# If examples are not specified in arguments, build all -all_examples = [] -for dir1 in os.scandir("examples"): - if dir1.is_dir(): - for entry in os.scandir(dir1.path): - if entry.is_dir(): - all_examples.append(dir1.name + '/' + entry.name) -filter_with_input(all_examples) -all_examples.sort() -# If boards are not specified in arguments, build all -all_boards = [] -for entry in os.scandir("hw/bsp"): - if entry.is_dir() and os.path.exists(entry.path + "/board.mk"): - all_boards.append(entry.name) -filter_with_input(all_boards) -all_boards.sort() +if __name__ == '__main__': + # If examples are not specified in arguments, build all + all_examples = [] + for dir1 in os.scandir("examples"): + if dir1.is_dir(): + for entry in os.scandir(dir1.path): + if entry.is_dir(): + all_examples.append(dir1.name + '/' + entry.name) + filter_with_input(all_examples) + all_examples.sort() -def build_board(example, board): - global success_count, fail_count, skip_count, exit_status - start_time = time.monotonic() - flash_size = "-" - sram_size = "-" + # If boards are not specified in arguments, build all + all_boards = [] + for entry in os.scandir("hw/bsp"): + if entry.is_dir() and os.path.exists(entry.path + "/board.mk"): + all_boards.append(entry.name) + filter_with_input(all_boards) + all_boards.sort() - # Check if board is skipped - if build_utils.skip_example(example, board): - success = SKIPPED - skip_count += 1 - print(build_format.format(example, board, success, '-', flash_size, sram_size)) - else: - subprocess.run("make -C examples/{} BOARD={} clean".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - build_result = subprocess.run("make -j -C examples/{} BOARD={} all".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - - if build_result.returncode == 0: - success = SUCCEEDED - success_count += 1 - (flash_size, sram_size) = build_size(example, board) - else: - exit_status = build_result.returncode - success = FAILED - fail_count += 1 - - build_duration = time.monotonic() - start_time - print(build_format.format(example, board, success, "{:.2f}s".format(build_duration), flash_size, sram_size)) - - if build_result.returncode != 0: - print(build_result.stdout.decode("utf-8")) - -def build_size(example, board): - #elf_file = 'examples/device/{}/_build/{}/{}-firmware.elf'.format(example, board, board) - elf_file = 'examples/{}/_build/{}/*.elf'.format(example, board) - size_output = subprocess.run('size {}'.format(elf_file), shell=True, stdout=subprocess.PIPE).stdout.decode("utf-8") - size_list = size_output.split('\n')[1].split('\t') - flash_size = int(size_list[0]) - sram_size = int(size_list[1]) + int(size_list[2]) - return (flash_size, sram_size) - -print(build_separator) -print(build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) - -for example in all_examples: print(build_separator) - for board in all_boards: - build_board(example, board) + print(build_utils.build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) + total_time = time.monotonic() -total_time = time.monotonic() - total_time -print(build_separator) -print("Build Summary: {} {}, {} {}, {} {} and took {:.2f}s".format(success_count, SUCCEEDED, fail_count, FAILED, skip_count, SKIPPED, total_time)) -print(build_separator) + # succeeded, failed, skipped + total_result = [0, 0, 0] + for example in all_examples: + print(build_separator) + with Pool(processes=os.cpu_count()) as pool: + pool_args = list((map(lambda b, e=example: [e, b], all_boards))) + result = pool.starmap(build_utils.build_example, pool_args) + # sum all element of same index (column sum) + result = list(map(sum, list(zip(*result)))) + + # add to total result + total_result = list(map(lambda x, y: x + y, total_result, result)) -sys.exit(exit_status) + total_time = time.monotonic() - total_time + print(build_separator) + print("Build Summary: {} {}, {} {}, {} {} and took {:.2f}s".format(total_result[0], SUCCEEDED, total_result[1], + FAILED, total_result[2], SKIPPED, total_time)) + print(build_separator) + + sys.exit(total_result[1]) diff --git a/tools/build_family.py b/tools/build_family.py index 57a6c4d17..c6c64d2b3 100644 --- a/tools/build_family.py +++ b/tools/build_family.py @@ -1,7 +1,5 @@ import os -import glob import sys -import subprocess import time from multiprocessing import Pool @@ -11,33 +9,15 @@ SUCCEEDED = "\033[32msucceeded\033[0m" FAILED = "\033[31mfailed\033[0m" SKIPPED = "\033[33mskipped\033[0m" -build_format = '| {:29} | {:30} | {:18} | {:7} | {:6} | {:6} |' build_separator = '-' * 106 + def filter_with_input(mylist): if len(sys.argv) > 1: input_args = list(set(mylist).intersection(sys.argv)) if len(input_args) > 0: mylist[:] = input_args -# If examples are not specified in arguments, build all -all_examples = [] -for dir1 in os.scandir("examples"): - if dir1.is_dir(): - for entry in os.scandir(dir1.path): - if entry.is_dir(): - all_examples.append(dir1.name + '/' + entry.name) -filter_with_input(all_examples) -all_examples.sort() - -# If family are not specified in arguments, build all -all_families = [] -for entry in os.scandir("hw/bsp"): - if entry.is_dir() and os.path.isdir(entry.path + "/boards") and entry.name not in ("esp32s2", "esp32s3"): - all_families.append(entry.name) - -filter_with_input(all_families) -all_families.sort() def build_family(example, family): all_boards = [] @@ -47,70 +27,48 @@ def build_family(example, family): filter_with_input(all_boards) all_boards.sort() - with Pool(processes=len(all_boards)) as pool: + with Pool(processes=os.cpu_count()) as pool: pool_args = list((map(lambda b, e=example: [e, b], all_boards))) - result = pool.starmap(build_board, pool_args) + result = pool.starmap(build_utils.build_example, pool_args) + # sum all element of same index (column sum) return list(map(sum, list(zip(*result)))) - -def build_board(example, board): - start_time = time.monotonic() - flash_size = "-" - sram_size = "-" - # succeeded, failed, skipped - ret = [0, 0, 0] - - # Check if board is skipped - if build_utils.skip_example(example, board): - status = SKIPPED - ret[2] = 1 - print(build_format.format(example, board, status, '-', flash_size, sram_size)) - else: - #subprocess.run("make -C examples/{} BOARD={} clean".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - build_result = subprocess.run("make -j -C examples/{} BOARD={} all".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - - if build_result.returncode == 0: - status = SUCCEEDED - ret[0] = 1 - (flash_size, sram_size) = build_size(example, board) - subprocess.run("make -j -C examples/{} BOARD={} copy-artifact".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - else: - status = FAILED - ret[1] = 1 - - build_duration = time.monotonic() - start_time - print(build_format.format(example, board, status, "{:.2f}s".format(build_duration), flash_size, sram_size)) - - if build_result.returncode != 0: - print(build_result.stdout.decode("utf-8")) - - return ret - -def build_size(example, board): - elf_file = 'examples/{}/_build/{}/*.elf'.format(example, board) - size_output = subprocess.run('size {}'.format(elf_file), shell=True, stdout=subprocess.PIPE).stdout.decode("utf-8") - size_list = size_output.split('\n')[1].split('\t') - flash_size = int(size_list[0]) - sram_size = int(size_list[1]) + int(size_list[2]) - return (flash_size, sram_size) if __name__ == '__main__': - # succeeded, failed, skipped - total_result = [0, 0, 0] + # If examples are not specified in arguments, build all + all_examples = [] + for dir1 in os.scandir("examples"): + if dir1.is_dir(): + for entry in os.scandir(dir1.path): + if entry.is_dir(): + all_examples.append(dir1.name + '/' + entry.name) + filter_with_input(all_examples) + all_examples.sort() + + # If family are not specified in arguments, build all + all_families = [] + for entry in os.scandir("hw/bsp"): + if entry.is_dir() and os.path.isdir(entry.path + "/boards") and entry.name not in ("esp32s2", "esp32s3"): + all_families.append(entry.name) + filter_with_input(all_families) + all_families.sort() print(build_separator) - print(build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) + print(build_utils.build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) total_time = time.monotonic() + # succeeded, failed, skipped + total_result = [0, 0, 0] for example in all_examples: print(build_separator) for family in all_families: fret = build_family(example, family) - total_result = list(map(lambda x, y: x+y, total_result, fret)) + total_result = list(map(lambda x, y: x + y, total_result, fret)) total_time = time.monotonic() - total_time print(build_separator) - print("Build Summary: {} {}, {} {}, {} {} and took {:.2f}s".format(total_result[0], SUCCEEDED, total_result[1], FAILED, total_result[2], SKIPPED, total_time)) + print("Build Summary: {} {}, {} {}, {} {} and took {:.2f}s".format(total_result[0], SUCCEEDED, total_result[1], + FAILED, total_result[2], SKIPPED, total_time)) print(build_separator) sys.exit(total_result[1]) diff --git a/tools/build_utils.py b/tools/build_utils.py index d570d20e3..f457c7986 100644 --- a/tools/build_utils.py +++ b/tools/build_utils.py @@ -1,9 +1,18 @@ +import subprocess import pathlib +import time + +build_format = '| {:29} | {:30} | {:18} | {:7} | {:6} | {:6} |' + +SUCCEEDED = "\033[32msucceeded\033[0m" +FAILED = "\033[31mfailed\033[0m" +SKIPPED = "\033[33mskipped\033[0m" + def skip_example(example, board): ex_dir = pathlib.Path('examples/') / example bsp = pathlib.Path("hw/bsp") - + if (bsp / board / "board.mk").exists(): # board without family board_dir = bsp / board @@ -15,19 +24,19 @@ def skip_example(example, board): if not board_dir: # Skip unknown boards return True - + board_dir = list(board_dir)[0] - + family_dir = board_dir.parent.parent family = family_dir.name - + # family CMake family_mk = family_dir / "family.cmake" - + # family.mk if not family_mk.exists(): family_mk = family_dir / "family.mk" - + mk_contents = family_mk.read_text() # Find the mcu, first in family mk then board mk @@ -66,3 +75,48 @@ def skip_example(example, board): "family:" + family in onlys) return False + + +def build_example(example, board): + start_time = time.monotonic() + flash_size = "-" + sram_size = "-" + + # succeeded, failed, skipped + ret = [0, 0, 0] + + # Check if board is skipped + if skip_example(example, board): + status = SKIPPED + ret[2] = 1 + print(build_format.format(example, board, status, '-', flash_size, sram_size)) + else: + build_result = subprocess.run("make -j -C examples/{} BOARD={} all".format(example, board), shell=True, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + + if build_result.returncode == 0: + status = SUCCEEDED + ret[0] = 1 + (flash_size, sram_size) = build_size(example, board) + subprocess.run("make -j -C examples/{} BOARD={} copy-artifact".format(example, board), shell=True, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + else: + status = FAILED + ret[1] = 1 + + build_duration = time.monotonic() - start_time + print(build_format.format(example, board, status, "{:.2f}s".format(build_duration), flash_size, sram_size)) + + if build_result.returncode != 0: + print(build_result.stdout.decode("utf-8")) + + return ret + + +def build_size(example, board): + elf_file = 'examples/{}/_build/{}/*.elf'.format(example, board) + size_output = subprocess.run('size {}'.format(elf_file), shell=True, stdout=subprocess.PIPE).stdout.decode("utf-8") + size_list = size_output.split('\n')[1].split('\t') + flash_size = int(size_list[0]) + sram_size = int(size_list[1]) + int(size_list[2]) + return (flash_size, sram_size) From 023191be23f736ccebd5eddd75d388ee1edb9e4b Mon Sep 17 00:00:00 2001 From: Pawel Hryniszak Date: Wed, 29 Jun 2022 20:28:22 +0100 Subject: [PATCH 416/504] Let to define CFG_BOARD_UART_BAUDRATE in CMake --- hw/bsp/board.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hw/bsp/board.h b/hw/bsp/board.h index b4e0cb298..339e2e3b5 100644 --- a/hw/bsp/board.h +++ b/hw/bsp/board.h @@ -41,7 +41,10 @@ #include "ansi_escape.h" #include "tusb.h" -#define CFG_BOARD_UART_BAUDRATE 115200 +// Define the default baudrate +#ifndef CFG_BOARD_UART_BAUDRATE +#define CFG_BOARD_UART_BAUDRATE 115200 ///< Default baud rate +#endif //--------------------------------------------------------------------+ // Board Porting API From 9ec92ff97bf5e4b5730925ff591ed9f044d2c847 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 30 Jun 2022 15:45:04 +0700 Subject: [PATCH 417/504] rp2040 enable SOF as resumed signal when remote wakeup --- src/device/usbd.c | 2 +- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 25 +++++++++++++------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 382efa4d1..c199e647e 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -316,7 +316,7 @@ void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback) for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { usbd_class_driver_t const * driver = get_driver(i); - if ( driver->control_xfer_cb == callback ) + if ( driver && driver->control_xfer_cb == callback ) { TU_LOG(USBD_DBG, " %s control complete\r\n", driver->name); return; diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index c6018c515..2003f72fd 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -55,6 +55,9 @@ static uint8_t *next_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 +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) { return &hw_endpoints[num][dir]; @@ -250,6 +253,10 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) if (status & USB_INTF_DEV_SOF_BITS) { handled |= USB_INTF_DEV_SOF_BITS; + + // disable SOF interrupt if it is used for RESUME in remote wakeup + if (!_sof_enable) usb_hw_clear->inte = USB_INTS_DEV_SOF_BITS; + dcd_event_sof(0, usb_hw->sof_rd & USB_SOF_RD_BITS, true); } @@ -411,9 +418,13 @@ void dcd_set_address (__unused uint8_t rhport, __unused uint8_t dev_addr) void dcd_remote_wakeup(__unused uint8_t rhport) { - pico_info("dcd_remote_wakeup %d\n", rhport); - assert(rhport == 0); - usb_hw_set->sie_ctrl = USB_SIE_CTRL_RESUME_BITS; + pico_info("dcd_remote_wakeup %d\n", rhport); + assert(rhport == 0); + + // since RESUME interrupt is not triggered if we are the one initiate + // briefly enable SOF to notify usbd when bus is ready + usb_hw_set->inte = USB_INTS_DEV_SOF_BITS; + usb_hw_set->sie_ctrl = USB_SIE_CTRL_RESUME_BITS; } // disconnect by disabling internal pull-up resistor on D+/D- @@ -434,17 +445,15 @@ void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; - uint32_t inte = usb_hw->inte; + _sof_enable = en; if (en) { - inte |= USB_INTS_DEV_SOF_BITS; + usb_hw_set->inte = USB_INTS_DEV_SOF_BITS; }else { - inte &= ~USB_INTS_DEV_SOF_BITS; + usb_hw_clear->inte = USB_INTS_DEV_SOF_BITS; } - - usb_hw->inte = inte; } /*------------------------------------------------------------------*/ From 60c1750a9bd79e46385680b35e12f116808894f7 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Thu, 30 Jun 2022 22:18:23 +0200 Subject: [PATCH 418/504] mimxrt: Add/change definitions for MIMXRT11XX boards. These are mostly identical to the MIMXRT10XX, with one tiny difference. --- hw/bsp/board_mcu.h | 2 +- src/class/audio/audio_device.c | 3 ++- src/common/tusb_mcu.h | 2 +- src/portable/chipidea/ci_hs/ci_hs_imxrt.h | 5 +++++ src/portable/chipidea/ci_hs/dcd_ci_hs.c | 2 +- src/portable/chipidea/ci_hs/hcd_ci_hs.c | 2 +- src/tusb_option.h | 1 + 7 files changed, 12 insertions(+), 5 deletions(-) diff --git a/hw/bsp/board_mcu.h b/hw/bsp/board_mcu.h index 8202479cb..93b1d595f 100644 --- a/hw/bsp/board_mcu.h +++ b/hw/bsp/board_mcu.h @@ -110,7 +110,7 @@ #elif CFG_TUSB_MCU == OPT_MCU_VALENTYUSB_EPTRI // no header needed -#elif CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX +#elif CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT11XX #include "fsl_device_registers.h" #elif CFG_TUSB_MCU == OPT_MCU_NUC120 diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 6df68c559..ef0f9c4b7 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -66,7 +66,7 @@ // Use ring buffer if it's available, some MCUs need extra RAM requirements #ifndef TUD_AUDIO_PREFER_RING_BUFFER -#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX +#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT11XX #define TUD_AUDIO_PREFER_RING_BUFFER 0 #else #define TUD_AUDIO_PREFER_RING_BUFFER 1 @@ -103,6 +103,7 @@ CFG_TUSB_MCU == OPT_MCU_LPC18XX || \ CFG_TUSB_MCU == OPT_MCU_LPC43XX || \ CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ + CFG_TUSB_MCU == OPT_MCU_MIMXRT11XX || \ CFG_TUSB_MCU == OPT_MCU_MSP432E4 #if TUD_AUDIO_PREFER_RING_BUFFER #define USE_LINEAR_BUFFER 0 diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 383a8d686..37866f2a3 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -75,7 +75,7 @@ // TODO USB0 has 5, USB1 has 6 #define TUP_DCD_ENDPOINT_MAX 6 -#elif TU_CHECK_MCU(OPT_MCU_MIMXRT10XX) +#elif TU_CHECK_MCU(OPT_MCU_MIMXRT10XX, OPT_MCU_MIMXRT11XX) #define TUP_USBIP_CHIPIDEA_HS #define TUP_USBIP_EHCI diff --git a/src/portable/chipidea/ci_hs/ci_hs_imxrt.h b/src/portable/chipidea/ci_hs/ci_hs_imxrt.h index 78ca5a5a2..a2a0c98f4 100644 --- a/src/portable/chipidea/ci_hs/ci_hs_imxrt.h +++ b/src/portable/chipidea/ci_hs/ci_hs_imxrt.h @@ -29,6 +29,11 @@ #include "fsl_device_registers.h" +#if CFG_TUSB_MCU == OPT_MCU_MIMXRT11XX +#define USB1_BASE USB_OTG1_BASE +#define USB2_BASE USB_OTG2_BASE +#endif + static const ci_hs_controller_t _ci_controller[] = { // RT1010 and RT1020 only has 1 USB controller diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c index 41d2f1870..0925215ae 100644 --- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c @@ -34,7 +34,7 @@ #include "device/dcd.h" #include "ci_hs_type.h" -#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX +#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT11XX #include "ci_hs_imxrt.h" #elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX) #include "ci_hs_lpc18_43.h" diff --git a/src/portable/chipidea/ci_hs/hcd_ci_hs.c b/src/portable/chipidea/ci_hs/hcd_ci_hs.c index 221721b0f..39b490f72 100644 --- a/src/portable/chipidea/ci_hs/hcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/hcd_ci_hs.c @@ -29,7 +29,7 @@ // Chipidea Highspeed USB IP implement EHCI for host functionality #if CFG_TUH_ENABLED && \ - (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX) + (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT11XX) //--------------------------------------------------------------------+ // INCLUDE diff --git a/src/tusb_option.h b/src/tusb_option.h index 206d23e72..0749a5e52 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -99,6 +99,7 @@ typedef int make_iso_compilers_happy; // NXP iMX RT #define OPT_MCU_MIMXRT10XX 700 ///< NXP iMX RT10xx +#define OPT_MCU_MIMXRT11XX 701 ///< NXP iMX RT11xx // Nuvoton #define OPT_MCU_NUC121 800 From ec6f56768a03fcc43158b0d429e8b826825d02f7 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Fri, 1 Jul 2022 08:42:46 +0200 Subject: [PATCH 419/504] mimxrt: Change OPT_MCU_MIMXRT1xXX to OPT_MCU_MIMXRT. Which fits both MIMXRT10XX and MIMXRT11XX. --- hw/bsp/board_mcu.h | 2 +- hw/bsp/f1c100s/README.md | 2 +- hw/bsp/imxrt/family.mk | 2 +- src/class/audio/audio_device.c | 5 ++--- src/common/tusb_mcu.h | 2 +- src/portable/chipidea/ci_hs/ci_hs_imxrt.h | 2 +- src/portable/chipidea/ci_hs/dcd_ci_hs.c | 2 +- src/portable/chipidea/ci_hs/hcd_ci_hs.c | 4 ++-- src/portable/nxp/transdimension/dcd_transdimension.c | 6 +++--- src/portable/nxp/transdimension/hcd_transdimension.c | 6 +++--- src/tusb_option.h | 4 ++-- 11 files changed, 18 insertions(+), 19 deletions(-) diff --git a/hw/bsp/board_mcu.h b/hw/bsp/board_mcu.h index 93b1d595f..5c309a21d 100644 --- a/hw/bsp/board_mcu.h +++ b/hw/bsp/board_mcu.h @@ -110,7 +110,7 @@ #elif CFG_TUSB_MCU == OPT_MCU_VALENTYUSB_EPTRI // no header needed -#elif CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT11XX +#elif CFG_TUSB_MCU == OPT_MCU_MIMXRT #include "fsl_device_registers.h" #elif CFG_TUSB_MCU == OPT_MCU_NUC120 diff --git a/hw/bsp/f1c100s/README.md b/hw/bsp/f1c100s/README.md index 325044716..4aa1e153b 100644 --- a/hw/bsp/f1c100s/README.md +++ b/hw/bsp/f1c100s/README.md @@ -17,4 +17,4 @@ Flash: `make BOARD=f1c100s flash` will write the image to SPI flash, and then re ## TODO -* Add F1C100s to `#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX` high speed MCU check in examples (maybe we should extract the logic?) \ No newline at end of file +* Add F1C100s to `#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT` high speed MCU check in examples (maybe we should extract the logic?) \ No newline at end of file diff --git a/hw/bsp/imxrt/family.mk b/hw/bsp/imxrt/family.mk index 0a55b740b..846ecd255 100644 --- a/hw/bsp/imxrt/family.mk +++ b/hw/bsp/imxrt/family.mk @@ -13,7 +13,7 @@ CFLAGS += \ -D__ARMVFP__=0 -D__ARMFPV5__=0\ -DXIP_EXTERNAL_FLASH=1 \ -DXIP_BOOT_HEADER_ENABLE=1 \ - -DCFG_TUSB_MCU=OPT_MCU_MIMXRT10XX + -DCFG_TUSB_MCU=OPT_MCU_MIMXRT ifdef BOARD_TUD_RHPORT CFLAGS += -DBOARD_TUD_RHPORT=$(BOARD_TUD_RHPORT) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index ef0f9c4b7..473d1e910 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -66,7 +66,7 @@ // Use ring buffer if it's available, some MCUs need extra RAM requirements #ifndef TUD_AUDIO_PREFER_RING_BUFFER -#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT11XX +#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT #define TUD_AUDIO_PREFER_RING_BUFFER 0 #else #define TUD_AUDIO_PREFER_RING_BUFFER 1 @@ -102,8 +102,7 @@ CFG_TUSB_MCU == OPT_MCU_GD32VF103 || \ CFG_TUSB_MCU == OPT_MCU_LPC18XX || \ CFG_TUSB_MCU == OPT_MCU_LPC43XX || \ - CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ - CFG_TUSB_MCU == OPT_MCU_MIMXRT11XX || \ + CFG_TUSB_MCU == OPT_MCU_MIMXRT || \ CFG_TUSB_MCU == OPT_MCU_MSP432E4 #if TUD_AUDIO_PREFER_RING_BUFFER #define USE_LINEAR_BUFFER 0 diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 37866f2a3..baa82fc14 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -75,7 +75,7 @@ // TODO USB0 has 5, USB1 has 6 #define TUP_DCD_ENDPOINT_MAX 6 -#elif TU_CHECK_MCU(OPT_MCU_MIMXRT10XX, OPT_MCU_MIMXRT11XX) +#elif TU_CHECK_MCU(OPT_MCU_MIMXRT) #define TUP_USBIP_CHIPIDEA_HS #define TUP_USBIP_EHCI diff --git a/src/portable/chipidea/ci_hs/ci_hs_imxrt.h b/src/portable/chipidea/ci_hs/ci_hs_imxrt.h index a2a0c98f4..53bc8bd00 100644 --- a/src/portable/chipidea/ci_hs/ci_hs_imxrt.h +++ b/src/portable/chipidea/ci_hs/ci_hs_imxrt.h @@ -29,7 +29,7 @@ #include "fsl_device_registers.h" -#if CFG_TUSB_MCU == OPT_MCU_MIMXRT11XX +#if !defined(USB1_BASE) && defined(USB_OTG1_BASE) #define USB1_BASE USB_OTG1_BASE #define USB2_BASE USB_OTG2_BASE #endif diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c index 0925215ae..c7cc3e0e8 100644 --- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c @@ -34,7 +34,7 @@ #include "device/dcd.h" #include "ci_hs_type.h" -#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT11XX +#if CFG_TUSB_MCU == OPT_MCU_MIMXRT #include "ci_hs_imxrt.h" #elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX) #include "ci_hs_lpc18_43.h" diff --git a/src/portable/chipidea/ci_hs/hcd_ci_hs.c b/src/portable/chipidea/ci_hs/hcd_ci_hs.c index 39b490f72..d0396daea 100644 --- a/src/portable/chipidea/ci_hs/hcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/hcd_ci_hs.c @@ -29,7 +29,7 @@ // Chipidea Highspeed USB IP implement EHCI for host functionality #if CFG_TUH_ENABLED && \ - (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT11XX) + (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT) //--------------------------------------------------------------------+ // INCLUDE @@ -39,7 +39,7 @@ #include "portable/ehci/ehci_api.h" #include "ci_hs_type.h" -#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX +#if CFG_TUSB_MCU == OPT_MCU_MIMXRT #include "ci_hs_imxrt.h" #elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX) #include "ci_hs_lpc18_43.h" diff --git a/src/portable/nxp/transdimension/dcd_transdimension.c b/src/portable/nxp/transdimension/dcd_transdimension.c index 2347e1dae..1f27a6872 100644 --- a/src/portable/nxp/transdimension/dcd_transdimension.c +++ b/src/portable/nxp/transdimension/dcd_transdimension.c @@ -27,14 +27,14 @@ #include "tusb_option.h" #if CFG_TUD_ENABLED && \ - (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX) + (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT) #warning "transdimenion is renamed to chipidea (portable/chipidea/ci_hs) to match other opensource naming convention such as linux. This file will be removed in the future, please update your makefile accordingly" //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ -#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX +#if CFG_TUSB_MCU == OPT_MCU_MIMXRT #include "fsl_device_registers.h" #define INCLUDE_FSL_DEVICE_REGISTERS #else @@ -153,7 +153,7 @@ typedef struct const uint8_t ep_count; // Max bi-directional Endpoints }dcd_controller_t; -#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX +#if CFG_TUSB_MCU == OPT_MCU_MIMXRT static const dcd_controller_t _dcd_controller[] = { // RT1010 and RT1020 only has 1 USB controller diff --git a/src/portable/nxp/transdimension/hcd_transdimension.c b/src/portable/nxp/transdimension/hcd_transdimension.c index 2d0830981..392764ff6 100644 --- a/src/portable/nxp/transdimension/hcd_transdimension.c +++ b/src/portable/nxp/transdimension/hcd_transdimension.c @@ -29,14 +29,14 @@ // NXP Trans-Dimension USB IP implement EHCI for host functionality #if CFG_TUH_ENABLED && \ - (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX) + (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT) #warning "transdimenion is renamed to chipidea (portable/chipidea/ci_hs) to match other opensource naming convention such as linux. This file will be removed in the future, please update your makefile accordingly" //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ -#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX +#if CFG_TUSB_MCU == OPT_MCU_MIMXRT #include "fsl_device_registers.h" #else // LPCOpen for 18xx & 43xx @@ -58,7 +58,7 @@ typedef struct const IRQn_Type irqnum; // IRQ number }hcd_controller_t; -#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX +#if CFG_TUSB_MCU == OPT_MCU_MIMXRT static const hcd_controller_t _hcd_controller[] = { // RT1010 and RT1020 only has 1 USB controller diff --git a/src/tusb_option.h b/src/tusb_option.h index 0749a5e52..a030197f6 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -98,8 +98,8 @@ typedef int make_iso_compilers_happy; #define OPT_MCU_VALENTYUSB_EPTRI 600 ///< Fomu eptri config // NXP iMX RT -#define OPT_MCU_MIMXRT10XX 700 ///< NXP iMX RT10xx -#define OPT_MCU_MIMXRT11XX 701 ///< NXP iMX RT11xx +#define OPT_MCU_MIMXRT 700 ///< NXP iMX RT Series +#define OPT_MCU_MIMXRT10XX OPT_MCU_MIMXRT // Nuvoton #define OPT_MCU_NUC121 800 From 12341118e373cce10cb868f234009e9d37bff940 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 1 Jul 2022 16:24:58 +0700 Subject: [PATCH 420/504] add get-deps target update ci to get-deps first --- .github/workflows/build_arm.yml | 13 +++++++++---- docs/reference/getting_started.rst | 7 ++++++- examples/make.mk | 5 ----- examples/rules.mk | 27 ++++++++++++++++++--------- 4 files changed, 33 insertions(+), 19 deletions(-) diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml index 27cb9f1f7..7cc1b10f9 100644 --- a/.github/workflows/build_arm.yml +++ b/.github/workflows/build_arm.yml @@ -67,6 +67,11 @@ jobs: - name: Setup Python uses: actions/setup-python@v3 + - name: Install ARM GCC + uses: carlosperate/arm-none-eabi-gcc-action@v1 + with: + release: '11.2-2022.02' + - name: Checkout TinyUSB uses: actions/checkout@v3 @@ -86,10 +91,10 @@ jobs: echo >> $GITHUB_ENV PICO_SDK_PATH=~/pico-sdk git submodule update --init hw/mcu/raspberry_pi/Pico-PIO-USB - - name: Install ARM GCC - uses: carlosperate/arm-none-eabi-gcc-action@v1 - with: - release: '11.2-2022.02' + - name: Get Dependencies + run: | + b=`find hw/bsp/${{ matrix.family }}/boards -depth -maxdepth 1 -type d -name '[^.]?*' -printf %f -quit` + make BOARD={b} get-deps - name: Build run: python3 tools/build_family.py ${{ matrix.family }} diff --git a/docs/reference/getting_started.rst b/docs/reference/getting_started.rst index fa5c51eff..1088d4700 100644 --- a/docs/reference/getting_started.rst +++ b/docs/reference/getting_started.rst @@ -50,7 +50,12 @@ Some TinyUSB examples also requires external submodule libraries in ``/lib`` suc $ git submodule update --init lib -In addition, MCU driver submodule is also needed to provide low-level MCU peripheral's driver. Luckily, it will be fetched if needed when you run the ``make`` to build your board. +In addition, MCU driver submodule is also needed to provide low-level MCU peripheral's driver. To download these depencies for your board, run the ``get-dpes`` as follow. + +.. code-block:: + + $ make BOARD=feather_nrf52840_express get-deps + Some modules will also require a module-specific SDK (e.g. RP2040) or binary (e.g. Sony Spresense) to build examples. diff --git a/examples/make.mk b/examples/make.mk index 27e1db38c..47520d660 100644 --- a/examples/make.mk +++ b/examples/make.mk @@ -45,11 +45,6 @@ else SRC_C += $(subst $(TOP)/,,$(wildcard $(TOP)/$(FAMILY_PATH)/*.c)) endif -# Fetch submodules depended by family -fetch_submodule_if_empty = $(if $(wildcard $(TOP)/$1/*),,$(info $(shell git -C $(TOP) submodule update --init $1))) -ifdef DEPS_SUBMODULES - $(foreach s,$(DEPS_SUBMODULES),$(call fetch_submodule_if_empty,$(s))) -endif #-------------- Cross Compiler ------------ # Can be set by board, default to ARM GCC diff --git a/examples/rules.mk b/examples/rules.mk index 538dffbcf..c3134056a 100644 --- a/examples/rules.mk +++ b/examples/rules.mk @@ -5,6 +5,7 @@ # Set all as default goal .DEFAULT_GOAL := all +# ---------------- GNU Make Start ----------------------- # ESP32-Sx and RP2040 has its own CMake build system ifeq (,$(findstring $(FAMILY),esp32s2 esp32s3 rp2040)) @@ -141,7 +142,23 @@ $(BUILD)/obj/%_asm.o: %.S @echo AS $(notdir $@) @$(CC) -x assembler-with-cpp $(ASFLAGS) -c -o $@ $< -endif # GNU Make +endif + +.PHONY: clean +clean: +ifeq ($(CMDEXE),1) + rd /S /Q $(subst /,\,$(BUILD)) +else + $(RM) -rf $(BUILD) +endif +# ---------------- GNU Make End ----------------------- + +# get depenecies +.PHONY: get-deps +get-deps: + ifdef DEPS_SUBMODULES + git -C $(TOP) submodule update --init $(DEPS_SUBMODULES) + endif size: $(BUILD)/$(PROJECT).elf -@echo '' @@ -152,14 +169,6 @@ size: $(BUILD)/$(PROJECT).elf linkermap: $(BUILD)/$(PROJECT).elf @linkermap -v $<.map -.PHONY: clean -clean: -ifeq ($(CMDEXE),1) - rd /S /Q $(subst /,\,$(BUILD)) -else - $(RM) -rf $(BUILD) -endif - # --------------------------------------- # Flash Targets # --------------------------------------- From 5323472afd1f35d0e62bd58bb3293bcfce36483b Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 1 Jul 2022 16:37:34 +0700 Subject: [PATCH 421/504] update get-deps for ci --- .github/workflows/build_arm.yml | 2 +- tools/build_board.py | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml index 7cc1b10f9..935d57e06 100644 --- a/.github/workflows/build_arm.yml +++ b/.github/workflows/build_arm.yml @@ -94,7 +94,7 @@ jobs: - name: Get Dependencies run: | b=`find hw/bsp/${{ matrix.family }}/boards -depth -maxdepth 1 -type d -name '[^.]?*' -printf %f -quit` - make BOARD={b} get-deps + make -C examples/device/board_test BOARD=${b} get-deps - name: Build run: python3 tools/build_family.py ${{ matrix.family }} diff --git a/tools/build_board.py b/tools/build_board.py index 62a4ea82f..8d10ef820 100644 --- a/tools/build_board.py +++ b/tools/build_board.py @@ -1,6 +1,7 @@ import os import sys import time +import subprocess from multiprocessing import Pool import build_utils @@ -38,6 +39,10 @@ if __name__ == '__main__': filter_with_input(all_boards) all_boards.sort() + # Get dependencies + for b in all_boards: + subprocess.run("make -C examples/device/board_test BOARD={} get-deps".format(b), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + print(build_separator) print(build_utils.build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) total_time = time.monotonic() From 53db23142a89def1ad2f866863a559a931eeb035 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 1 Jul 2022 17:23:14 +0700 Subject: [PATCH 422/504] add get-dependencies.py --- .github/workflows/build_aarch64.yml | 3 +++ .github/workflows/build_arm.yml | 15 ++++++--------- .github/workflows/build_msp430.yml | 3 +++ .github/workflows/build_renesas.yml | 3 +++ .github/workflows/build_riscv.yml | 3 +++ hw/bsp/rp2040/family.mk | 2 ++ tools/get_dependencies.py | 25 +++++++++++++++++++++++++ 7 files changed, 45 insertions(+), 9 deletions(-) create mode 100644 tools/get_dependencies.py diff --git a/.github/workflows/build_aarch64.yml b/.github/workflows/build_aarch64.yml index 1720ba592..b4ea8a0eb 100644 --- a/.github/workflows/build_aarch64.yml +++ b/.github/workflows/build_aarch64.yml @@ -55,6 +55,9 @@ jobs: - name: Set Toolchain Path run: echo >> $GITHUB_PATH `echo ~/cache/toolchain/*/bin` + - name: Get Dependencies + run: python3 tools/get_dependencies.py ${{ matrix.family }} + - name: Build run: python3 tools/build_family.py ${{ matrix.family }} diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml index 935d57e06..4297ba895 100644 --- a/.github/workflows/build_arm.yml +++ b/.github/workflows/build_arm.yml @@ -89,12 +89,9 @@ jobs: run: | git clone --depth 1 -b develop https://github.com/raspberrypi/pico-sdk ~/pico-sdk echo >> $GITHUB_ENV PICO_SDK_PATH=~/pico-sdk - git submodule update --init hw/mcu/raspberry_pi/Pico-PIO-USB - name: Get Dependencies - run: | - b=`find hw/bsp/${{ matrix.family }}/boards -depth -maxdepth 1 -type d -name '[^.]?*' -printf %f -quit` - make -C examples/device/board_test BOARD=${b} get-deps + run: python3 tools/get_dependencies.py ${{ matrix.family }} - name: Build run: python3 tools/build_family.py ${{ matrix.family }} @@ -127,16 +124,16 @@ jobs: - name: Setup Python uses: actions/setup-python@v3 + - name: Install ARM GCC + uses: carlosperate/arm-none-eabi-gcc-action@v1 + with: + release: '11.2-2022.02' + - name: Checkout TinyUSB uses: actions/checkout@v3 - name: Checkout common submodules in lib run: git submodule update --init lib/FreeRTOS-Kernel lib/lwip - - name: Install ARM GCC - uses: carlosperate/arm-none-eabi-gcc-action@v1 - with: - release: '11.2-2022.02' - - name: Build run: python3 tools/build_board.py ${{ matrix.example }} diff --git a/.github/workflows/build_msp430.yml b/.github/workflows/build_msp430.yml index 6a468ab04..ea93f09a0 100644 --- a/.github/workflows/build_msp430.yml +++ b/.github/workflows/build_msp430.yml @@ -52,6 +52,9 @@ jobs: - name: Set Toolchain Path run: echo >> $GITHUB_PATH `echo ~/cache/toolchain/*/bin` + - name: Get Dependencies + run: python3 tools/get_dependencies.py ${{ matrix.family }} + - name: Build run: python3 tools/build_family.py ${{ matrix.family }} diff --git a/.github/workflows/build_renesas.yml b/.github/workflows/build_renesas.yml index 50618ff6b..2563d3549 100644 --- a/.github/workflows/build_renesas.yml +++ b/.github/workflows/build_renesas.yml @@ -53,6 +53,9 @@ jobs: - name: Set Toolchain Path run: echo >> $GITHUB_PATH `echo ~/cache/toolchain/*/bin` + - name: Get Dependencies + run: python3 tools/get_dependencies.py ${{ matrix.family }} + - name: Build run: python3 tools/build_family.py ${{ matrix.family }} diff --git a/.github/workflows/build_riscv.yml b/.github/workflows/build_riscv.yml index 2d670138d..90dc35206 100644 --- a/.github/workflows/build_riscv.yml +++ b/.github/workflows/build_riscv.yml @@ -53,6 +53,9 @@ jobs: - name: Set Toolchain Path run: echo >> $GITHUB_PATH `echo ~/cache/toolchain/*/bin` + - name: Get Dependencies + run: python3 tools/get_dependencies.py ${{ matrix.family }} + - name: Build run: python3 tools/build_family.py ${{ matrix.family }} diff --git a/hw/bsp/rp2040/family.mk b/hw/bsp/rp2040/family.mk index 5db784b14..cf6b53793 100644 --- a/hw/bsp/rp2040/family.mk +++ b/hw/bsp/rp2040/family.mk @@ -1,6 +1,8 @@ JLINK_DEVICE = rp2040_m0_0 PYOCD_TARGET = rp2040 +DEPS_SUBMODULES += hw/mcu/raspberry_pi/Pico-PIO-USB + ifeq ($(DEBUG), 1) CMAKE_DEFSYM += -DCMAKE_BUILD_TYPE=Debug endif diff --git a/tools/get_dependencies.py b/tools/get_dependencies.py new file mode 100644 index 000000000..e7d3e0a76 --- /dev/null +++ b/tools/get_dependencies.py @@ -0,0 +1,25 @@ +import os +import sys +import subprocess + + +# dependency lookup (ABC sorted) +# deps = { +# 'LPC11UXX' : [ [] ] +# } + + +def get_family_dep(family): + for entry in os.scandir("hw/bsp/{}/boards".format(family)): + if entry.is_dir(): + result = subprocess.run("make -C examples/device/board_test BOARD={} get-deps".format(entry.name), + shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + print(result.stdout.decode("utf-8")) + return result.returncode + +status = 0 +all_family = sys.argv[1:] +for f in all_family: + status += get_family_dep(f) + +sys.exit(status) \ No newline at end of file From 54250d7dd5b22dee07138b925a4ad218a6defcc8 Mon Sep 17 00:00:00 2001 From: NConrad Date: Sat, 9 Jul 2022 17:50:17 -0400 Subject: [PATCH 423/504] USBTMC: explicit type conversions fix --- src/class/usbtmc/usbtmc_device.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index c50ca65d5..af4a92732 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -603,23 +603,23 @@ bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request if(ep_addr == usbtmc_state.ep_bulk_out) { criticalEnter(); - usbd_edpt_stall(rhport, ep_addr); - usbd_edpt_clear_stall(rhport, ep_addr); + usbd_edpt_stall(rhport, (uint8_t)ep_addr); + usbd_edpt_clear_stall(rhport, (uint8_t)ep_addr); usbtmc_state.state = STATE_NAK; // USBD core has placed EP in NAK state for us criticalLeave(); tud_usbtmc_bulkOut_clearFeature_cb(); } else if (ep_addr == usbtmc_state.ep_bulk_in) { - usbd_edpt_stall(rhport, ep_addr); - usbd_edpt_clear_stall(rhport, ep_addr); + usbd_edpt_stall(rhport, (uint8_t)ep_addr); + usbd_edpt_clear_stall(rhport, (uint8_t)ep_addr); tud_usbtmc_bulkIn_clearFeature_cb(); } else if ((usbtmc_state.ep_int_in != 0) && (ep_addr == usbtmc_state.ep_int_in)) { // Clearing interrupt in EP - usbd_edpt_stall(rhport, ep_addr); - usbd_edpt_clear_stall(rhport, ep_addr); + usbd_edpt_stall(rhport, (uint8_t)ep_addr); + usbd_edpt_clear_stall(rhport, (uint8_t)ep_addr); } else { From 19768936ae6379b4c86947f70ab5cf2c0f8ed8f4 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 11 Jul 2022 14:01:18 +0700 Subject: [PATCH 424/504] bump up mcux-sdk for rt11xx, add back OPT_MCU_MIMXRT11XX --- examples/host/bare_api/only.txt | 1 + examples/host/cdc_msc_hid/only.txt | 1 + examples/host/hid_controller/only.txt | 1 + hw/mcu/nxp/mcux-sdk | 2 +- src/portable/chipidea/ci_hs/ci_hs_imxrt.h | 3 +++ src/tusb_option.h | 5 +++-- 6 files changed, 10 insertions(+), 3 deletions(-) diff --git a/examples/host/bare_api/only.txt b/examples/host/bare_api/only.txt index 7fe4e3f5c..da3ffdd19 100644 --- a/examples/host/bare_api/only.txt +++ b/examples/host/bare_api/only.txt @@ -4,6 +4,7 @@ mcu:LPC18XX mcu:LPC40XX mcu:LPC43XX mcu:MIMXRT10XX +mcu:MIMXRT11XX mcu:RP2040 mcu:MSP432E4 mcu:RX65X diff --git a/examples/host/cdc_msc_hid/only.txt b/examples/host/cdc_msc_hid/only.txt index 7fe4e3f5c..da3ffdd19 100644 --- a/examples/host/cdc_msc_hid/only.txt +++ b/examples/host/cdc_msc_hid/only.txt @@ -4,6 +4,7 @@ mcu:LPC18XX mcu:LPC40XX mcu:LPC43XX mcu:MIMXRT10XX +mcu:MIMXRT11XX mcu:RP2040 mcu:MSP432E4 mcu:RX65X diff --git a/examples/host/hid_controller/only.txt b/examples/host/hid_controller/only.txt index 7fe4e3f5c..da3ffdd19 100644 --- a/examples/host/hid_controller/only.txt +++ b/examples/host/hid_controller/only.txt @@ -4,6 +4,7 @@ mcu:LPC18XX mcu:LPC40XX mcu:LPC43XX mcu:MIMXRT10XX +mcu:MIMXRT11XX mcu:RP2040 mcu:MSP432E4 mcu:RX65X diff --git a/hw/mcu/nxp/mcux-sdk b/hw/mcu/nxp/mcux-sdk index cb21c6609..ae2ab01d9 160000 --- a/hw/mcu/nxp/mcux-sdk +++ b/hw/mcu/nxp/mcux-sdk @@ -1 +1 @@ -Subproject commit cb21c660991c92e90ece99ccb63a4bc611899c3a +Subproject commit ae2ab01d9d70ad00cd0e935c2552bd5f0e5c0294 diff --git a/src/portable/chipidea/ci_hs/ci_hs_imxrt.h b/src/portable/chipidea/ci_hs/ci_hs_imxrt.h index 53bc8bd00..2de0d9cb4 100644 --- a/src/portable/chipidea/ci_hs/ci_hs_imxrt.h +++ b/src/portable/chipidea/ci_hs/ci_hs_imxrt.h @@ -31,6 +31,9 @@ #if !defined(USB1_BASE) && defined(USB_OTG1_BASE) #define USB1_BASE USB_OTG1_BASE +#endif + +#if !defined(USB2_BASE) && defined(USB_OTG2_BASE) #define USB2_BASE USB_OTG2_BASE #endif diff --git a/src/tusb_option.h b/src/tusb_option.h index a030197f6..70ef1c399 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -98,8 +98,9 @@ typedef int make_iso_compilers_happy; #define OPT_MCU_VALENTYUSB_EPTRI 600 ///< Fomu eptri config // NXP iMX RT -#define OPT_MCU_MIMXRT 700 ///< NXP iMX RT Series -#define OPT_MCU_MIMXRT10XX OPT_MCU_MIMXRT +#define OPT_MCU_MIMXRT 700 ///< NXP iMX RT Series +#define OPT_MCU_MIMXRT10XX OPT_MCU_MIMXRT ///< RT10xx +#define OPT_MCU_MIMXRT11XX OPT_MCU_MIMXRT ///< RT11xx // Nuvoton #define OPT_MCU_NUC121 800 From 6da1e93edd4547a5ec5a1681cd1cb31803564993 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 11 Jul 2022 14:21:19 +0700 Subject: [PATCH 425/504] fix rt1050 evk build with latest mcu-sdk --- examples/host/bare_api/only.txt | 1 + examples/host/cdc_msc_hid/only.txt | 1 + examples/host/hid_controller/only.txt | 1 + hw/bsp/imxrt/boards/mimxrt1050_evkb/board.h | 4 ++-- 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/host/bare_api/only.txt b/examples/host/bare_api/only.txt index da3ffdd19..fa9c14857 100644 --- a/examples/host/bare_api/only.txt +++ b/examples/host/bare_api/only.txt @@ -3,6 +3,7 @@ mcu:LPC177X_8X mcu:LPC18XX mcu:LPC40XX mcu:LPC43XX +mcu:MIMXRT mcu:MIMXRT10XX mcu:MIMXRT11XX mcu:RP2040 diff --git a/examples/host/cdc_msc_hid/only.txt b/examples/host/cdc_msc_hid/only.txt index da3ffdd19..fa9c14857 100644 --- a/examples/host/cdc_msc_hid/only.txt +++ b/examples/host/cdc_msc_hid/only.txt @@ -3,6 +3,7 @@ mcu:LPC177X_8X mcu:LPC18XX mcu:LPC40XX mcu:LPC43XX +mcu:MIMXRT mcu:MIMXRT10XX mcu:MIMXRT11XX mcu:RP2040 diff --git a/examples/host/hid_controller/only.txt b/examples/host/hid_controller/only.txt index da3ffdd19..fa9c14857 100644 --- a/examples/host/hid_controller/only.txt +++ b/examples/host/hid_controller/only.txt @@ -3,6 +3,7 @@ mcu:LPC177X_8X mcu:LPC18XX mcu:LPC40XX mcu:LPC43XX +mcu:MIMXRT mcu:MIMXRT10XX mcu:MIMXRT11XX mcu:RP2040 diff --git a/hw/bsp/imxrt/boards/mimxrt1050_evkb/board.h b/hw/bsp/imxrt/boards/mimxrt1050_evkb/board.h index 928fbd727..0472f608c 100644 --- a/hw/bsp/imxrt/boards/mimxrt1050_evkb/board.h +++ b/hw/bsp/imxrt/boards/mimxrt1050_evkb/board.h @@ -45,7 +45,7 @@ // UART #define UART_PORT LPUART1 -#define UART_RX_PINMUX IOMUXC_GPIO_AD_B0_13_LPUART1_RX -#define UART_TX_PINMUX IOMUXC_GPIO_AD_B0_12_LPUART1_TX +#define UART_RX_PINMUX IOMUXC_GPIO_AD_B0_13_LPUART1_RXD +#define UART_TX_PINMUX IOMUXC_GPIO_AD_B0_12_LPUART1_TXD #endif /* BOARD_H_ */ From bb5dbd2da838773d8c1443ce52096ab9de63df19 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 11 Jul 2022 23:57:34 +0700 Subject: [PATCH 426/504] only enable warnings with approriate gcc version for rp2040 --- examples/example.cmake | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/examples/example.cmake b/examples/example.cmake index 3e395d53f..6b5e41dd9 100644 --- a/examples/example.cmake +++ b/examples/example.cmake @@ -4,28 +4,29 @@ target_compile_options(${PROJECT} PUBLIC -Werror -Wfatal-errors -Wdouble-promotion - #-Wstrict-prototypes - -Wstrict-overflow - #-Werror-implicit-function-declaration -Wfloat-equal - #-Wundef -Wshadow -Wwrite-strings -Wsign-compare -Wmissing-format-attribute -Wunreachable-code -Wcast-align - -Wcast-function-type -Wcast-qual -Wnull-dereference -Wuninitialized -Wunused -Wredundant-decls + #-Wstrict-prototypes + #-Werror-implicit-function-declaration + #-Wundef ) -# GCC version 9 or prior has a bug with incorrect Wconversion warnings +# GCC 10 if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10.0) - target_compile_options(${PROJECT} PUBLIC - -Wconversion - ) + target_compile_options(${PROJECT} PUBLIC -Wconversion) +endif() + +# GCC 8 +if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0) + target_compile_options(${PROJECT} PUBLIC -Wcast-function-type -Wstrict-overflow) endif() From 345558307d06338fdc2c79d88c95c8d97bdeeeb0 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 12 Jul 2022 00:50:52 +0700 Subject: [PATCH 427/504] fix incorrect null-dereference warnings when compiling with gcc7 --- src/host/usbh.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index b6a03b82e..0415a26cb 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -123,7 +123,6 @@ typedef struct { // Invalid driver ID in itf2drv[] ep2drv[][] mapping enum { DRVID_INVALID = 0xFFu }; -enum { ADDR_INVALID = 0xFFu }; enum { CONTROLLER_INVALID = 0xFFu }; #if CFG_TUSB_DEBUG >= 2 @@ -1434,7 +1433,8 @@ static uint8_t get_new_address(bool is_hub) { if (!_usbh_devices[idx].connected) return (idx+1); } - return ADDR_INVALID; + + return 0; // invalid address } static bool enum_request_set_addr(void) @@ -1443,7 +1443,7 @@ static bool enum_request_set_addr(void) // Get new address uint8_t const new_addr = get_new_address(desc_device->bDeviceClass == TUSB_CLASS_HUB); - TU_ASSERT(new_addr != ADDR_INVALID); + TU_ASSERT(new_addr != 0); TU_LOG2("Set Address = %d\r\n", new_addr); From 4ea27acd1da9e0144dbfbf805b87b22d16f7db8c Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 12 Jul 2022 01:55:33 +0700 Subject: [PATCH 428/504] minor update to webusb serial example --- examples/device/webusb_serial/src/main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/device/webusb_serial/src/main.c b/examples/device/webusb_serial/src/main.c index 8eaad7706..604d30a83 100644 --- a/examples/device/webusb_serial/src/main.c +++ b/examples/device/webusb_serial/src/main.c @@ -71,7 +71,7 @@ enum { static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; -#define URL "example.tinyusb.org/webusb-serial/" +#define URL "example.tinyusb.org/webusb-serial/index.html" const tusb_desc_webusb_url_t desc_url = { @@ -114,6 +114,7 @@ void echo_all(uint8_t buf[], uint32_t count) if ( web_serial_connected ) { tud_vendor_write(buf, count); + tud_vendor_flush(); } // echo to cdc @@ -211,7 +212,8 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ board_led_write(true); blink_interval_ms = BLINK_ALWAYS_ON; - tud_vendor_write_str("\r\nTinyUSB WebUSB device example\r\n"); + tud_vendor_write_str("\r\nWebUSB interface connected\r\n"); + tud_vendor_flush(); }else { blink_interval_ms = BLINK_MOUNTED; From fc1a27b6c9d5a19529d6ac968164f2734ea89023 Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Tue, 12 Jul 2022 12:58:30 -0500 Subject: [PATCH 429/504] RP@040: rework CMake for compiler warnings --- .../device/audio_4_channel_mic/CMakeLists.txt | 3 - examples/device/audio_test/CMakeLists.txt | 3 - examples/device/board_test/CMakeLists.txt | 3 - examples/device/cdc_dual_ports/CMakeLists.txt | 3 - examples/device/cdc_msc/CMakeLists.txt | 3 - examples/device/dfu/CMakeLists.txt | 3 - examples/device/dfu_runtime/CMakeLists.txt | 3 - .../dynamic_configuration/CMakeLists.txt | 3 - .../device/hid_boot_interface/CMakeLists.txt | 3 - examples/device/hid_composite/CMakeLists.txt | 3 - .../device/hid_generic_inout/CMakeLists.txt | 3 - .../hid_multiple_interface/CMakeLists.txt | 3 - examples/device/midi_test/CMakeLists.txt | 3 - examples/device/msc_dual_lun/CMakeLists.txt | 3 - .../device/net_lwip_webserver/CMakeLists.txt | 3 - examples/device/uac2_headset/CMakeLists.txt | 3 - examples/device/usbtmc/CMakeLists.txt | 3 - examples/device/video_capture/CMakeLists.txt | 3 - examples/device/webusb_serial/CMakeLists.txt | 3 - .../host_hid_to_device_cdc/CMakeLists.txt | 9 +-- examples/example.cmake | 32 --------- examples/host/bare_api/CMakeLists.txt | 3 - examples/host/cdc_msc_hid/CMakeLists.txt | 3 - examples/host/hid_controller/CMakeLists.txt | 3 - hw/bsp/family_support.cmake | 37 ++++++++++ hw/bsp/rp2040/family.cmake | 71 +++++++++++-------- src/portable/raspberrypi/rp2040/rp2040_usb.c | 2 + 27 files changed, 85 insertions(+), 132 deletions(-) delete mode 100644 examples/example.cmake diff --git a/examples/device/audio_4_channel_mic/CMakeLists.txt b/examples/device/audio_4_channel_mic/CMakeLists.txt index e6ce2813e..f6e10e2ea 100644 --- a/examples/device/audio_4_channel_mic/CMakeLists.txt +++ b/examples/device/audio_4_channel_mic/CMakeLists.txt @@ -23,9 +23,6 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) -# Example common such as compiler warnings -include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) - # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) diff --git a/examples/device/audio_test/CMakeLists.txt b/examples/device/audio_test/CMakeLists.txt index 416b91665..cb321f9a8 100644 --- a/examples/device/audio_test/CMakeLists.txt +++ b/examples/device/audio_test/CMakeLists.txt @@ -23,9 +23,6 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) -# Example common such as compiler warnings -include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) - # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/board_test/CMakeLists.txt b/examples/device/board_test/CMakeLists.txt index ac530a928..37113578e 100644 --- a/examples/device/board_test/CMakeLists.txt +++ b/examples/device/board_test/CMakeLists.txt @@ -36,9 +36,6 @@ else() ${CMAKE_CURRENT_SOURCE_DIR}/src ) - # Example common such as compiler warnings - include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) - # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) diff --git a/examples/device/cdc_dual_ports/CMakeLists.txt b/examples/device/cdc_dual_ports/CMakeLists.txt index 438635958..abc4d91da 100644 --- a/examples/device/cdc_dual_ports/CMakeLists.txt +++ b/examples/device/cdc_dual_ports/CMakeLists.txt @@ -23,9 +23,6 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) -# Example common such as compiler warnings -include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) - # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/cdc_msc/CMakeLists.txt b/examples/device/cdc_msc/CMakeLists.txt index 04c7c1b26..fa6e83b7e 100644 --- a/examples/device/cdc_msc/CMakeLists.txt +++ b/examples/device/cdc_msc/CMakeLists.txt @@ -24,9 +24,6 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) -# Example common such as compiler warnings -include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) - # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/dfu/CMakeLists.txt b/examples/device/dfu/CMakeLists.txt index 121ab3852..acaa54198 100644 --- a/examples/device/dfu/CMakeLists.txt +++ b/examples/device/dfu/CMakeLists.txt @@ -23,9 +23,6 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) -# Example common such as compiler warnings -include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) - # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) diff --git a/examples/device/dfu_runtime/CMakeLists.txt b/examples/device/dfu_runtime/CMakeLists.txt index 438635958..abc4d91da 100644 --- a/examples/device/dfu_runtime/CMakeLists.txt +++ b/examples/device/dfu_runtime/CMakeLists.txt @@ -23,9 +23,6 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) -# Example common such as compiler warnings -include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) - # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/dynamic_configuration/CMakeLists.txt b/examples/device/dynamic_configuration/CMakeLists.txt index 04c7c1b26..fa6e83b7e 100644 --- a/examples/device/dynamic_configuration/CMakeLists.txt +++ b/examples/device/dynamic_configuration/CMakeLists.txt @@ -24,9 +24,6 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) -# Example common such as compiler warnings -include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) - # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/hid_boot_interface/CMakeLists.txt b/examples/device/hid_boot_interface/CMakeLists.txt index 438635958..abc4d91da 100644 --- a/examples/device/hid_boot_interface/CMakeLists.txt +++ b/examples/device/hid_boot_interface/CMakeLists.txt @@ -23,9 +23,6 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) -# Example common such as compiler warnings -include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) - # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/hid_composite/CMakeLists.txt b/examples/device/hid_composite/CMakeLists.txt index 438635958..abc4d91da 100644 --- a/examples/device/hid_composite/CMakeLists.txt +++ b/examples/device/hid_composite/CMakeLists.txt @@ -23,9 +23,6 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) -# Example common such as compiler warnings -include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) - # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/hid_generic_inout/CMakeLists.txt b/examples/device/hid_generic_inout/CMakeLists.txt index 438635958..abc4d91da 100644 --- a/examples/device/hid_generic_inout/CMakeLists.txt +++ b/examples/device/hid_generic_inout/CMakeLists.txt @@ -23,9 +23,6 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) -# Example common such as compiler warnings -include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) - # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/hid_multiple_interface/CMakeLists.txt b/examples/device/hid_multiple_interface/CMakeLists.txt index 438635958..abc4d91da 100644 --- a/examples/device/hid_multiple_interface/CMakeLists.txt +++ b/examples/device/hid_multiple_interface/CMakeLists.txt @@ -23,9 +23,6 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) -# Example common such as compiler warnings -include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) - # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/midi_test/CMakeLists.txt b/examples/device/midi_test/CMakeLists.txt index 438635958..abc4d91da 100644 --- a/examples/device/midi_test/CMakeLists.txt +++ b/examples/device/midi_test/CMakeLists.txt @@ -23,9 +23,6 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) -# Example common such as compiler warnings -include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) - # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/msc_dual_lun/CMakeLists.txt b/examples/device/msc_dual_lun/CMakeLists.txt index 518eac3ad..9e834ae21 100644 --- a/examples/device/msc_dual_lun/CMakeLists.txt +++ b/examples/device/msc_dual_lun/CMakeLists.txt @@ -24,9 +24,6 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) -# Example common such as compiler warnings -include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) - # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/net_lwip_webserver/CMakeLists.txt b/examples/device/net_lwip_webserver/CMakeLists.txt index 0f41b888a..9fe1a325e 100644 --- a/examples/device/net_lwip_webserver/CMakeLists.txt +++ b/examples/device/net_lwip_webserver/CMakeLists.txt @@ -69,9 +69,6 @@ if (EXISTS ${TOP}/lib/lwip/src) ${TOP}/lib/networking/rndis_reports.c ) - # Example common such as compiler warnings - include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) - # due to warnings from other net source, we need to prevent error from some of the warnings options target_compile_options(${PROJECT} PUBLIC -Wno-error=null-dereference diff --git a/examples/device/uac2_headset/CMakeLists.txt b/examples/device/uac2_headset/CMakeLists.txt index 438635958..abc4d91da 100644 --- a/examples/device/uac2_headset/CMakeLists.txt +++ b/examples/device/uac2_headset/CMakeLists.txt @@ -23,9 +23,6 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) -# Example common such as compiler warnings -include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) - # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/usbtmc/CMakeLists.txt b/examples/device/usbtmc/CMakeLists.txt index 74f81b24f..c49603c26 100644 --- a/examples/device/usbtmc/CMakeLists.txt +++ b/examples/device/usbtmc/CMakeLists.txt @@ -24,9 +24,6 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) -# Example common such as compiler warnings -include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) - # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/video_capture/CMakeLists.txt b/examples/device/video_capture/CMakeLists.txt index 416b91665..cb321f9a8 100644 --- a/examples/device/video_capture/CMakeLists.txt +++ b/examples/device/video_capture/CMakeLists.txt @@ -23,9 +23,6 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) -# Example common such as compiler warnings -include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) - # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/device/webusb_serial/CMakeLists.txt b/examples/device/webusb_serial/CMakeLists.txt index 438635958..abc4d91da 100644 --- a/examples/device/webusb_serial/CMakeLists.txt +++ b/examples/device/webusb_serial/CMakeLists.txt @@ -23,9 +23,6 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) -# Example common such as compiler warnings -include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) - # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT}) \ No newline at end of file diff --git a/examples/dual/host_hid_to_device_cdc/CMakeLists.txt b/examples/dual/host_hid_to_device_cdc/CMakeLists.txt index 909ee423f..fc9bbfc13 100644 --- a/examples/dual/host_hid_to_device_cdc/CMakeLists.txt +++ b/examples/dual/host_hid_to_device_cdc/CMakeLists.txt @@ -23,8 +23,9 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) -# Example common such as compiler warnings -include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) +# Configure compilation flags and libraries for the example... see the corresponding function +# in hw/bsp/FAMILY/family.cmake for details. +family_configure_dual_usb_example(${PROJECT}) # due to warnings from other net source, we need to prevent error from some of the warnings options target_compile_options(${PROJECT} PUBLIC @@ -37,7 +38,3 @@ target_compile_options(${PROJECT} PUBLIC -Wno-error=sign-compare -Wno-error=unused-function ) - -# Configure compilation flags and libraries for the example... see the corresponding function -# in hw/bsp/FAMILY/family.cmake for details. -family_configure_dual_usb_example(${PROJECT}) diff --git a/examples/example.cmake b/examples/example.cmake deleted file mode 100644 index 6b5e41dd9..000000000 --- a/examples/example.cmake +++ /dev/null @@ -1,32 +0,0 @@ -target_compile_options(${PROJECT} PUBLIC - -Wall - -Wextra - -Werror - -Wfatal-errors - -Wdouble-promotion - -Wfloat-equal - -Wshadow - -Wwrite-strings - -Wsign-compare - -Wmissing-format-attribute - -Wunreachable-code - -Wcast-align - -Wcast-qual - -Wnull-dereference - -Wuninitialized - -Wunused - -Wredundant-decls - #-Wstrict-prototypes - #-Werror-implicit-function-declaration - #-Wundef - ) - -# GCC 10 -if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10.0) - target_compile_options(${PROJECT} PUBLIC -Wconversion) -endif() - -# GCC 8 -if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0) - target_compile_options(${PROJECT} PUBLIC -Wcast-function-type -Wstrict-overflow) -endif() diff --git a/examples/host/bare_api/CMakeLists.txt b/examples/host/bare_api/CMakeLists.txt index 98540ffb0..bc04b01a7 100644 --- a/examples/host/bare_api/CMakeLists.txt +++ b/examples/host/bare_api/CMakeLists.txt @@ -22,9 +22,6 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) -# Example common such as compiler warnings -include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) - # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_host_example(${PROJECT}) diff --git a/examples/host/cdc_msc_hid/CMakeLists.txt b/examples/host/cdc_msc_hid/CMakeLists.txt index 6990e957b..c4a4d8e63 100644 --- a/examples/host/cdc_msc_hid/CMakeLists.txt +++ b/examples/host/cdc_msc_hid/CMakeLists.txt @@ -24,9 +24,6 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) -# Example common such as compiler warnings -include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) - # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_host_example(${PROJECT}) diff --git a/examples/host/hid_controller/CMakeLists.txt b/examples/host/hid_controller/CMakeLists.txt index eefeb4a49..6153d399a 100644 --- a/examples/host/hid_controller/CMakeLists.txt +++ b/examples/host/hid_controller/CMakeLists.txt @@ -23,9 +23,6 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) -# Example common such as compiler warnings -include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake) - # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_host_example(${PROJECT}) diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index ee29caba7..75bd97cb6 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -79,6 +79,43 @@ if (NOT TARGET _family_support_marker) endif() endfunction() + function(family_add_default_example_warnings TARGET) + target_compile_options(${TARGET} PUBLIC + -Wall + -Wextra + -Werror + -Wfatal-errors + -Wdouble-promotion + -Wfloat-equal + -Wshadow + -Wwrite-strings + -Wsign-compare + -Wmissing-format-attribute + -Wunreachable-code + -Wcast-align + -Wcast-qual + -Wnull-dereference + -Wuninitialized + -Wunused + -Wredundant-decls + #-Wstrict-prototypes + #-Werror-implicit-function-declaration + #-Wundef + ) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + # GCC 10 + if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10.0) + target_compile_options(${TARGET} PUBLIC -Wconversion) + endif() + + # GCC 8 + if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0) + target_compile_options(${TARGET} PUBLIC -Wcast-function-type -Wstrict-overflow) + endif() + endif() + endfunction() + # configure an executable target to link to tinyusb in device mode, and add the board implementation function(family_configure_device_example TARGET) # default implentation is empty, the function should be redefined in the FAMILY/family.cmake diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index 530d80fec..31e97d9af 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -147,16 +147,23 @@ if (NOT TARGET _rp2040_family_inclusion_marker) target_link_libraries(${TARGET} PUBLIC pico_stdlib pico_bootsel_via_double_reset tinyusb_board tinyusb_additions) endfunction() + function(rp2040_family_configure_example_warnings TARGET) + if (NOT PICO_TINYUSB_NO_EXAMPLE_WARNINGS) + family_add_default_example_warnings(${TARGET}) + endif() + suppress_tinyusb_warnings() + endfunction() + function(family_configure_device_example TARGET) family_configure_target(${TARGET}) target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_device) - suppress_tinyusb_warnings() + rp2040_family_configure_example_warnings(${TARGET}) endfunction() function(family_configure_host_example TARGET) family_configure_target(${TARGET}) target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_host) - suppress_tinyusb_warnings() + rp2040_family_configure_example_warnings(${TARGET}) endfunction() function(family_add_pico_pio_usb TARGET) @@ -167,7 +174,7 @@ if (NOT TARGET _rp2040_family_inclusion_marker) family_configure_target(${TARGET}) # require tinyusb_pico_pio_usb target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_device tinyusb_host tinyusb_pico_pio_usb ) - suppress_tinyusb_warnings() + rp2040_family_configure_example_warnings(${TARGET}) endfunction() function(check_and_add_pico_pio_usb_support) @@ -236,30 +243,38 @@ if (NOT TARGET _rp2040_family_inclusion_marker) # This method must be called from the project scope to suppress known warnings in TinyUSB source files function(suppress_tinyusb_warnings) # some of these are pretty silly warnings only occurring in some older GCC versions 9 or prior - if (CMAKE_C_COMPILER_VERSION VERSION_LESS 10.0) - set(CONVERSION_WARNING_FILES - ${PICO_TINYUSB_PATH}/src/tusb.c - ${PICO_TINYUSB_PATH}/src/common/tusb_fifo.c - ${PICO_TINYUSB_PATH}/src/device/usbd.c - ${PICO_TINYUSB_PATH}/src/device/usbd_control.c - ${PICO_TINYUSB_PATH}/src/host/usbh.c - ${PICO_TINYUSB_PATH}/src/class/cdc/cdc_device.c - ${PICO_TINYUSB_PATH}/src/class/cdc/cdc_host.c - ${PICO_TINYUSB_PATH}/src/class/hid/hid_device.c - ${PICO_TINYUSB_PATH}/src/class/hid/hid_host.c - ${PICO_TINYUSB_PATH}/src/class/audio/audio_device.c - ${PICO_TINYUSB_PATH}/src/class/dfu/dfu_device.c - ${PICO_TINYUSB_PATH}/src/class/dfu/dfu_rt_device.c - ${PICO_TINYUSB_PATH}/src/class/midi/midi_device.c - ${PICO_TINYUSB_PATH}/src/class/usbtmc/usbtmc_device.c - ${PICO_TINYUSB_PATH}/src/portable/raspberrypi/rp2040/hcd_rp2040.c - ) - foreach(SOURCE_FILE IN LISTS CONVERSION_WARNING_FILES) - set_source_files_properties( - ${SOURCE_FILE} - PROPERTIES - COMPILE_FLAGS "-Wno-conversion") - endforeach() - endif() + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + if (CMAKE_C_COMPILER_VERSION VERSION_LESS 10.0) + set(CONVERSION_WARNING_FILES + ${PICO_TINYUSB_PATH}/src/tusb.c + ${PICO_TINYUSB_PATH}/src/common/tusb_fifo.c + ${PICO_TINYUSB_PATH}/src/device/usbd.c + ${PICO_TINYUSB_PATH}/src/device/usbd_control.c + ${PICO_TINYUSB_PATH}/src/host/usbh.c + ${PICO_TINYUSB_PATH}/src/class/cdc/cdc_device.c + ${PICO_TINYUSB_PATH}/src/class/cdc/cdc_host.c + ${PICO_TINYUSB_PATH}/src/class/hid/hid_device.c + ${PICO_TINYUSB_PATH}/src/class/hid/hid_host.c + ${PICO_TINYUSB_PATH}/src/class/audio/audio_device.c + ${PICO_TINYUSB_PATH}/src/class/dfu/dfu_device.c + ${PICO_TINYUSB_PATH}/src/class/dfu/dfu_rt_device.c + ${PICO_TINYUSB_PATH}/src/class/midi/midi_device.c + ${PICO_TINYUSB_PATH}/src/class/usbtmc/usbtmc_device.c + ${PICO_TINYUSB_PATH}/src/portable/raspberrypi/rp2040/hcd_rp2040.c + ) + foreach(SOURCE_FILE IN LISTS CONVERSION_WARNING_FILES) + set_source_files_properties( + ${SOURCE_FILE} + PROPERTIES + COMPILE_FLAGS "-Wno-conversion") + endforeach() + endif() + if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 11.0) + set_source_files_properties( + ${PICO_TINYUSB_PATH}/src/portable/raspberrypi/rp2040/rp2040_usb.c + PROPERTIES + COMPILE_FLAGS "-Wno-stringop-overflow -Wno-array-bounds") + endif() + endif() endfunction() endif() diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index 49be90167..25c013bd2 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -60,7 +60,9 @@ void rp2040_usb_init(void) // Clear any previous state just in case #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warray-bounds" +#if __GNUC__ > 6 #pragma GCC diagnostic ignored "-Wstringop-overflow" +#endif memset(usb_hw, 0, sizeof(*usb_hw)); memset(usb_dpram, 0, sizeof(*usb_dpram)); #pragma GCC diagnostic pop From 4bd47bcb99eef7a71ba2d45842af43e6269c30d4 Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Tue, 12 Jul 2022 13:29:47 -0500 Subject: [PATCH 430/504] disable bad gcc 6 warning --- hw/bsp/family_support.cmake | 5 +++++ src/host/usbh.c | 2 ++ 2 files changed, 7 insertions(+) diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index 75bd97cb6..c5311b63f 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -113,6 +113,11 @@ if (NOT TARGET _family_support_marker) if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0) target_compile_options(${TARGET} PUBLIC -Wcast-function-type -Wstrict-overflow) endif() + + # GCC 6 + if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 6.0) + target_compile_options(${TARGET} PUBLIC -Wno-strict-aliasing) + endif() endif() endfunction() diff --git a/src/host/usbh.c b/src/host/usbh.c index 0415a26cb..26351d16a 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -655,7 +655,9 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result TU_ASSERT( hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.buffer, request->wLength) ); return true; } +#if __GNUC__ >= 7 __attribute__((fallthrough)); +#endif case CONTROL_STAGE_DATA: if (request->wLength) From 7e4c0f64cd32ee0c73da37703dda2f83ed760132 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 14 Jul 2022 18:39:47 +0700 Subject: [PATCH 431/504] abtract attribute fallthrough --- src/common/tusb_compiler.h | 10 ++++++++++ src/host/usbh.c | 4 +--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h index ae00f4e75..2c30daf6f 100644 --- a/src/common/tusb_compiler.h +++ b/src/common/tusb_compiler.h @@ -131,6 +131,12 @@ #define TU_ATTR_BIT_FIELD_ORDER_BEGIN #define TU_ATTR_BIT_FIELD_ORDER_END + #if __has_attribute(__fallthrough__) + #define TU_ATTR_FALLTHROUGH __attribute__((fallthrough)) + #else + #define TU_ATTR_FALLTHROUGH do {} while (0) /* fallthrough */ + #endif + // Endian conversion use well-known host to network (big endian) naming #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #define TU_BYTE_ORDER TU_LITTLE_ENDIAN @@ -156,6 +162,7 @@ #define TU_ATTR_DEPRECATED(mess) __attribute__ ((deprecated(mess))) // warn if function with this attribute is used #define TU_ATTR_UNUSED __attribute__ ((unused)) // Function/Variable is meant to be possibly unused #define TU_ATTR_USED __attribute__ ((used)) + #define TU_ATTR_FALLTHROUGH __attribute__((fallthrough)) #define TU_ATTR_PACKED_BEGIN #define TU_ATTR_PACKED_END @@ -182,6 +189,7 @@ #define TU_ATTR_DEPRECATED(mess) __attribute__ ((deprecated(mess))) // warn if function with this attribute is used #define TU_ATTR_UNUSED __attribute__ ((unused)) // Function/Variable is meant to be possibly unused #define TU_ATTR_USED __attribute__ ((used)) // Function/Variable is meant to be used + #define TU_ATTR_FALLTHROUGH __attribute__((fallthrough)) #define TU_ATTR_PACKED_BEGIN #define TU_ATTR_PACKED_END @@ -207,6 +215,7 @@ #define TU_ATTR_DEPRECATED(mess) #define TU_ATTR_UNUSED #define TU_ATTR_USED + #define TU_ATTR_FALLTHROUGH do {} while (0) /* fallthrough */ #define TU_ATTR_PACKED_BEGIN _Pragma("pack") #define TU_ATTR_PACKED_END _Pragma("packoption") @@ -227,6 +236,7 @@ #error "Compiler attribute porting is required" #endif + #if (TU_BYTE_ORDER == TU_LITTLE_ENDIAN) #define tu_htons(u16) (TU_BSWAP16(u16)) diff --git a/src/host/usbh.c b/src/host/usbh.c index 26351d16a..9d618db92 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -655,9 +655,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result TU_ASSERT( hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.buffer, request->wLength) ); return true; } -#if __GNUC__ >= 7 - __attribute__((fallthrough)); -#endif + TU_ATTR_FALLTHROUGH; case CONTROL_STAGE_DATA: if (request->wLength) From b495d6f8ec263e51b0683ab85ff9e54dab6f5fd3 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 17 Jul 2022 22:46:16 +0700 Subject: [PATCH 432/504] temporarily revert len back to uint8_t in tud_hid_report_complete_cb() for up coming release --- examples/device/hid_boot_interface/src/main.c | 2 +- examples/device/hid_composite/src/main.c | 2 +- examples/device/hid_composite_freertos/src/main.c | 2 +- src/class/hid/hid_device.c | 2 +- src/class/hid/hid_device.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/device/hid_boot_interface/src/main.c b/examples/device/hid_boot_interface/src/main.c index 1958d614d..71afa3f46 100644 --- a/examples/device/hid_boot_interface/src/main.c +++ b/examples/device/hid_boot_interface/src/main.c @@ -181,7 +181,7 @@ void tud_hid_set_protocol_cb(uint8_t instance, uint8_t protocol) // Invoked when sent REPORT successfully to host // Application can use this to send the next report // Note: For composite reports, report[0] is report ID -void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len) +void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, /*uint16_t*/ uint8_t len) { (void) instance; (void) report; diff --git a/examples/device/hid_composite/src/main.c b/examples/device/hid_composite/src/main.c index 05315f266..f7d76cfc7 100644 --- a/examples/device/hid_composite/src/main.c +++ b/examples/device/hid_composite/src/main.c @@ -225,7 +225,7 @@ void hid_task(void) // Invoked when sent REPORT successfully to host // Application can use this to send the next report // Note: For composite reports, report[0] is report ID -void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len) +void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, /*uint16_t*/ uint8_t len) { (void) instance; (void) len; diff --git a/examples/device/hid_composite_freertos/src/main.c b/examples/device/hid_composite_freertos/src/main.c index ea8d917fe..b67c10937 100644 --- a/examples/device/hid_composite_freertos/src/main.c +++ b/examples/device/hid_composite_freertos/src/main.c @@ -294,7 +294,7 @@ void hid_task(void* param) // Invoked when sent REPORT successfully to host // Application can use this to send the next report // Note: For composite reports, report[0] is report ID -void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len) +void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, /*uint16_t*/ uint8_t len) { (void) instance; (void) len; diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 2d46d760f..8077e4deb 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -403,7 +403,7 @@ bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ { if (tud_hid_report_complete_cb) { - tud_hid_report_complete_cb(instance, p_hid->epin_buf, (uint16_t) xferred_bytes); + tud_hid_report_complete_cb(instance, p_hid->epin_buf, (/*uint16_t*/ uint8_t) xferred_bytes); } } // Received report diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index 3714d2769..3143b1024 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -116,7 +116,7 @@ TU_ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t instance, uint8_t idle_rate); // Invoked when sent REPORT successfully to host // Application can use this to send the next report // Note: For composite reports, report[0] is report ID -TU_ATTR_WEAK void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len); +TU_ATTR_WEAK void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, /*uint16_t*/ uint8_t len ); //--------------------------------------------------------------------+ From b0b155c9491d9e8cfc3d40366f77accfd3302cec Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 19 Jul 2022 12:28:52 +0700 Subject: [PATCH 433/504] increase version for release along with minor doc update --- README.rst | 4 ++-- docs/reference/getting_started.rst | 19 +++++++++---------- src/tusb_option.h | 2 +- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/README.rst b/README.rst index 1a96f6e16..92cb0ba6c 100644 --- a/README.rst +++ b/README.rst @@ -94,8 +94,8 @@ TinyUSB is completely thread-safe by pushing all Interrupt Service Request (ISR) - `RT-Thread `_: `repo `_ - **Mynewt** Due to the newt package build system, Mynewt examples are better to be on its `own repo `_ -Local Docs -========== +Docs +==== - Info diff --git a/docs/reference/getting_started.rst b/docs/reference/getting_started.rst index 1088d4700..3cdb46849 100644 --- a/docs/reference/getting_started.rst +++ b/docs/reference/getting_started.rst @@ -50,16 +50,7 @@ Some TinyUSB examples also requires external submodule libraries in ``/lib`` suc $ git submodule update --init lib -In addition, MCU driver submodule is also needed to provide low-level MCU peripheral's driver. To download these depencies for your board, run the ``get-dpes`` as follow. - -.. code-block:: - - $ make BOARD=feather_nrf52840_express get-deps - - -Some modules will also require a module-specific SDK (e.g. RP2040) or binary (e.g. Sony Spresense) to build examples. - -Note: some examples especially those that uses Vendor class (e.g webUSB) may requires udev permission on Linux (and/or macOS) to access usb device. It depends on your OS distro, typically copy ``/examples/device/99-tinyusb.rules`` file to /etc/udev/rules.d/ then run ``sudo udevadm control --reload-rules && sudo udevadm trigger`` is good enough. +Some ports will also require a port-specific SDK (e.g. RP2040) or binary (e.g. Sony Spresense) to build examples. They are out of scope for tinyusb, you should download/install it first according to its manufacturer guide. Build ^^^^^ @@ -70,6 +61,13 @@ To build example, first change directory to an example folder. $ cd examples/device/cdc_msc +Before building, we need to download MCU driver submodule to provide low-level MCU peripheral's driver first. Run the ``get-dpes`` target in one of the example folder as follow. You only need to do this once per mcu + +.. code-block:: + + $ make BOARD=feather_nrf52840_express get-deps + + Some modules (e.g. RP2040 and ESP32s2) require the project makefiles to be customized using CMake. If necessary apply any setup steps for the platform's SDK. Then compile with ``make BOARD=[board_name] all``\ , for example @@ -79,6 +77,7 @@ Then compile with ``make BOARD=[board_name] all``\ , for example $ make BOARD=feather_nrf52840_express all Note: ``BOARD`` can be found as directory name in ``hw/bsp``\ , either in its family/boards or directly under bsp (no family). +Note: some examples especially those that uses Vendor class (e.g webUSB) may requires udev permission on Linux (and/or macOS) to access usb device. It depends on your OS distro, typically copy ``/examples/device/99-tinyusb.rules`` file to /etc/udev/rules.d/ then run ``sudo udevadm control --reload-rules && sudo udevadm trigger`` is good enough. Port Selection ~~~~~~~~~~~~~~ diff --git a/src/tusb_option.h b/src/tusb_option.h index 70ef1c399..a557c785a 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -33,7 +33,7 @@ typedef int make_iso_compilers_happy; #include "common/tusb_compiler.h" #define TUSB_VERSION_MAJOR 0 -#define TUSB_VERSION_MINOR 13 +#define TUSB_VERSION_MINOR 14 #define TUSB_VERSION_REVISION 0 #define TUSB_VERSION_STRING TU_STRING(TUSB_VERSION_MAJOR) "." TU_STRING(TUSB_VERSION_MINOR) "." TU_STRING(TUSB_VERSION_REVISION) From 23ea8d1e255b00be6916f7d3ca0a1fba60c68ef4 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 25 Jul 2022 22:27:33 +0700 Subject: [PATCH 434/504] update doc --- README.rst | 2 +- docs/reference/supported.rst | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 92cb0ba6c..ba176a8c8 100644 --- a/README.rst +++ b/README.rst @@ -43,7 +43,7 @@ The stack supports the following MCUs: - **Nuvoton:** NUC120, NUC121/NUC125, NUC126, NUC505 - **NXP:** - - iMX RT Series: RT1011, RT1015, RT1021, RT1052, RT1062, RT1064 + - iMX RT Series: RT10xx, RT11xx - Kinetis: KL25, K32L2 - LPC Series: 11u, 13, 15, 17, 18, 40, 43, 51u, 54, 55 diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index 7ce982713..ad2af98ff 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -41,6 +41,8 @@ Supported MCUs | | NUC505 | ✔ | | ✔ | | | +--------------+---------+-------------+--------+------+-----------+-------------------+--------------+ | NXP | iMXRT | RT10xx | ✔ | ✔ | ✔ | ci_hs | | +| | +-------------+--------+------+-----------+-------------------+--------------+ +| | | RT11xx | ✔ | ✔ | ✔ | ci_hs | | | +---------+-------------+--------+------+-----------+-------------------+--------------+ | | Kinetis | KL25 | ✔ | ⚠ | ✖ | | | | | +-------------+--------+------+-----------+-------------------+--------------+ From 0be6db50f873ccba3781aa3dd4fbc9b0fd46f38e Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 23 Jul 2022 18:39:22 +0700 Subject: [PATCH 435/504] test self-hosted --- .github/workflows/build_arm.yml | 24 ++++++++++++++++++- .github/workflows/test_hardware.yml | 37 +++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/test_hardware.yml diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml index 4297ba895..64322082d 100644 --- a/.github/workflows/build_arm.yml +++ b/.github/workflows/build_arm.yml @@ -99,11 +99,33 @@ jobs: - name: Linker Map run: | pip install linkermap/ - for ex in `ls -d examples/device/*/`; do \ + # find -quit to only print map of 1 board per example + for ex in `ls -d examples/*/*/`; do \ find ${ex} -name *.map -print -quit | \ xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"'; \ done + # Following steps are for Hardware Test with self-hosted + + - name: Prepare Artifacts + if: matrix.family == 'rp2040' + run: find examples/ -name "*.elf" -exec mv {} . \; + + - name: Upload Artifacts for Hardware Test + if: matrix.family == 'rp2040' + uses: actions/upload-artifact@v3 + with: + name: ${{ matrix.family }} + path: | + *.elf + + - name: Trigger Hardware Test + if: matrix.family == 'rp2040' + uses: benc-uk/workflow-dispatch@v1 + with: + workflow: Hardware Test + token: ${{ secrets.TRIGGER_SELF_HOSTED }} + # --------------------------------------- # Build all no-family (orphaned) boards # --------------------------------------- diff --git a/.github/workflows/test_hardware.yml b/.github/workflows/test_hardware.yml new file mode 100644 index 000000000..a39fb6927 --- /dev/null +++ b/.github/workflows/test_hardware.yml @@ -0,0 +1,37 @@ +name: Hardware Test +on: + workflow_dispatch: + +# Hardware in the loop (HIL) +# Current self-hosted instance is running on an RPI4 with +# - pico + pico-probe connected via USB + +jobs: + hw-test: + # Limit the run to only hathach due to limited resource on RPI4 + #if: github.repository_owner == 'hathach' && ${{ github.event.workflow_run.conclusion == 'success' }} + if: github.repository_owner == 'hathach' + runs-on: [self-hosted, Linux, ARM64] + + steps: + - name: Test self-host + run: | + echo "Running on self-hosted" + ls + + - name: Download rp2040 Artifacts + uses: dawidd6/action-download-artifact@v2 + with: + workflow: build_arm.yml + name: rp2040 + + - name: List + run: ls + +# - name: Clean workspace +# run: | +# echo "Cleaning up previous run" +# rm -rf "${{ github.workspace }}" +# mkdir -p "${{ github.workspace }}" + + \ No newline at end of file From d15a86bc69a31fd0637661f44b6a7d53b80a5cad Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 26 Jul 2022 16:49:51 +0700 Subject: [PATCH 436/504] test flash and hw test with cdc msc --- .github/workflows/test_hardware.yml | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/.github/workflows/test_hardware.yml b/.github/workflows/test_hardware.yml index a39fb6927..923cd4f0a 100644 --- a/.github/workflows/test_hardware.yml +++ b/.github/workflows/test_hardware.yml @@ -14,10 +14,11 @@ jobs: runs-on: [self-hosted, Linux, ARM64] steps: - - name: Test self-host + - name: Clean workspace run: | - echo "Running on self-hosted" - ls + echo "Cleaning up previous run" + rm -rf "${{ github.workspace }}" + mkdir -p "${{ github.workspace }}" - name: Download rp2040 Artifacts uses: dawidd6/action-download-artifact@v2 @@ -25,13 +26,13 @@ jobs: workflow: build_arm.yml name: rp2040 - - name: List - run: ls - -# - name: Clean workspace -# run: | -# echo "Cleaning up previous run" -# rm -rf "${{ github.workspace }}" -# mkdir -p "${{ github.workspace }}" - - \ No newline at end of file + - name: Flash cdc_msc + run: openocd -f "interface/picoprobe.cfg" -f "target/rp2040.cfg" -c "program cdc_msc.elf verify reset exit" + + - name: Test + run: | + test -e /dev/ttyACM1 + test -e /media/pi/TinyUSB\ MSC/README.TXT + cat /media/pi/TinyUSB\ MSC/README.TXT + # failed on purpose + test -e /dev/ttyACM2 From 95c0262cd68edbafeb5b8154cf7693d63c26c07f Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 26 Jul 2022 22:55:47 +0700 Subject: [PATCH 437/504] update test --- .github/workflows/test_hardware.yml | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test_hardware.yml b/.github/workflows/test_hardware.yml index 923cd4f0a..93440754e 100644 --- a/.github/workflows/test_hardware.yml +++ b/.github/workflows/test_hardware.yml @@ -5,6 +5,7 @@ on: # Hardware in the loop (HIL) # Current self-hosted instance is running on an RPI4 with # - pico + pico-probe connected via USB +# - pico-probe is /dev/ttyACM0 jobs: hw-test: @@ -26,13 +27,19 @@ jobs: workflow: build_arm.yml name: rp2040 - - name: Flash cdc_msc - run: openocd -f "interface/picoprobe.cfg" -f "target/rp2040.cfg" -c "program cdc_msc.elf verify reset exit" - - - name: Test + - name: Test cdc_dual_ports + env: + example: cdc_dual_ports run: | + openocd -f "interface/picoprobe.cfg" -f "target/rp2040.cfg" -c "program ${{ env.example }}.elf verify reset exit" + test -e /dev/ttyACM1 + test -e /dev/ttyACM2 + + - name: Test cdc_msc + env: + example: cdc_dual_ports + run: | + openocd -f "interface/picoprobe.cfg" -f "target/rp2040.cfg" -c "program ${{ env.example }}.elf verify reset exit" test -e /dev/ttyACM1 test -e /media/pi/TinyUSB\ MSC/README.TXT cat /media/pi/TinyUSB\ MSC/README.TXT - # failed on purpose - test -e /dev/ttyACM2 From f5f2433c5afef3785caeb5251d4cac75e62b77f0 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 27 Jul 2022 11:56:31 +0700 Subject: [PATCH 438/504] wait for enumeration before test --- .github/workflows/test_hardware.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test_hardware.yml b/.github/workflows/test_hardware.yml index 93440754e..30f9e53e8 100644 --- a/.github/workflows/test_hardware.yml +++ b/.github/workflows/test_hardware.yml @@ -32,14 +32,20 @@ jobs: example: cdc_dual_ports run: | openocd -f "interface/picoprobe.cfg" -f "target/rp2040.cfg" -c "program ${{ env.example }}.elf verify reset exit" + echo "Waiting for enumeration" + while ! lsusb | grep "cafe:" ; do : ; done + # Test test -e /dev/ttyACM1 test -e /dev/ttyACM2 - name: Test cdc_msc env: - example: cdc_dual_ports + example: cdc_msc run: | openocd -f "interface/picoprobe.cfg" -f "target/rp2040.cfg" -c "program ${{ env.example }}.elf verify reset exit" + echo "Waiting for enumeration" + while ! lsusb | grep "cafe:" ; do : ; done + # Test test -e /dev/ttyACM1 test -e /media/pi/TinyUSB\ MSC/README.TXT cat /media/pi/TinyUSB\ MSC/README.TXT From 1ff0c7a52b1350e477d75cfc5fd5243cdaedd508 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 27 Jul 2022 15:03:55 +0700 Subject: [PATCH 439/504] sleep 0.2 for new image take affect --- .github/workflows/test_hardware.yml | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/.github/workflows/test_hardware.yml b/.github/workflows/test_hardware.yml index 30f9e53e8..68425a645 100644 --- a/.github/workflows/test_hardware.yml +++ b/.github/workflows/test_hardware.yml @@ -31,21 +31,25 @@ jobs: env: example: cdc_dual_ports run: | - openocd -f "interface/picoprobe.cfg" -f "target/rp2040.cfg" -c "program ${{ env.example }}.elf verify reset exit" - echo "Waiting for enumeration" - while ! lsusb | grep "cafe:" ; do : ; done + openocd -f "interface/picoprobe.cfg" -f "target/rp2040.cfg" -c "program ${{ env.example }}.elf reset exit" + echo "Waiting for enumeration (200 ms for reset, 5s for enumeration)" + sleep 0.2 + SECONDS=0 + while (! lsusb | grep "cafe:") && [ $SECONDS -le 5 ] ; do : ; done # Test - test -e /dev/ttyACM1 - test -e /dev/ttyACM2 + test -e /dev/ttyACM1 && echo "ttyACM1 exists" + test -e /dev/ttyACM2 && echo "ttyACM2 exists" - name: Test cdc_msc env: example: cdc_msc run: | - openocd -f "interface/picoprobe.cfg" -f "target/rp2040.cfg" -c "program ${{ env.example }}.elf verify reset exit" - echo "Waiting for enumeration" - while ! lsusb | grep "cafe:" ; do : ; done + openocd -f "interface/picoprobe.cfg" -f "target/rp2040.cfg" -c "program ${{ env.example }}.elf reset exit" + echo "Waiting for enumeration (200 ms for reset, 5s for enumeration)" + sleep 0.2 + SECONDS=0 + while (! lsusb | grep "cafe:") && [ $SECONDS -le 5 ] ; do : ; done # Test - test -e /dev/ttyACM1 - test -e /media/pi/TinyUSB\ MSC/README.TXT + test -e /dev/ttyACM1 && echo "ttyACM1 exists" + test -f /media/pi/TinyUSB\ MSC/README.TXT && echo "MSC README.TXT exist" cat /media/pi/TinyUSB\ MSC/README.TXT From 05ccd6c32b60994634add3b4b867870dab27aca5 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 27 Jul 2022 15:44:21 +0700 Subject: [PATCH 440/504] more hw test update --- .github/workflows/test_hardware.yml | 30 ++++++++++++----------------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/.github/workflows/test_hardware.yml b/.github/workflows/test_hardware.yml index 68425a645..1470effd4 100644 --- a/.github/workflows/test_hardware.yml +++ b/.github/workflows/test_hardware.yml @@ -15,12 +15,20 @@ jobs: runs-on: [self-hosted, Linux, ARM64] steps: - - name: Clean workspace + - name: Prepare workspace run: | echo "Cleaning up previous run" rm -rf "${{ github.workspace }}" mkdir -p "${{ github.workspace }}" - + echo "Create flash.sh" + touch flash.sh + chmod +x flash.sh + echo >> flash.sh 'openocd -f "interface/picoprobe.cfg" -f "target/rp2040.cfg" -c "program $1.elf reset exit"' + echo >> flash.sh '"Waiting for enumeration (500 ms for reset, 5s for enumeration)"' + echo >> flash.sh 'sleep 0.5' + echo >> flash.sh 'SECONDS=0' + echo >> flash.sh 'while (! lsusb | grep "cafe:") && [ $SECONDS -le 5 ] ; do : ; done' + - name: Download rp2040 Artifacts uses: dawidd6/action-download-artifact@v2 with: @@ -28,28 +36,14 @@ jobs: name: rp2040 - name: Test cdc_dual_ports - env: - example: cdc_dual_ports run: | - openocd -f "interface/picoprobe.cfg" -f "target/rp2040.cfg" -c "program ${{ env.example }}.elf reset exit" - echo "Waiting for enumeration (200 ms for reset, 5s for enumeration)" - sleep 0.2 - SECONDS=0 - while (! lsusb | grep "cafe:") && [ $SECONDS -le 5 ] ; do : ; done - # Test + ./flash_sh cdc_dual_ports test -e /dev/ttyACM1 && echo "ttyACM1 exists" test -e /dev/ttyACM2 && echo "ttyACM2 exists" - name: Test cdc_msc - env: - example: cdc_msc run: | - openocd -f "interface/picoprobe.cfg" -f "target/rp2040.cfg" -c "program ${{ env.example }}.elf reset exit" - echo "Waiting for enumeration (200 ms for reset, 5s for enumeration)" - sleep 0.2 - SECONDS=0 - while (! lsusb | grep "cafe:") && [ $SECONDS -le 5 ] ; do : ; done - # Test + ./flash.sh cdc_msc test -e /dev/ttyACM1 && echo "ttyACM1 exists" test -f /media/pi/TinyUSB\ MSC/README.TXT && echo "MSC README.TXT exist" cat /media/pi/TinyUSB\ MSC/README.TXT From 4411579ae099acbcf4559c691a0fb67b2596b52c Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 27 Jul 2022 16:08:08 +0700 Subject: [PATCH 441/504] ci update --- .github/workflows/test_hardware.yml | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/.github/workflows/test_hardware.yml b/.github/workflows/test_hardware.yml index 1470effd4..b5e0831d4 100644 --- a/.github/workflows/test_hardware.yml +++ b/.github/workflows/test_hardware.yml @@ -15,33 +15,38 @@ jobs: runs-on: [self-hosted, Linux, ARM64] steps: - - name: Prepare workspace + - name: Clean workspace run: | echo "Cleaning up previous run" rm -rf "${{ github.workspace }}" mkdir -p "${{ github.workspace }}" - echo "Create flash.sh" - touch flash.sh - chmod +x flash.sh - echo >> flash.sh 'openocd -f "interface/picoprobe.cfg" -f "target/rp2040.cfg" -c "program $1.elf reset exit"' - echo >> flash.sh '"Waiting for enumeration (500 ms for reset, 5s for enumeration)"' - echo >> flash.sh 'sleep 0.5' - echo >> flash.sh 'SECONDS=0' - echo >> flash.sh 'while (! lsusb | grep "cafe:") && [ $SECONDS -le 5 ] ; do : ; done' - name: Download rp2040 Artifacts uses: dawidd6/action-download-artifact@v2 with: workflow: build_arm.yml name: rp2040 - + + - name: Create flash.sh + #working-directory: ${{github.workspace}} + run: | + touch flash.sh + chmod +x flash.sh + echo > flash.sh 'openocd -f "interface/picoprobe.cfg" -f "target/rp2040.cfg" -c "program $1.elf reset exit"' + echo >> flash.sh '"Waiting for enumeration (500 ms for reset, 5s for enumeration)"' + echo >> flash.sh 'sleep 0.5' + echo >> flash.sh 'SECONDS=0' + echo >> flash.sh 'while (! lsusb | grep "cafe:") && [ $SECONDS -le 5 ] ; do : ; done' + - name: Test cdc_dual_ports + #working-directory: ${{github.workspace}} run: | ./flash_sh cdc_dual_ports test -e /dev/ttyACM1 && echo "ttyACM1 exists" test -e /dev/ttyACM2 && echo "ttyACM2 exists" - name: Test cdc_msc + #working-directory: ${{github.workspace}} run: | ./flash.sh cdc_msc test -e /dev/ttyACM1 && echo "ttyACM1 exists" From 2d5be437472d2da573bae0c1e64ee8e017391dfe Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 27 Jul 2022 20:31:57 +0700 Subject: [PATCH 442/504] fix typo --- .github/workflows/test_hardware.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test_hardware.yml b/.github/workflows/test_hardware.yml index b5e0831d4..77b95bfee 100644 --- a/.github/workflows/test_hardware.yml +++ b/.github/workflows/test_hardware.yml @@ -41,7 +41,7 @@ jobs: - name: Test cdc_dual_ports #working-directory: ${{github.workspace}} run: | - ./flash_sh cdc_dual_ports + ./flash.sh cdc_dual_ports test -e /dev/ttyACM1 && echo "ttyACM1 exists" test -e /dev/ttyACM2 && echo "ttyACM2 exists" From e01b437af5581794618ff031b3f8d6614bb46cec Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 28 Jul 2022 11:10:54 +0700 Subject: [PATCH 443/504] more hw test --- .github/workflows/test_hardware.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test_hardware.yml b/.github/workflows/test_hardware.yml index 77b95bfee..50353474b 100644 --- a/.github/workflows/test_hardware.yml +++ b/.github/workflows/test_hardware.yml @@ -33,15 +33,16 @@ jobs: touch flash.sh chmod +x flash.sh echo > flash.sh 'openocd -f "interface/picoprobe.cfg" -f "target/rp2040.cfg" -c "program $1.elf reset exit"' - echo >> flash.sh '"Waiting for enumeration (500 ms for reset, 5s for enumeration)"' + echo >> flash.sh 'echo "Waiting for 0.5s for reset"' echo >> flash.sh 'sleep 0.5' echo >> flash.sh 'SECONDS=0' - echo >> flash.sh 'while (! lsusb | grep "cafe:") && [ $SECONDS -le 5 ] ; do : ; done' + echo >> flash.sh 'lsusb | grep "cafe:"' - name: Test cdc_dual_ports #working-directory: ${{github.workspace}} run: | ./flash.sh cdc_dual_ports + while ! ([ -e /dev/ttyACM1 ] && [ -e /dev/ttyACM2 ]) && [$SECONDS -le 5]; do :; done test -e /dev/ttyACM1 && echo "ttyACM1 exists" test -e /dev/ttyACM2 && echo "ttyACM2 exists" @@ -49,6 +50,8 @@ jobs: #working-directory: ${{github.workspace}} run: | ./flash.sh cdc_msc + while ! ([ -e /dev/ttyACM1 ] && [ -e /dev/sda ]) && [$SECONDS -le 5]; do :; done test -e /dev/ttyACM1 && echo "ttyACM1 exists" + test -e /dev/sda && echo "sda exists" test -f /media/pi/TinyUSB\ MSC/README.TXT && echo "MSC README.TXT exist" cat /media/pi/TinyUSB\ MSC/README.TXT From 229a1c145801861401392184c818f0c87766d601 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 28 Jul 2022 11:37:09 +0700 Subject: [PATCH 444/504] update hw test --- .github/workflows/test_hardware.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test_hardware.yml b/.github/workflows/test_hardware.yml index 50353474b..eefdb4c0a 100644 --- a/.github/workflows/test_hardware.yml +++ b/.github/workflows/test_hardware.yml @@ -42,7 +42,8 @@ jobs: #working-directory: ${{github.workspace}} run: | ./flash.sh cdc_dual_ports - while ! ([ -e /dev/ttyACM1 ] && [ -e /dev/ttyACM2 ]) && [$SECONDS -le 5]; do :; done + echo $SECONDS + while (! ([ -e /dev/ttyACM1 ] && [ -e /dev/ttyACM2 ])) && [$SECONDS -le 5]; do :; done test -e /dev/ttyACM1 && echo "ttyACM1 exists" test -e /dev/ttyACM2 && echo "ttyACM2 exists" @@ -50,7 +51,8 @@ jobs: #working-directory: ${{github.workspace}} run: | ./flash.sh cdc_msc - while ! ([ -e /dev/ttyACM1 ] && [ -e /dev/sda ]) && [$SECONDS -le 5]; do :; done + echo $SECONDS + while (! ([ -e /dev/ttyACM1 ] && [ -e /dev/sda ])) && [$SECONDS -le 5]; do :; done test -e /dev/ttyACM1 && echo "ttyACM1 exists" test -e /dev/sda && echo "sda exists" test -f /media/pi/TinyUSB\ MSC/README.TXT && echo "MSC README.TXT exist" From d36ea6ddc1674c03764d69708cea63b5631e6766 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 28 Jul 2022 12:23:01 +0700 Subject: [PATCH 445/504] update issue template --- .github/ISSUE_TEMPLATE/bug_report.yml | 8 ++++ .github/ISSUE_TEMPLATE/feature_request.md | 14 ------- .github/ISSUE_TEMPLATE/feature_request.yml | 49 ++++++++++++++++++++++ 3 files changed, 57 insertions(+), 14 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index c0b520e35..2958d3b12 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -76,3 +76,11 @@ body: description: If applicable, add screenshots to help explain your problem. validations: required: false + + - type: checkboxes + attributes: + label: I have checked existing issues, dicussion and documentation + description: You agree to check all the resources above before opening a new issue. + options: + - label: I confirm I have checked existing issues, dicussion and documentation. + required: true diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 562d3113b..000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: Feature Request -about: Suggest an idea for this project -title: '' -labels: Feature 💡 -assignees: '' - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 000000000..e168b73a6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,49 @@ +name: Feature Request +description: Suggest an idea for this project +labels: 'Feature 💡' +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this request! + It's okay to leave some blank if it doesn't apply to your request. + + - type: input + attributes: + label: Related area + description: Please briefly explain the area of your Feature Request. + placeholder: eg. new port support, device stack, class driver ... + validations: + required: true + + - type: input + attributes: + label: Hardware specification + description: Please provide if your proposal depends on specific Hardware. + placeholder: eg. rp2040, samd51 ... + validations: + required: true + + - type: textarea + attributes: + label: Is your feature request related to a problem? + description: Please provide a clear and concise description of what the problem is. Add relevant issue link. + placeholder: ex. I'm facing the issue/missing function... + validations: + required: true + + - type: textarea + attributes: + label: Describe the solution you'd like + description: Please provide a clear and concise description of what you want to happen. + placeholder: ex. When using this function... + validations: + required: true + + - type: checkboxes + attributes: + label: I have checked existing issues, dicussion and documentation + description: You agree to check all the resources above before opening a new issue. + options: + - label: I confirm I have checked existing issues, dicussion and documentation. + required: true From cbb7c9f313f8e8e29ba448ecd3ad07ca36d83309 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 28 Jul 2022 13:31:42 +0700 Subject: [PATCH 446/504] fix hw test --- .github/workflows/test_hardware.yml | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/.github/workflows/test_hardware.yml b/.github/workflows/test_hardware.yml index eefdb4c0a..77d4c2527 100644 --- a/.github/workflows/test_hardware.yml +++ b/.github/workflows/test_hardware.yml @@ -33,27 +33,29 @@ jobs: touch flash.sh chmod +x flash.sh echo > flash.sh 'openocd -f "interface/picoprobe.cfg" -f "target/rp2040.cfg" -c "program $1.elf reset exit"' - echo >> flash.sh 'echo "Waiting for 0.5s for reset"' - echo >> flash.sh 'sleep 0.5' - echo >> flash.sh 'SECONDS=0' - echo >> flash.sh 'lsusb | grep "cafe:"' + # echo >> flash.sh 'echo "Waiting for 0.5s for reset"' + # echo >> flash.sh 'sleep 0.5' + # echo >> flash.sh 'SECONDS=0' + # echo >> flash.sh 'lsusb | grep "cafe:"' - name: Test cdc_dual_ports - #working-directory: ${{github.workspace}} run: | + echo "Second = $SECONDS" ./flash.sh cdc_dual_ports + echo "Second = $SECONDS" + while (! ([ -e /dev/ttyACM1 ] && [ -e /dev/ttyACM2 ])) && [ $SECONDS -le 5 ]; do :; done echo $SECONDS - while (! ([ -e /dev/ttyACM1 ] && [ -e /dev/ttyACM2 ])) && [$SECONDS -le 5]; do :; done test -e /dev/ttyACM1 && echo "ttyACM1 exists" test -e /dev/ttyACM2 && echo "ttyACM2 exists" - name: Test cdc_msc - #working-directory: ${{github.workspace}} run: | + readme='/media/pi/TinyUSB MSC/README.TXT' + echo "Second = $SECONDS" ./flash.sh cdc_msc - echo $SECONDS - while (! ([ -e /dev/ttyACM1 ] && [ -e /dev/sda ])) && [$SECONDS -le 5]; do :; done + echo "Second = $SECONDS" + while (! ([ -e /dev/ttyACM1 ] && [ -f "$readme" ])) && [ $SECONDS -le 5 ]; do :; done + echo "Second = $SECONDS" test -e /dev/ttyACM1 && echo "ttyACM1 exists" - test -e /dev/sda && echo "sda exists" - test -f /media/pi/TinyUSB\ MSC/README.TXT && echo "MSC README.TXT exist" - cat /media/pi/TinyUSB\ MSC/README.TXT + test -f "$readme" && echo "$readme exists" + cat "$readme" From 292dea408fe05d9c46ba7ad0b7d317edfb692e11 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 28 Jul 2022 21:27:38 +0700 Subject: [PATCH 447/504] add dfu test --- .github/workflows/test_hardware.yml | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test_hardware.yml b/.github/workflows/test_hardware.yml index 77d4c2527..5326ca823 100644 --- a/.github/workflows/test_hardware.yml +++ b/.github/workflows/test_hardware.yml @@ -28,7 +28,6 @@ jobs: name: rp2040 - name: Create flash.sh - #working-directory: ${{github.workspace}} run: | touch flash.sh chmod +x flash.sh @@ -40,22 +39,31 @@ jobs: - name: Test cdc_dual_ports run: | + #SECONDS=0 echo "Second = $SECONDS" ./flash.sh cdc_dual_ports - echo "Second = $SECONDS" while (! ([ -e /dev/ttyACM1 ] && [ -e /dev/ttyACM2 ])) && [ $SECONDS -le 5 ]; do :; done - echo $SECONDS test -e /dev/ttyACM1 && echo "ttyACM1 exists" test -e /dev/ttyACM2 && echo "ttyACM2 exists" - name: Test cdc_msc run: | - readme='/media/pi/TinyUSB MSC/README.TXT' + #SECONDS=0 echo "Second = $SECONDS" ./flash.sh cdc_msc - echo "Second = $SECONDS" + readme='/media/pi/TinyUSB MSC/README.TXT' while (! ([ -e /dev/ttyACM1 ] && [ -f "$readme" ])) && [ $SECONDS -le 5 ]; do :; done - echo "Second = $SECONDS" test -e /dev/ttyACM1 && echo "ttyACM1 exists" test -f "$readme" && echo "$readme exists" cat "$readme" + + - name: Test dfu + run: | + #SECONDS=0 + echo "Second = $SECONDS" + ./flash.sh dfu + while (! (dfu-util -l | grep "Found DFU")) && [ $SECONDS -le 5 ]; do :; done + dfu-util -d cafe -a 0 -U dfu0 + dfu-util -d cafe -a 1 -U dfu1 + grep "TinyUSB DFU! - Partition 0" dfu0 + grep "TinyUSB DFU! - Partition 1" dfu1 From aa8880c681f8d8549e17028cde41c6457b19c66e Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 28 Jul 2022 22:13:39 +0700 Subject: [PATCH 448/504] clean up --- .github/workflows/test_hardware.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.github/workflows/test_hardware.yml b/.github/workflows/test_hardware.yml index 5326ca823..eb24b5351 100644 --- a/.github/workflows/test_hardware.yml +++ b/.github/workflows/test_hardware.yml @@ -32,15 +32,9 @@ jobs: touch flash.sh chmod +x flash.sh echo > flash.sh 'openocd -f "interface/picoprobe.cfg" -f "target/rp2040.cfg" -c "program $1.elf reset exit"' - # echo >> flash.sh 'echo "Waiting for 0.5s for reset"' - # echo >> flash.sh 'sleep 0.5' - # echo >> flash.sh 'SECONDS=0' - # echo >> flash.sh 'lsusb | grep "cafe:"' - name: Test cdc_dual_ports run: | - #SECONDS=0 - echo "Second = $SECONDS" ./flash.sh cdc_dual_ports while (! ([ -e /dev/ttyACM1 ] && [ -e /dev/ttyACM2 ])) && [ $SECONDS -le 5 ]; do :; done test -e /dev/ttyACM1 && echo "ttyACM1 exists" @@ -48,8 +42,6 @@ jobs: - name: Test cdc_msc run: | - #SECONDS=0 - echo "Second = $SECONDS" ./flash.sh cdc_msc readme='/media/pi/TinyUSB MSC/README.TXT' while (! ([ -e /dev/ttyACM1 ] && [ -f "$readme" ])) && [ $SECONDS -le 5 ]; do :; done @@ -59,8 +51,6 @@ jobs: - name: Test dfu run: | - #SECONDS=0 - echo "Second = $SECONDS" ./flash.sh dfu while (! (dfu-util -l | grep "Found DFU")) && [ $SECONDS -le 5 ]; do :; done dfu-util -d cafe -a 0 -U dfu0 From 4a47db97eb36c36319b1b434ac1f577ad77fb68c Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 29 Jul 2022 11:32:17 +0700 Subject: [PATCH 449/504] test hw dfu_runtime --- .github/workflows/build_arm.yml | 6 +++--- .github/workflows/test_hardware.yml | 6 +++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml index 64322082d..a321948e3 100644 --- a/.github/workflows/build_arm.yml +++ b/.github/workflows/build_arm.yml @@ -108,11 +108,11 @@ jobs: # Following steps are for Hardware Test with self-hosted - name: Prepare Artifacts - if: matrix.family == 'rp2040' + if: matrix.family == 'rp2040' && github.repository_owner == 'hathach' run: find examples/ -name "*.elf" -exec mv {} . \; - name: Upload Artifacts for Hardware Test - if: matrix.family == 'rp2040' + if: matrix.family == 'rp2040' && github.repository_owner == 'hathach' uses: actions/upload-artifact@v3 with: name: ${{ matrix.family }} @@ -120,7 +120,7 @@ jobs: *.elf - name: Trigger Hardware Test - if: matrix.family == 'rp2040' + if: matrix.family == 'rp2040' && github.repository_owner == 'hathach' uses: benc-uk/workflow-dispatch@v1 with: workflow: Hardware Test diff --git a/.github/workflows/test_hardware.yml b/.github/workflows/test_hardware.yml index eb24b5351..2fbfcb991 100644 --- a/.github/workflows/test_hardware.yml +++ b/.github/workflows/test_hardware.yml @@ -10,7 +10,6 @@ on: jobs: hw-test: # Limit the run to only hathach due to limited resource on RPI4 - #if: github.repository_owner == 'hathach' && ${{ github.event.workflow_run.conclusion == 'success' }} if: github.repository_owner == 'hathach' runs-on: [self-hosted, Linux, ARM64] @@ -57,3 +56,8 @@ jobs: dfu-util -d cafe -a 1 -U dfu1 grep "TinyUSB DFU! - Partition 0" dfu0 grep "TinyUSB DFU! - Partition 1" dfu1 + + - name: Test dfu + run: | + ./flash.sh dfu_runtime + while (! (dfu-util -l | grep "Found Runtime")) && [ $SECONDS -le 5 ]; do :; done From fe7fca7abbea02b9f0ac8f53bf4ca1d1019c6e85 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 1 Aug 2022 14:42:58 +0700 Subject: [PATCH 450/504] minor clean up --- .github/workflows/test_hardware.yml | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test_hardware.yml b/.github/workflows/test_hardware.yml index 2fbfcb991..7a6e2a470 100644 --- a/.github/workflows/test_hardware.yml +++ b/.github/workflows/test_hardware.yml @@ -30,18 +30,18 @@ jobs: run: | touch flash.sh chmod +x flash.sh - echo > flash.sh 'openocd -f "interface/picoprobe.cfg" -f "target/rp2040.cfg" -c "program $1.elf reset exit"' + echo > flash.sh 'openocd -f "interface/picoprobe.cfg" -f "target/rp2040.cfg" -c "program $1 reset exit"' - name: Test cdc_dual_ports run: | - ./flash.sh cdc_dual_ports + ./flash.sh cdc_dual_ports.elf while (! ([ -e /dev/ttyACM1 ] && [ -e /dev/ttyACM2 ])) && [ $SECONDS -le 5 ]; do :; done test -e /dev/ttyACM1 && echo "ttyACM1 exists" test -e /dev/ttyACM2 && echo "ttyACM2 exists" - name: Test cdc_msc run: | - ./flash.sh cdc_msc + ./flash.sh cdc_msc.elf readme='/media/pi/TinyUSB MSC/README.TXT' while (! ([ -e /dev/ttyACM1 ] && [ -f "$readme" ])) && [ $SECONDS -le 5 ]; do :; done test -e /dev/ttyACM1 && echo "ttyACM1 exists" @@ -50,14 +50,20 @@ jobs: - name: Test dfu run: | - ./flash.sh dfu + ./flash.sh dfu.elf while (! (dfu-util -l | grep "Found DFU")) && [ $SECONDS -le 5 ]; do :; done dfu-util -d cafe -a 0 -U dfu0 dfu-util -d cafe -a 1 -U dfu1 grep "TinyUSB DFU! - Partition 0" dfu0 grep "TinyUSB DFU! - Partition 1" dfu1 - - name: Test dfu + - name: Test dfu_runtime run: | - ./flash.sh dfu_runtime + ./flash.sh dfu_runtime.elf while (! (dfu-util -l | grep "Found Runtime")) && [ $SECONDS -le 5 ]; do :; done + +# - name: Test hid_boot_interface +# run: | +# ./flash.sh hid_boot_interface.elf +# while (! (dfu-util -l | grep "Found Runtime")) && [ $SECONDS -le 5 ]; do :; done + \ No newline at end of file From a219ba86eaf9d5ce1b90556053940daadd8527b5 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 1 Aug 2022 14:52:29 +0700 Subject: [PATCH 451/504] fix issue with TUD_OPT_HIGH_SPEED --- src/tusb_option.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tusb_option.h b/src/tusb_option.h index 70ef1c399..e0447b10c 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -223,7 +223,7 @@ typedef int make_iso_compilers_happy; #define TUSB_OPT_DEVICE_ENABLED CFG_TUD_ENABLED // highspeed support indicator -#define TUD_OPT_HIGH_SPEED (CFG_TUD_MAX_SPEED ? CFG_TUD_MAX_SPEED : TUP_RHPORT_HIGHSPEED) +#define TUD_OPT_HIGH_SPEED (CFG_TUD_MAX_SPEED ? (CFG_TUD_MAX_SPEED & OPT_MODE_HIGH_SPEED) : TUP_RHPORT_HIGHSPEED) //------------- Roothub as Host -------------// From d1c61e33a617439258605555947a1ffc78519674 Mon Sep 17 00:00:00 2001 From: Peter Lawrence <12226419+majbthrd@users.noreply.github.com> Date: Wed, 3 Aug 2022 12:28:50 -0500 Subject: [PATCH 452/504] add 'stm32l052dap52' (STM32L052K8 MCU) board target 'dap52' is Olimex's name of their STM32L052-based fork of 'dap42' --- examples/device/uac2_headset/skip.txt | 3 +- .../stm32l052dap52/STM32L052K8Ux_FLASH.ld | 169 +++++++++ hw/bsp/stm32l0/boards/stm32l052dap52/board.h | 109 ++++++ hw/bsp/stm32l0/boards/stm32l052dap52/board.mk | 11 + hw/bsp/stm32l0/family.c | 181 ++++++++++ hw/bsp/stm32l0/family.mk | 40 +++ hw/bsp/stm32l0/stm32l0xx_hal_conf.h | 338 ++++++++++++++++++ 7 files changed, 850 insertions(+), 1 deletion(-) create mode 100644 hw/bsp/stm32l0/boards/stm32l052dap52/STM32L052K8Ux_FLASH.ld create mode 100644 hw/bsp/stm32l0/boards/stm32l052dap52/board.h create mode 100644 hw/bsp/stm32l0/boards/stm32l052dap52/board.mk create mode 100644 hw/bsp/stm32l0/family.c create mode 100644 hw/bsp/stm32l0/family.mk create mode 100644 hw/bsp/stm32l0/stm32l0xx_hal_conf.h diff --git a/examples/device/uac2_headset/skip.txt b/examples/device/uac2_headset/skip.txt index 9471822a4..70d8e8838 100644 --- a/examples/device/uac2_headset/skip.txt +++ b/examples/device/uac2_headset/skip.txt @@ -3,4 +3,5 @@ mcu:LPC13XX mcu:NUC121 mcu:SAMD11 mcu:SAME5X -mcu:SAMG \ No newline at end of file +mcu:SAMG +board:stm32l052dap52 diff --git a/hw/bsp/stm32l0/boards/stm32l052dap52/STM32L052K8Ux_FLASH.ld b/hw/bsp/stm32l0/boards/stm32l052dap52/STM32L052K8Ux_FLASH.ld new file mode 100644 index 000000000..1bc16cc7b --- /dev/null +++ b/hw/bsp/stm32l0/boards/stm32l052dap52/STM32L052K8Ux_FLASH.ld @@ -0,0 +1,169 @@ +/* +***************************************************************************** +** + +** File : LinkerScript.ld +** +** Abstract : Linker script for STM32L052K8Ux Device with +** 64KByte FLASH, 8KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +** (c)Copyright Ac6. +** You may use this file as-is or modify it according to the needs of your +** project. Distribution of this file (unmodified or modified) is not +** permitted. Ac6 permit registered System Workbench for MCU users the +** rights to distribute the assembled, compiled & linked contents of this +** file as part of an application binary file, provided that it is built +** using the System Workbench for MCU toolchain. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20002000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 64K +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* 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); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + + diff --git a/hw/bsp/stm32l0/boards/stm32l052dap52/board.h b/hw/bsp/stm32l0/boards/stm32l052dap52/board.h new file mode 100644 index 000000000..8ad3e43c8 --- /dev/null +++ b/hw/bsp/stm32l0/boards/stm32l052dap52/board.h @@ -0,0 +1,109 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, 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 BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// LED +#define LED_PORT GPIOB +#define LED_PIN GPIO_PIN_4 +#define LED_STATE_ON 1 + +// Button +#define BUTTON_PORT GPIOA +#define BUTTON_PIN GPIO_PIN_6 +#define BUTTON_STATE_ACTIVE 0 + +// UART +#define UART_DEV USART2 +#define UART_CLK_EN __HAL_RCC_USART2_CLK_ENABLE +#define UART_GPIO_PORT GPIOA +#define UART_GPIO_AF GPIO_AF4_USART2 +#define UART_TX_PIN GPIO_PIN_2 +#define UART_RX_PIN GPIO_PIN_3 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_stm32l0_clock_init(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; + static RCC_CRSInitTypeDef RCC_CRSInitStruct; + + /* Enable HSI Oscillator to be used as System clock source + Enable HSI48 Oscillator to be used as USB clock source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSI48; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Select HSI48 as USB clock source */ + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; + PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + + /* Select HSI as system clock source and configure the HCLK, PCLK1 and PCLK2 + clock dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0); + + /*Configure the clock recovery system (CRS)**********************************/ + + /*Enable CRS Clock*/ + __HAL_RCC_CRS_CLK_ENABLE(); + + /* Default Synchro Signal division factor (not divided) */ + RCC_CRSInitStruct.Prescaler = RCC_CRS_SYNC_DIV1; + /* Set the SYNCSRC[1:0] bits according to CRS_Source value */ + RCC_CRSInitStruct.Source = RCC_CRS_SYNC_SOURCE_USB; + /* HSI48 is synchronized with USB SOF at 1KHz rate */ + RCC_CRSInitStruct.ReloadValue = __HAL_RCC_CRS_RELOADVALUE_CALCULATE(48000000, 1000); + RCC_CRSInitStruct.ErrorLimitValue = RCC_CRS_ERRORLIMIT_DEFAULT; + /* Set the TRIM[5:0] to the default value*/ + RCC_CRSInitStruct.HSI48CalibrationValue = 0x20; + /* Start automatic synchronization */ + HAL_RCCEx_CRSConfig (&RCC_CRSInitStruct); +} + +static inline void board_vbus_sense_init(void) +{ +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/stm32l0/boards/stm32l052dap52/board.mk b/hw/bsp/stm32l0/boards/stm32l052dap52/board.mk new file mode 100644 index 000000000..84662344d --- /dev/null +++ b/hw/bsp/stm32l0/boards/stm32l052dap52/board.mk @@ -0,0 +1,11 @@ +CFLAGS += -DSTM32L052xx -DCFG_EXAMPLE_VIDEO_READONLY + +LD_FILE = $(BOARD_PATH)/STM32L052K8Ux_FLASH.ld + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32l052xx.s + +# For flash-jlink target +JLINK_DEVICE = stm32l052k8 + +# flash target using on-board stlink +flash: flash-stlink diff --git a/hw/bsp/stm32l0/family.c b/hw/bsp/stm32l0/family.c new file mode 100644 index 000000000..80a7c7435 --- /dev/null +++ b/hw/bsp/stm32l0/family.c @@ -0,0 +1,181 @@ +/* + * 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. + */ + +#include "stm32l0xx_hal.h" +#include "bsp/board.h" +#include "board.h" + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void USB_IRQHandler(void) +{ + tud_int_handler(0); +} + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ +UART_HandleTypeDef UartHandle; + +void board_init(void) +{ + board_stm32l0_clock_init(); + + // Enable All GPIOs clocks + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + + // Enable UART Clock + UART_CLK_EN(); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); + +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // Explicitly disable systick to prevent its ISR runs before scheduler start + SysTick->CTRL &= ~1U; + + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); +#endif + + // LED + GPIO_InitTypeDef GPIO_InitStruct; + GPIO_InitStruct.Pin = LED_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct); + + // Button + GPIO_InitStruct.Pin = BUTTON_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); + + // Uart + GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = UART_GPIO_AF; + HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); + + UartHandle.Instance = UART_DEV; + UartHandle.Init.BaudRate = CFG_BOARD_UART_BAUDRATE; + UartHandle.Init.WordLength = UART_WORDLENGTH_8B; + UartHandle.Init.StopBits = UART_STOPBITS_1; + UartHandle.Init.Parity = UART_PARITY_NONE; + UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; + UartHandle.Init.Mode = UART_MODE_TX_RX; + UartHandle.Init.OverSampling = UART_OVERSAMPLING_16; + HAL_UART_Init(&UartHandle); + + // USB Pins + // Configure USB DM and DP pins. This is optional, and maintained only for user guidance. + GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + // USB Clock enable + __HAL_RCC_USB_CLK_ENABLE(); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +} + +uint32_t board_button_read(void) +{ + return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); +} + +int board_uart_read(uint8_t* buf, int len) +{ + (void) buf; (void) len; + return 0; +} + +int board_uart_write(void const * buf, int len) +{ + HAL_UART_Transmit(&UartHandle, (uint8_t*)(uintptr_t) buf, len, 0xffff); + return len; +} + +#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; +} +#endif + +void HardFault_Handler (void) +{ + asm("bkpt"); +} + +#ifdef USE_FULL_ASSERT +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t* file, uint32_t line) +{ + (void) file; (void) 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 */ + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void) +{ + +} diff --git a/hw/bsp/stm32l0/family.mk b/hw/bsp/stm32l0/family.mk new file mode 100644 index 000000000..622fa61e0 --- /dev/null +++ b/hw/bsp/stm32l0/family.mk @@ -0,0 +1,40 @@ +ST_FAMILY = l0 +DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/st/cmsis_device_$(ST_FAMILY) hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) +ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +include $(TOP)/$(BOARD_PATH)/board.mk + +CFLAGS += \ + -flto \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m0plus \ + -mfloat-abi=soft \ + -nostdlib -nostartfiles \ + -DCFG_EXAMPLE_MSC_READONLY \ + -DCFG_EXAMPLE_VIDEO_READONLY \ + -DCFG_TUSB_MCU=OPT_MCU_STM32L0 + +# suppress warning caused by vendor mcu driver +CFLAGS += -Wno-error=unused-parameter -Wno-error=redundant-decls -Wno-error=cast-align -Wno-error=maybe-uninitialized + +SRC_C += \ + src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ + $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + $(TOP)/$(ST_CMSIS)/Include \ + $(TOP)/$(ST_HAL_DRIVER)/Inc + +# For freeRTOS port source +FREERTOS_PORT = ARM_CM0 diff --git a/hw/bsp/stm32l0/stm32l0xx_hal_conf.h b/hw/bsp/stm32l0/stm32l0xx_hal_conf.h new file mode 100644 index 000000000..cc20ea8e0 --- /dev/null +++ b/hw/bsp/stm32l0/stm32l0xx_hal_conf.h @@ -0,0 +1,338 @@ +/** + ****************************************************************************** + * @file stm32l0xx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration template file. + * This file should be copied to the application folder and renamed + * to stm32l0xx_hal_conf.h. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L0xx_HAL_CONF_H +#define __STM32L0xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/*#define HAL_ADC_MODULE_ENABLED */ +/*#define HAL_COMP_MODULE_ENABLED */ +/*#define HAL_CRC_MODULE_ENABLED */ +/*#define HAL_CRYP_MODULE_ENABLED */ +/*#define HAL_DAC_MODULE_ENABLED */ +#define HAL_DMA_MODULE_ENABLED +/*#define HAL_FIREWALL_MODULE_ENABLED */ +#define HAL_FLASH_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +/*#define HAL_I2C_MODULE_ENABLED */ +/*#define HAL_I2S_MODULE_ENABLED */ +/*#define HAL_IWDG_MODULE_ENABLED */ +/*#define HAL_LCD_MODULE_ENABLED */ +/*#define HAL_LPTIM_MODULE_ENABLED */ +#define HAL_PWR_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +/*#define HAL_RNG_MODULE_ENABLED */ +/*#define HAL_RTC_MODULE_ENABLED */ +/*#define HAL_SPI_MODULE_ENABLED */ +/*#define HAL_TIM_MODULE_ENABLED */ +/*#define HAL_TSC_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/*#define HAL_USART_MODULE_ENABLED */ +/*#define HAL_IRDA_MODULE_ENABLED */ +/*#define HAL_SMARTCARD_MODULE_ENABLED */ +/*#define HAL_SMBUS_MODULE_ENABLED */ +/*#define HAL_WWDG_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED +#define HAL_PCD_MODULE_ENABLED + +/* ########################## Oscillator Values adaptation ####################*/ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal Multiple Speed oscillator (MSI) default value. + * This value is the default MSI range value after Reset. + */ +#if !defined (MSI_VALUE) + #define MSI_VALUE ((uint32_t)2097152U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* MSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal High Speed oscillator for USB (HSI48) value. + */ +#if !defined (HSI48_VALUE) +#define HSI48_VALUE ((uint32_t)48000000U) /*!< Value of the Internal High Speed oscillator for USB in Hz. + The real value may vary depending on the variations + in voltage and temperature. */ +#endif /* HSI48_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE ((uint32_t)37000U) /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature.*/ +/** + * @brief External Low Speed oscillator (LSE) value. + * This value is used by the UART, RTC HAL module to compute the system frequency + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External oscillator in Hz*/ +#endif /* LSE_VALUE */ + +/** + * @brief Time out for LSE start up value in ms. + */ +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY (((uint32_t)1U<<__NVIC_PRIO_BITS) - 1U) /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define PREREAD_ENABLE 0U +#define BUFFER_CACHE_DISABLE 0U + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + + +/* ################## Register callback feature configuration ############### */ +/** + * @brief Set below the peripheral configuration to "1U" to add the support + * of HAL callback registration/deregistration feature for the HAL + * driver(s). This allows user application to provide specific callback + * functions thanks to HAL_PPP_RegisterCallback() rather than overwriting + * the default weak callback functions (see each stm32l0xx_hal_ppp.h file + * for possible callback identifiers defined in HAL_PPP_CallbackIDTypeDef + * for each PPP peripheral). + */ +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U +#define USE_HAL_COMP_REGISTER_CALLBACKS 0U +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U +#define USE_HAL_TSC_REGISTER_CALLBACKS 0U +#define USE_HAL_UART_REGISTER_CALLBACKS 0U +#define USE_HAL_USART_REGISTER_CALLBACKS 0U +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver + * Activated: CRC code is present inside driver + * Deactivated: CRC code cleaned from driver + */ + +#define USE_SPI_CRC 1U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32l0xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32l0xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32l0xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32l0xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32l0xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED + #include "stm32l0xx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32l0xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32l0xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32l0xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_FIREWALL_MODULE_ENABLED + #include "stm32l0xx_hal_firewall.h" +#endif /* HAL_FIREWALL_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32l0xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32l0xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32l0xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32l0xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LCD_MODULE_ENABLED + #include "stm32l0xx_hal_lcd.h" +#endif /* HAL_LCD_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED +#include "stm32l0xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32l0xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32l0xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32l0xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32l0xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32l0xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_TSC_MODULE_ENABLED + #include "stm32l0xx_hal_tsc.h" +#endif /* HAL_TSC_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32l0xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32l0xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32l0xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32l0xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32l0xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32l0xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32l0xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L0xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + From c7469ce986b495ccd3777e542df31bd90f4134f2 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Tue, 9 Aug 2022 09:53:08 +0200 Subject: [PATCH 453/504] dfu: Allow DFU coexistence with other interfaces dfu_moded_open() only works correct when its called on DFU interface descriptor. It means that DFU is the only one interface in configuration or driver is called after all others interface drivers were tried and gave up. If other interface is supported and but driver for DFU is called first (this is the case for BTH and RNDIS). Code after while loop (that was not entered) has an TU_ASSERT that will make set_configuration to fail. Now TU_VERIFY is called first to make sure open code is called for DFU only and not other interface descriptors like in other drivers. --- src/class/dfu/dfu_device.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index 8d859d2ee..aa5891ca9 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -167,6 +167,8 @@ uint16_t dfu_moded_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint8_t alt_count = 0; uint16_t drv_len = 0; + TU_VERIFY(itf_desc->bInterfaceSubClass == TUD_DFU_APP_SUBCLASS && itf_desc->bInterfaceProtocol == DFU_PROTOCOL_DFU, 0); + while(itf_desc->bInterfaceSubClass == TUD_DFU_APP_SUBCLASS && itf_desc->bInterfaceProtocol == DFU_PROTOCOL_DFU) { TU_ASSERT(max_len > drv_len, 0); From 5efef4393c2f67773843c4ccc0a50f07dac6ece9 Mon Sep 17 00:00:00 2001 From: Ryzee119 Date: Mon, 15 Aug 2022 17:34:13 +0930 Subject: [PATCH 454/504] Hub: Expand hub helpers to handle device events --- src/host/hub.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/host/hub.c b/src/host/hub.c index 3400b154a..e3b81ad23 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -85,7 +85,7 @@ bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, { .bmRequestType_bit = { - .recipient = TUSB_REQ_RCPT_OTHER, + .recipient = (hub_port == 0) ? TUSB_REQ_RCPT_DEVICE : TUSB_REQ_RCPT_OTHER, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_OUT }, @@ -117,7 +117,7 @@ bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, { .bmRequestType_bit = { - .recipient = TUSB_REQ_RCPT_OTHER, + .recipient = (hub_port == 0) ? TUSB_REQ_RCPT_DEVICE : TUSB_REQ_RCPT_OTHER, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_OUT }, @@ -149,7 +149,7 @@ bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, { .bmRequestType_bit = { - .recipient = TUSB_REQ_RCPT_OTHER, + .recipient = (hub_port == 0) ? TUSB_REQ_RCPT_DEVICE : TUSB_REQ_RCPT_OTHER, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_IN }, From aafea8ef5d6f329d66c6c1e903b8a6b33d769ad5 Mon Sep 17 00:00:00 2001 From: Ryzee119 Date: Mon, 15 Aug 2022 17:36:45 +0930 Subject: [PATCH 455/504] Hub: Rename port status callback to be more generic --- src/host/hub.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/host/hub.c b/src/host/hub.c index e3b81ad23..dc2e4e759 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -313,7 +313,7 @@ static void config_port_power_complete (tuh_xfer_t* xfer) // Connection Changes //--------------------------------------------------------------------+ -static void connection_get_status_complete (tuh_xfer_t* xfer); +static void hub_port_get_status_complete (tuh_xfer_t* xfer); static void connection_clear_conn_change_complete (tuh_xfer_t* xfer); static void connection_port_reset_complete (tuh_xfer_t* xfer); @@ -333,7 +333,7 @@ bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32 { if ( tu_bit_test(p_hub->status_change, port) ) { - if (hub_port_get_status(dev_addr, port, &p_hub->port_status, connection_get_status_complete, 0) == false) + if (hub_port_get_status(dev_addr, port, &p_hub->port_status, hub_port_get_status_complete, 0) == false) { //Hub status control transfer failed, retry hub_edpt_status_xfer(dev_addr); @@ -347,7 +347,7 @@ bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32 return true; } -static void connection_get_status_complete (tuh_xfer_t* xfer) +static void hub_port_get_status_complete (tuh_xfer_t* xfer) { TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, ); From 3c7b5dcaffb9ccc81e700d5b0b212e897b4b9b0d Mon Sep 17 00:00:00 2001 From: Ryzee119 Date: Mon, 15 Aug 2022 17:39:32 +0930 Subject: [PATCH 456/504] Hub: Handle hub device status change interrupt --- src/host/hub.c | 59 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 8 deletions(-) diff --git a/src/host/hub.c b/src/host/hub.c index dc2e4e759..99c629071 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -44,6 +44,7 @@ typedef struct uint8_t status_change; // data from status change interrupt endpoint hub_port_status_response_t port_status; + hub_status_response_t hub_status; } hub_interface_t; CFG_TUSB_MEM_SECTION static hub_interface_t hub_data[CFG_TUH_HUB]; @@ -314,6 +315,7 @@ static void config_port_power_complete (tuh_xfer_t* xfer) //--------------------------------------------------------------------+ static void hub_port_get_status_complete (tuh_xfer_t* xfer); +static void hub_get_status_complete (tuh_xfer_t* xfer); static void connection_clear_conn_change_complete (tuh_xfer_t* xfer); static void connection_port_reset_complete (tuh_xfer_t* xfer); @@ -326,19 +328,31 @@ bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32 hub_interface_t* p_hub = get_itf(dev_addr); - TU_LOG2(" Port Status Change = 0x%02X\r\n", p_hub->status_change); + TU_LOG2(" Hub Status Change = 0x%02X\r\n", p_hub->status_change); - // Hub ignore bit0 in status change - for (uint8_t port=1; port <= p_hub->port_count; port++) + // Hub bit 0 is for the hub device events + if (tu_bit_test(p_hub->status_change, 0)) { - if ( tu_bit_test(p_hub->status_change, port) ) + if (hub_port_get_status(dev_addr, 0, &p_hub->hub_status, hub_get_status_complete, 0) == false) { - if (hub_port_get_status(dev_addr, port, &p_hub->port_status, hub_port_get_status_complete, 0) == false) + //Hub status control transfer failed, retry + hub_edpt_status_xfer(dev_addr); + } + } + else + { + // Hub bits 1 to n are hub port events + for (uint8_t port=1; port <= p_hub->port_count; port++) + { + if ( tu_bit_test(p_hub->status_change, port) ) { - //Hub status control transfer failed, retry - hub_edpt_status_xfer(dev_addr); + if (hub_port_get_status(dev_addr, port, &p_hub->port_status, hub_port_get_status_complete, 0) == false) + { + //Hub status control transfer failed, retry + hub_edpt_status_xfer(dev_addr); + } + break; } - break; } } @@ -347,6 +361,35 @@ bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32 return true; } +static void hub_clear_feature_complete_stub(tuh_xfer_t* xfer) +{ + TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, ); + hub_edpt_status_xfer(xfer->daddr); +} + +static void hub_get_status_complete (tuh_xfer_t* xfer) +{ + TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, ); + + uint8_t const daddr = xfer->daddr; + hub_interface_t* p_hub = get_itf(daddr); + uint8_t const port_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); + TU_ASSERT(port_num == 0 , ); + + TU_LOG2("HUB Got hub status, addr = %u, status = %04x\r\n", daddr, p_hub->hub_status.change.value); + + if (p_hub->hub_status.change.local_power_source) + { + TU_LOG2("HUB Local Power Change, addr = %u\r\n", daddr); + hub_port_clear_feature(daddr, port_num, HUB_FEATURE_HUB_LOCAL_POWER_CHANGE, hub_clear_feature_complete_stub, 0); + } + else if (p_hub->hub_status.change.over_current) + { + TU_LOG1("HUB Over Current, addr = %u\r\n", daddr); + hub_port_clear_feature(daddr, port_num, HUB_FEATURE_HUB_OVER_CURRENT_CHANGE, hub_clear_feature_complete_stub, 0); + } +} + static void hub_port_get_status_complete (tuh_xfer_t* xfer) { TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, ); From 2b2354d3021202f0b88d17b9356ff924cb01e45f Mon Sep 17 00:00:00 2001 From: Ryzee119 Date: Mon, 15 Aug 2022 17:40:59 +0930 Subject: [PATCH 457/504] Hub: Clear other port feature changes --- src/host/hub.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/host/hub.c b/src/host/hub.c index 99c629071..3da5358b2 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -408,7 +408,24 @@ static void hub_port_get_status_complete (tuh_xfer_t* xfer) hub_port_clear_feature(daddr, port_num, HUB_FEATURE_PORT_CONNECTION_CHANGE, connection_clear_conn_change_complete, 0); }else { - // Other changes are: Enable, Suspend, Over Current, Reset, L1 state + // Clear other port status change interrupts. TODO Not currently handled - just cleared. + if (p_hub->port_status.change.port_enable) + { + hub_port_clear_feature(daddr, port_num, HUB_FEATURE_PORT_ENABLE_CHANGE, hub_clear_feature_complete_stub, 0); + } + else if (p_hub->port_status.change.suspend) + { + hub_port_clear_feature(daddr, port_num, HUB_FEATURE_PORT_SUSPEND_CHANGE, hub_clear_feature_complete_stub, 0); + } + else if (p_hub->port_status.change.over_current) + { + hub_port_clear_feature(daddr, port_num, HUB_FEATURE_PORT_OVER_CURRENT_CHANGE, hub_clear_feature_complete_stub, 0); + } + else if (p_hub->port_status.change.reset) + { + hub_port_clear_feature(daddr, port_num, HUB_FEATURE_PORT_RESET_CHANGE, hub_clear_feature_complete_stub, 0); + } + // Other changes are: L1 state // TODO clear change // prepare for next hub status From 961e83e0836879ef9010184404c0f61c933035bf Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 19 Aug 2022 17:11:40 +0700 Subject: [PATCH 458/504] more docs update --- README.rst | 2 +- docs/info/changelog.rst | 58 ++++++++++++++++++++++++++++++++++++ docs/reference/supported.rst | 9 +++++- 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index ba176a8c8..05963a655 100644 --- a/README.rst +++ b/README.rst @@ -51,7 +51,7 @@ The stack supports the following MCUs: - **Renesas:** RX63N, RX65N, RX72N - **Silabs:** EFM32GG - **Sony:** CXD56 -- **ST:** STM32 series: F0, F1, F2, F3, F4, F7, H7, G4, L0, L1, L4, L4+ +- **ST:** STM32 series: F0, F1, F2, F3, F4, F7, H7, G4, L0, L1, L4, L4+, WB - **TI:** MSP430, MSP432E4, TM4C123 - **ValentyUSB:** eptri diff --git a/docs/info/changelog.rst b/docs/info/changelog.rst index bd6712b93..67bb6af65 100644 --- a/docs/info/changelog.rst +++ b/docs/info/changelog.rst @@ -2,6 +2,64 @@ Changelog ********* +0.14.0 +====== + +- Improve compiler support for CCRX and IAR +- Add timeout to osal_queue_receive() +- Add tud_task_ext(timeout, in_isr) as generic version of tud_task(). Same as tuh_task_ext(), tuh_task() +- Enable more warnings -Wnull-dereference -Wuninitialized -Wunused -Wredundant-decls -Wconversion +- Add new examples + - host/bare_api to demonstrate generic (app-level) enumeration and endpoint transfer + - dual/host_hid_to_device_cdc to run both device and host stack concurrently, get HID report from host and print out to device CDC. This example only work with multiple-controller MCUs and rp2040 with the help of pio-usb as added controller. + +Controller Driver (DCD & HCD) +----------------------------- + +- Enhance rhports management to better support dual roles + - CFG_TUD_ENABLED/CFG_TUH_ENABLED, CFG_TUD_MAX_SPEED/CFG_TUH_MAX_SPEED can be used to replace CFG_TUSB_RHPORT0_MODE/CFG_TUSB_RHPORT1_MODE + - tud_init(rphort), tuh_init(rhport) can be used to init stack on specified roothub port (controller) instead of tusb_init(void) +- Add dcd/hcd port specific defines TUP_ (stand for tinyusb port-specific) +- [dwc2] + - Update to support stm32 h72x, h73x with only 1 otg controller + - Fix overwrite with grstctl when disable endpoint +- [EHCI] Fix an issue with EHCI driver +- [msp430] Fix for possible bug in msp430-elf-gcc 9.3.0 +- [nrf5x] Fix DMA access race condition using atomic function +- [pic32] Fix PIC32 santiy +- [rp2040] + - Add PICO-PIO-USB as controller (device/host) support for rp2040 + - Use shared IRQ handlers, so user can also hook the USB IRQ + - Fix resumed signal not reported to device stack +- [stm32fsdev] Add support for stm32wb55 + +Device Stack +------------ + +- [Audio] Add support for feedback endpoint computation + - New API tud_audio_feedback_params_cb(), tud_audio_feedback_interval_isr(). + - Supported computation method are: frequency with fixed/float or power of 2. Feedback with fifo count is not yet supported. + - Fix nitfs (should be 3) in TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR + - Fix typo in audiod_rx_done_cb() +- [DFU] Fix coexistence with other interfaces BTH, RNDIS +- [MSC] Fix inquiry response additional length field +- [Venndor] Improve write performance + +Host Stack +---------- + +- Add new API tuh_configure(rhport, cfg_id, cfg_param) for dynamnic port specific behavior configuration +- [HID] Open OUT endpoint if available +- [Hub] hub clear port and device interrupts +- [USBH] Major improvement + - Rework usbh control transfer with complete callback. New API tuh_control_xfer() though still only carry 1 usbh (no queueing) at a time. + - Add generic endpoint transfer with tuh_edpt_open(), tuh_edpt_xfer(). Require `CFG_TUH_API_EDPT_XFER=1` + - Support app-level enumeration with new APIs + - tuh_descriptor_get(), tuh_descriptor_get_device(), tuh_descriptor_get_configuration(), tuh_descriptor_get_hid_report() + - tuh_descriptor_get_string(), tuh_descriptor_get_manufacturer_string(), tuh_descriptor_get_product_string(), tuh_descriptor_get_serial_string() + - Also add _sync() as sync/blocking version for above APIs + + 0.13.0 ====== diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index ad2af98ff..1fb858a45 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -60,7 +60,7 @@ Supported MCUs | | +-------------+--------+------+-----------+-------------------+--------------+ | | | 55 | ✔ | | ✔ | lpc_ip3511 | | +--------------+---------+-------------+--------+------+-----------+-------------------+--------------+ -| Raspberry Pi | RP2040 | ✔ | ✔ | ✖ | rp2040 | | +| Raspberry Pi | RP2040 | ✔ | ✔ | ✖ | rp2040, pio_usb | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ | Renesas | RX 63N, 65N, 72N | ✔ | ✔ | ✖ | usba | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ @@ -95,6 +95,8 @@ Supported MCUs | | L4+ | ✔ | | | dwc2 | | | +-----------------------+--------+------+-----------+-------------------+--------------+ | | U5 | ⚠ | | | dwc2 | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ +| | WBx5 | ✔ | | | stm32_fsdev | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ | TI | MSP430 | ✔ | ✖ | ✖ | msp430x5xx | | | +-----------------------+--------+------+-----------+-------------------+--------------+ @@ -241,6 +243,7 @@ iMX RT - `MIMX RT1060 Evaluation Kit `__ - `MIMX RT1064 Evaluation Kit `__ - `Teensy 4.0 Development Board `__ +- `Teensy 4.1 Development Board `__ Kinetis ^^^^^^^ @@ -379,6 +382,10 @@ L4 - `STM32 L4P5zg Nucleo `__ - `STM32 L4R5zi Nucleo `__ +WB +^^ +- `STM32 WB55 Nucleo `__ + TI -- From 05e19b7848cea88031b912f69be04bf6a0fdd163 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Fri, 19 Aug 2022 23:57:39 +0700 Subject: [PATCH 459/504] Update feature_request.yml --- .github/ISSUE_TEMPLATE/feature_request.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index e168b73a6..19f403246 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -41,9 +41,9 @@ body: required: true - type: checkboxes - attributes: - label: I have checked existing issues, dicussion and documentation - description: You agree to check all the resources above before opening a new issue. - options: - - label: I confirm I have checked existing issues, dicussion and documentation. - required: true + attributes: + label: I have checked existing issues, dicussion and documentation + description: You agree to check all the resources above before opening a new issue. + options: + - label: I confirm I have checked existing issues, dicussion and documentation. + required: true From 3e815c709cef3a12841e07e8c416bad7c0d35c5d Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 23 Aug 2022 12:00:20 +0700 Subject: [PATCH 460/504] update repository.yml --- repository.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/repository.yml b/repository.yml index aaec10eb7..dc341a3c1 100644 --- a/repository.yml +++ b/repository.yml @@ -11,7 +11,8 @@ repo.versions: "0.11.0": "0.11.0" "0.12.0": "0.12.0" "0.13.0": "0.13.0" + "0.14.0": "0.14.0" "0-dev": "0.0.0" # master - "0-latest": "0.13.0" # latest stable release + "0-latest": "0.14.0" # latest stable release From 660e8f50a7b551eec7e02f78c828a54394920e51 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 23 Aug 2022 14:43:09 +0700 Subject: [PATCH 461/504] try to fix release body in tinyusb_src (not tested) --- .github/workflows/trigger.yml | 4 +++- docs/info/changelog.rst | 3 +-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/trigger.yml b/.github/workflows/trigger.yml index 780d6f4f3..e434ca238 100644 --- a/.github/workflows/trigger.yml +++ b/.github/workflows/trigger.yml @@ -55,4 +55,6 @@ jobs: git push origin ${{ github.event.release.tag_name }} # Send POST reqwuest to release https://docs.github.com/en/rest/reference/repos#create-a-release - curl -X POST -H "Authorization: token ${{ secrets.API_TOKEN_GITHUB }}" -H "Accept: application/vnd.github.v3+json" --data '{"tag_name": "${{ github.event.release.tag_name }}", "name": "${{ github.event.release.name }}", "body": "${{ github.event.release.body }}", "draft": ${{ github.event.release.draft }}, "prerelease": ${{ github.event.release.prerelease }}}' https://api.github.com/repos/hathach/tinyusb_src/releases + bb={{ github.event.release.body }} + bb=${bb//\n/\\\n} + curl -X POST -H "Authorization: token ${{ secrets.API_TOKEN_GITHUB }}" -H "Accept: application/vnd.github.v3+json" --data '{"tag_name": "${{ github.event.release.tag_name }}", "name": "${{ github.event.release.name }}", "body": "$bb", "draft": ${{ github.event.release.draft }}, "prerelease": ${{ github.event.release.prerelease }}}' https://api.github.com/repos/hathach/tinyusb_src/releases diff --git a/docs/info/changelog.rst b/docs/info/changelog.rst index 67bb6af65..da29e04fb 100644 --- a/docs/info/changelog.rst +++ b/docs/info/changelog.rst @@ -57,8 +57,7 @@ Host Stack - Support app-level enumeration with new APIs - tuh_descriptor_get(), tuh_descriptor_get_device(), tuh_descriptor_get_configuration(), tuh_descriptor_get_hid_report() - tuh_descriptor_get_string(), tuh_descriptor_get_manufacturer_string(), tuh_descriptor_get_product_string(), tuh_descriptor_get_serial_string() - - Also add _sync() as sync/blocking version for above APIs - + - Also add _sync() as sync/blocking version for above APIs 0.13.0 ====== From 8a537a0092a5bea5540e238c9ff2726204879f77 Mon Sep 17 00:00:00 2001 From: Ahmed El-Sharnoby Date: Tue, 23 Aug 2022 17:18:32 +0200 Subject: [PATCH 462/504] Remove Hardcoded interface numbers from video descriptors Removing the Hardcoded interface numbers from the video descriptors allow the user to add other interfaces before or after the Video Control Interface and Video Streaming Interface --- examples/device/video_capture/src/usb_descriptors.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/device/video_capture/src/usb_descriptors.h b/examples/device/video_capture/src/usb_descriptors.h index 23511c909..90537aa06 100644 --- a/examples/device/video_capture/src/usb_descriptors.h +++ b/examples/device/video_capture/src/usb_descriptors.h @@ -38,7 +38,7 @@ #define FRAME_RATE 10 enum { - ITF_NUM_VIDEO_CONTROL = 0, + ITF_NUM_VIDEO_CONTROL, ITF_NUM_VIDEO_STREAMING, ITF_NUM_TOTAL }; @@ -74,19 +74,19 @@ enum { TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfmtdesc, TUD_VIDEO_GUID_I420, 12, _frmidx, _asrx, _asry, _interlace, _cp) #define TUD_VIDEO_CAPTURE_DESCRIPTOR(_stridx, _epin, _width, _height, _fps, _epsize) \ - TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, ITF_NUM_TOTAL, _stridx), \ + TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ /* Video control 0 */ \ TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \ /* wTotalLength - bLength */ \ TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \ - UVC_CLOCK_FREQUENCY, 1), \ + UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\ /*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\ /*wObjectiveFocalLength*/0, /*bmControls*/0), \ TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ /* Video stream alt. 0 */ \ - TUD_VIDEO_DESC_STD_VS( 1, 0, 0, 0), \ + TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 0, _stridx), \ /* Video stream header for without still image capture */ \ TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ /*wTotalLength - bLength */\ @@ -106,7 +106,7 @@ enum { (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ /* VS alt 1 */\ - TUD_VIDEO_DESC_STD_VS(1, 1, 1, 0), \ + TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 1, 1, _stridx), \ /* EP */ \ TUD_VIDEO_DESC_EP_ISO(_epin, _epsize, 1) From 5e3cfe7b5784ee94a4914b36232d28ce96cf18f2 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Fri, 26 Aug 2022 08:01:06 +0200 Subject: [PATCH 463/504] nrf5x: Fix endpoint internal state when closed Field started (regardind transfer) was only cleaed when transfer was finished. For audio devices set interface is called many times. When there is no audio (silence) set interface requests zero lenght bandwithd that in turn calls dcd_edpt_close(). When endpoint is closed due to set interface request transfer should not longer be started since it will block next start transfer with assert. This just sets 'started' to false when endpoint is closed. --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index efa30c60a..f213e9f9f 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -438,6 +438,7 @@ void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) // When both ISO endpoint are close there is no need for SOF any more. if (_dcd.xfer[EP_ISO_NUM][TUSB_DIR_IN].mps + _dcd.xfer[EP_ISO_NUM][TUSB_DIR_OUT].mps == 0) NRF_USBD->INTENCLR = USBD_INTENCLR_SOF_Msk; } + _dcd.xfer[epnum][dir].started = false; __ISB(); __DSB(); } From c5992edc7de6f54d5fdab801c46e964bc0f18542 Mon Sep 17 00:00:00 2001 From: ReimuNotMoe <34613827+ReimuNotMoe@users.noreply.github.com> Date: Sat, 3 Sep 2022 05:18:29 +0800 Subject: [PATCH 464/504] Initial PIC32MM/MX & PIC24 support --- src/portable/microchip/pic/dcd_pic.c | 711 +++++++++++++++++++++++++++ src/tusb_option.h | 5 + 2 files changed, 716 insertions(+) create mode 100644 src/portable/microchip/pic/dcd_pic.c diff --git a/src/portable/microchip/pic/dcd_pic.c b/src/portable/microchip/pic/dcd_pic.c new file mode 100644 index 000000000..df9b2ff01 --- /dev/null +++ b/src/portable/microchip/pic/dcd_pic.c @@ -0,0 +1,711 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Koji Kitayama + * Copyright (c) 2022 Reimu NotMoe + * + * 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_PIC32MX || CFG_TUSB_MCU == OPT_MCU_PIC32MM || \ + CFG_TUSB_MCU == OPT_MCU_PIC32MK || CFG_TUSB_MCU == OPT_MCU_PIC24 || \ + CFG_TUSB_MCU == OPT_MCU_DSPIC33) + +#include + +#include "device/dcd.h" + + +#if (CFG_TUSB_MCU == OPT_MCU_PIC32MX || CFG_TUSB_MCU == OPT_MCU_PIC32MM || CFG_TUSB_MCU == OPT_MCU_PIC32MK) + +#define TU_PIC_HAS_MMU 1 +#define TU_PIC_HAS_HW_RMW 1 +#define TU_PIC_INT_SIZE 4 + +#elif (CFG_TUSB_MCU == OPT_MCU_PIC24 || CFG_TUSB_MCU == OPT_MCU_DSPIC33) + +#define TU_PIC_HAS_MMU 0 +#define TU_PIC_HAS_HW_RMW 0 +#define TU_PIC_INT_SIZE 2 + +#else + +#error Unsupportd PIC MCU + +#endif + + +#if TU_PIC_HAS_MMU + +#ifndef KVA_TO_PA +#define KVA_TO_PA(kva) ((uint32_t)(kva) & 0x1fffffff) +#endif + +#ifndef PA_TO_KVA1 +#define PA_TO_KVA1(pa) ((uint32_t)(pa) | 0xA0000000) +#endif + +#else + +#ifndef KVA_TO_PA +#define KVA_TO_PA(kva) (kva) +#endif + +#ifndef PA_TO_KVA1 +#define PA_TO_KVA1(pa) (pa) +#endif + +#endif + + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ + +enum { + TOK_PID_OUT = 0x1u, + TOK_PID_IN = 0x9u, + TOK_PID_SETUP = 0xDu, +}; + +typedef struct TU_ATTR_PACKED +{ + union { + uint32_t head; + struct { + union { + struct { + uint16_t : 2; + uint16_t tok_pid : 4; + uint16_t data : 1; + uint16_t own : 1; + uint16_t : 8; + }; + struct { + uint16_t : 2; + uint16_t bdt_stall : 1; + uint16_t dts : 1; + uint16_t ninc : 1; + uint16_t keep : 1; + uint16_t : 10; + }; + }; + uint16_t bc : 10; + uint16_t : 6; + }; + }; + uint8_t *addr; +} buffer_descriptor_t; + +TU_VERIFY_STATIC( sizeof(buffer_descriptor_t) == 8, "size is not correct" ); + +typedef struct TU_ATTR_PACKED +{ + union { + uint32_t state; + struct { + uint32_t max_packet_size :11; + uint32_t : 5; + uint32_t odd : 1; + uint32_t :15; + }; + }; + uint16_t length; + uint16_t remaining; +} endpoint_state_t; + +TU_VERIFY_STATIC( sizeof(endpoint_state_t) == 8, "size is not correct" ); + +typedef struct +{ + union { + /* [#EP][OUT,IN][EVEN,ODD] */ + buffer_descriptor_t bdt[16][2][2]; + uint16_t bda[512]; + }; + TU_ATTR_ALIGNED(4) union { + endpoint_state_t endpoint[16][2]; + endpoint_state_t endpoint_unified[16 * 2]; + }; + uint8_t setup_packet[8]; + uint8_t addr; +} dcd_data_t; + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ +// BDT(Buffer Descriptor Table) must be 256-byte aligned +CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(512) volatile static dcd_data_t _dcd; + +TU_VERIFY_STATIC( sizeof(_dcd.bdt) == 512, "size is not correct" ); + +#if TU_PIC_INT_SIZE == 4 +typedef uint32_t ep_reg_t; +#elif TU_PIC_INT_SIZE == 2 +typedef uint16_t ep_reg_t; +#endif + +static inline volatile void *ep_addr(uint8_t rhport, uint8_t ep_num) { +#if CFG_TUSB_MCU == OPT_MCU_PIC32MK + volatile void *ep_reg_base = rhport ? (&U2EP0) : (&U1EP0); +#else + volatile void *ep_reg_base = &U1EP0; +#endif + return ep_reg_base + 0x10 * ep_num; +} + +static inline ep_reg_t ep_read(uint8_t rhport, uint8_t ep_num) { + volatile ep_reg_t *ep = ep_addr(rhport, ep_num); + return *ep; +} + +static inline void ep_write(uint8_t rhport, uint8_t ep_num, ep_reg_t val) { + volatile ep_reg_t *ep = ep_addr(rhport, ep_num); + *ep = val; +} + +static inline void ep_clear(uint8_t rhport, uint8_t ep_num, ep_reg_t val) { +#if TU_PIC_HAS_HW_RMW + volatile ep_reg_t *ep_clr = (ep_addr(rhport, ep_num) + 0x4); + *ep_clr = val; +#else + ep_reg_t v = ep_read(rhport, ep_num); + v &= ~val; + ep_write(rhport, ep_num, v); +#endif +} + +static inline void ep_set(uint8_t rhport, uint8_t ep_num, ep_reg_t val) { +#if TU_PIC_HAS_HW_RMW + volatile ep_reg_t *ep_s = (ep_addr(rhport, ep_num) + 0x8); + *ep_s = val; +#else + ep_reg_t v = ep_read(rhport, ep_num); + v |= val; + ep_write(rhport, ep_num, v); +#endif +} + +static inline void intr_enable(uint8_t rhport) { +#if CFG_TUSB_MCU == OPT_MCU_PIC32MM + IEC0SET = _IEC0_USBIE_MASK; +#elif CFG_TUSB_MCU == OPT_MCU_PIC32MX + IEC1SET = _IEC1_USBIE_MASK; +#elif CFG_TUSB_MCU == OPT_MCU_PIC32MK + if (rhport == 0) + IEC1SET = _IEC1_USB1IE_MASK; + else + IEC7SET = _IEC7_USB2IE_MASK; +#elif (CFG_TUSB_MCU == OPT_MCU_PIC24) || (CFG_TUSB_MCU == OPT_MCU_DSPIC33) + IEC5bits.USB1IE = 1; +#endif +} + +static inline void intr_disable(uint8_t rhport) { +#if CFG_TUSB_MCU == OPT_MCU_PIC32MM + IEC0CLR = _IEC0_USBIE_MASK; +#elif CFG_TUSB_MCU == OPT_MCU_PIC32MX + IEC1CLR = _IEC1_USBIE_MASK; +#elif CFG_TUSB_MCU == OPT_MCU_PIC32MK + if (rhport == 0) + IEC1CLR = _IEC1_USB1IE_MASK; + else + IEC7CLR = _IEC7_USB2IE_MASK; +#elif (CFG_TUSB_MCU == OPT_MCU_PIC24) || (CFG_TUSB_MCU == OPT_MCU_DSPIC33) + IEC5bits.USB1IE = 0; +#endif +} + +static inline int intr_is_enabled(uint8_t rhport) { +#if CFG_TUSB_MCU == OPT_MCU_PIC32MM + return IEC0bits.USBIE; +#elif CFG_TUSB_MCU == OPT_MCU_PIC32MX + return IEC1bits.USBIE; +#elif CFG_TUSB_MCU == OPT_MCU_PIC32MK + if (rhport == 0) + return IEC1bits.USB1IE; + else + return IEC7bits.USB2IE; +#elif (CFG_TUSB_MCU == OPT_MCU_PIC24) || (CFG_TUSB_MCU == OPT_MCU_DSPIC33) + return IEC5bits.USB1IE; +#endif +} + +static inline void intr_clear(uint8_t rhport) { +#if CFG_TUSB_MCU == OPT_MCU_PIC32MM + IFS0CLR = _IFS0_USBIF_MASK; +#elif CFG_TUSB_MCU == OPT_MCU_PIC32MX + IFS1CLR = _IFS1_USBIF_MASK; +#elif CFG_TUSB_MCU == OPT_MCU_PIC32MK + if (rhport == 0) + IFS1CLR = _IFS1_USB1IF_MASK; + else + IFS7CLR = _IFS7_USB2IF_MASK; +#elif (CFG_TUSB_MCU == OPT_MCU_PIC24) || (CFG_TUSB_MCU == OPT_MCU_DSPIC33) + IFS5bits.USB1IF = 0; +#endif +} + +static void prepare_next_setup_packet(uint8_t rhport) +{ + const unsigned out_odd = _dcd.endpoint[0][0].odd; + const unsigned in_odd = _dcd.endpoint[0][1].odd; + TU_ASSERT(0 == _dcd.bdt[0][0][out_odd].own, ); + + _dcd.bdt[0][0][out_odd].data = 0; + _dcd.bdt[0][0][out_odd ^ 1].data = 1; + _dcd.bdt[0][1][in_odd].data = 1; + _dcd.bdt[0][1][in_odd ^ 1].data = 0; + dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_OUT), + _dcd.setup_packet, sizeof(_dcd.setup_packet)); +} + +static void process_stall(uint8_t rhport) +{ + for (int i = 0; i < 16; ++i) { + unsigned const endpt = ep_read(rhport, i); + + if (endpt & _U1EP0_EPSTALL_MASK) { + // prepare next setup if endpoint0 + if ( i == 0 ) prepare_next_setup_packet(rhport); + + // clear stall bit + ep_clear(rhport, i, _U1EP0_EPSTALL_MASK); + } + } +} + +static void process_tokdne(uint8_t rhport) +{ + uint32_t s = U1STAT; + + U1IR = _U1IR_TRNIF_MASK; + + uint8_t epnum = (s >> _U1STAT_ENDPT0_POSITION); + uint8_t dir = (s & _U1STAT_DIR_MASK) >> _U1STAT_DIR_POSITION; + unsigned odd = (s & _U1STAT_PPBI_MASK) ? 1 : 0; + + buffer_descriptor_t *bd = (buffer_descriptor_t *)&_dcd.bda[s]; + endpoint_state_t *ep = &_dcd.endpoint_unified[s >> 3]; + + /* fetch pid before discarded by the next steps */ + const unsigned pid = bd->tok_pid; + + /* reset values for a next transfer */ + bd->bdt_stall = 0; + bd->dts = 1; + bd->ninc = 0; + bd->keep = 0; + /* update the odd variable to prepare for the next transfer */ + ep->odd = odd ^ 1; + if (pid == TOK_PID_SETUP) { + dcd_event_setup_received(rhport, (uint8_t *)PA_TO_KVA1(bd->addr), true); + U1CONCLR = _U1CON_PKTDIS_TOKBUSY_MASK; + return; + } + + const unsigned bc = bd->bc; + const unsigned remaining = ep->remaining - bc; + if (remaining && bc == ep->max_packet_size) { + /* continue the transferring consecutive data */ + ep->remaining = remaining; + const int next_remaining = remaining - ep->max_packet_size; + if (next_remaining > 0) { + /* prepare to the after next transfer */ + bd->addr += ep->max_packet_size * 2; + bd->bc = next_remaining > ep->max_packet_size ? ep->max_packet_size: next_remaining; + bd->own = 1; /* the own bit must set after addr */ + } + return; + } + const unsigned length = ep->length; + dcd_event_xfer_complete(rhport, + tu_edpt_addr(epnum, dir), + length - remaining, XFER_RESULT_SUCCESS, true); + if (0 == epnum && 0 == length) { + /* After completion a ZLP of control transfer, + * it prepares for the next steup transfer. */ + if (_dcd.addr) { + /* When the transfer was the SetAddress, + * the device address should be updated here. */ + U1ADDR = _dcd.addr; + _dcd.addr = 0; + } + prepare_next_setup_packet(rhport); + } +} + +static void process_bus_reset(uint8_t rhport) +{ + U1PWRCCLR = _U1PWRC_USUSPEND_MASK; + U1CONSET = _U1CON_PPBRST_MASK; + U1ADDR = 0; + + U1IE = _U1IE_URSTIE_DETACHIE_MASK | _U1IE_TRNIE_MASK | _U1IE_IDLEIE_MASK | + _U1IE_UERRIE_MASK | _U1IE_STALLIE_MASK; + + U1EP0 = _U1EP0_EPHSHK_MASK | _U1EP0_EPRXEN_MASK | _U1EP0_EPTXEN_MASK; + + for (unsigned i = 1; i < 16; ++i) { + ep_write(rhport, i, 0); + } + + buffer_descriptor_t *bd = _dcd.bdt[0][0]; + for (unsigned i = 0; i < sizeof(_dcd.bdt)/sizeof(*bd); ++i, ++bd) { + bd->head = 0; + } + const endpoint_state_t ep0 = { + .max_packet_size = CFG_TUD_ENDPOINT0_SIZE, + .odd = 0, + .length = 0, + .remaining = 0, + }; + _dcd.endpoint[0][0] = ep0; + _dcd.endpoint[0][1] = ep0; + tu_memclr(_dcd.endpoint[1], sizeof(_dcd.endpoint) - sizeof(_dcd.endpoint[0])); + _dcd.addr = 0; + prepare_next_setup_packet(rhport); + U1CONCLR = _U1CON_PPBRST_MASK; + dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true); +} + +static void process_bus_sleep(uint8_t rhport) +{ + // Enable resume & disable suspend interrupt + dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); +} + +static void process_bus_resume(uint8_t rhport) +{ + // Enable suspend & disable resume interrupt + U1PWRCCLR = _U1PWRC_USUSPEND_MASK; + U1IECLR = _U1IE_RESUMEIE_MASK; + U1IESET = _U1IE_IDLEIE_MASK; + + dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); +} + +/*------------------------------------------------------------------*/ +/* Device API + *------------------------------------------------------------------*/ +void dcd_init(uint8_t rhport) +{ + intr_disable(rhport); + intr_clear(rhport); + +#if CFG_TUSB_MCU == OPT_MCU_PIC32MM + TRISBbits.TRISB6 = 1; +#endif + +#if (CFG_TUSB_MCU == OPT_MCU_PIC32MX) || (CFG_TUSB_MCU == OPT_MCU_PIC32MM) + U1PWRCSET = _U1PWRC_USBPWR_MASK; +#elif CFG_TUSB_MCU == OPT_MCU_PIC32MK + // TODO +#elif (CFG_TUSB_MCU == OPT_MCU_PIC24) || (CFG_TUSB_MCU == OPT_MCU_DSPIC33) + U1PWRCbits.USBPWR = 1; +#endif + + tu_memclr(&_dcd, sizeof(_dcd)); + + uint32_t bdt_phys = KVA_TO_PA((uintptr_t)_dcd.bdt); + + U1BDTP1 = (uint8_t)(bdt_phys >> 8); + U1BDTP2 = (uint8_t)(bdt_phys >> 16); + U1BDTP3 = (uint8_t)(bdt_phys >> 24); + + U1IE = _U1IE_URSTIE_DETACHIE_MASK; + + dcd_connect(rhport); + +} + +void dcd_int_enable(uint8_t rhport) +{ + intr_enable(rhport); +} + +void dcd_int_disable(uint8_t rhport) +{ + intr_disable(rhport); +} + +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + _dcd.addr = dev_addr & 0x7F; + /* Response with status first before changing device address */ + dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); +} + +void dcd_remote_wakeup(uint8_t rhport) +{ + U1CONSET = _U1CON_RESUME_MASK; + + unsigned cnt = 25000000 / 1000; + while (cnt--) asm volatile("nop"); + + U1CONCLR = _U1CON_RESUME_MASK; +} + +void dcd_connect(uint8_t rhport) +{ + while (!U1CONbits.USBEN) + U1CONSET = _U1CON_USBEN_SOFEN_MASK; +} + +void dcd_disconnect(uint8_t rhport) +{ + U1CON = 0; +} + +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; +} + +//--------------------------------------------------------------------+ +// Endpoint API +//--------------------------------------------------------------------+ +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) +{ + const unsigned ep_addr = ep_desc->bEndpointAddress; + const unsigned epn = tu_edpt_number(ep_addr); + const unsigned dir = tu_edpt_dir(ep_addr); + const unsigned xfer = ep_desc->bmAttributes.xfer; + endpoint_state_t *ep = &_dcd.endpoint[epn][dir]; + const unsigned odd = ep->odd; + buffer_descriptor_t *bd = _dcd.bdt[epn][dir]; + + /* No support for control transfer */ + TU_ASSERT(epn && (xfer != TUSB_XFER_CONTROL)); + + ep->max_packet_size = tu_edpt_packet_size(ep_desc); + + unsigned val = _U1EP0_EPCONDIS_MASK; + val |= (xfer != TUSB_XFER_ISOCHRONOUS) ? _U1EP0_EPHSHK_MASK : 0; + val |= dir ? _U1EP0_EPTXEN_MASK : _U1EP0_EPRXEN_MASK; + + volatile void *ep_reg_base = &U1EP0; + volatile uint32_t *reg_ep = (ep_reg_base + 0x10 * epn); + + *reg_ep |= val; + + if (xfer != TUSB_XFER_ISOCHRONOUS) { + bd[odd].dts = 1; + bd[odd].data = 0; + bd[odd ^ 1].dts = 1; + bd[odd ^ 1].data = 1; + } + + return true; +} + +void dcd_edpt_close_all(uint8_t rhport) +{ + const unsigned ie = intr_is_enabled(rhport); + intr_disable(rhport); + + for (unsigned i = 1; i < 16; ++i) { + ep_write(rhport, i, 0); + } + + if (ie) intr_enable(rhport); + + buffer_descriptor_t *bd = _dcd.bdt[1][0]; + for (unsigned i = 2; i < sizeof(_dcd.bdt)/sizeof(*bd); ++i, ++bd) { + bd->head = 0; + } + endpoint_state_t *ep = &_dcd.endpoint[1][0]; + for (unsigned i = 2; i < sizeof(_dcd.endpoint)/sizeof(*ep); ++i, ++ep) { + /* Clear except the odd */ + ep->max_packet_size = 0; + ep->length = 0; + ep->remaining = 0; + } +} + +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) +{ + const unsigned epn = tu_edpt_number(ep_addr); + const unsigned dir = tu_edpt_dir(ep_addr); + endpoint_state_t *ep = &_dcd.endpoint[epn][dir]; + buffer_descriptor_t *bd = _dcd.bdt[epn][dir]; + const unsigned msk = dir ? _U1EP0_EPTXEN_MASK : _U1EP0_EPRXEN_MASK; + const unsigned ie = intr_is_enabled(rhport); + + intr_disable(rhport); + + ep_clear(rhport, epn, msk); + + ep->max_packet_size = 0; + ep->length = 0; + ep->remaining = 0; + bd[0].head = 0; + bd[1].head = 0; + + if (ie) intr_enable(rhport); +} + +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) +{ + const unsigned epn = tu_edpt_number(ep_addr); + const unsigned dir = tu_edpt_dir(ep_addr); + endpoint_state_t *ep = &_dcd.endpoint[epn][dir]; + buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][ep->odd]; + TU_ASSERT(0 == bd->own); + + const unsigned ie = intr_is_enabled(rhport); + + intr_disable(rhport); + + ep->length = total_bytes; + ep->remaining = total_bytes; + + const unsigned mps = ep->max_packet_size; + if (total_bytes > mps) { + buffer_descriptor_t *next = ep->odd ? bd - 1: bd + 1; + /* When total_bytes is greater than the max packet size, + * it prepares to the next transfer to avoid NAK in advance. */ + next->bc = total_bytes >= 2 * mps ? mps: total_bytes - mps; + next->addr = (uint8_t *)KVA_TO_PA(buffer + mps); + next->own = 1; + } + bd->bc = total_bytes >= mps ? mps: total_bytes; + bd->addr = (uint8_t *)KVA_TO_PA(buffer); +// __DSB(); + bd->own = 1; /* This bit must be set last */ + + if (ie) intr_enable(rhport); + + return true; +} + +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + const unsigned epn = tu_edpt_number(ep_addr); + + if (0 == epn) { + ep_set(rhport, epn, _U1EP0_EPSTALL_MASK); + } else { + const unsigned dir = tu_edpt_dir(ep_addr); + const unsigned odd = _dcd.endpoint[epn][dir].odd; + buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][odd]; + TU_ASSERT(0 == bd->own,); + + const unsigned ie = intr_is_enabled(rhport); + + intr_disable(rhport); + + bd->bdt_stall = 1; + bd->own = 1; /* This bit must be set last */ + + if (ie) intr_enable(rhport); + } +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + const unsigned epn = tu_edpt_number(ep_addr); + TU_VERIFY(epn,); + const unsigned dir = tu_edpt_dir(ep_addr); + const unsigned odd = _dcd.endpoint[epn][dir].odd; + buffer_descriptor_t *bd = _dcd.bdt[epn][dir]; + TU_VERIFY(bd[odd].own,); + + const unsigned ie = intr_is_enabled(rhport); + + intr_disable(rhport); + + bd[odd].own = 0; + + // clear stall + bd[odd].bdt_stall = 0; + + // Reset data toggle + bd[odd ].data = 0; + bd[odd ^ 1].data = 1; + + // We already cleared this in ISR, but just clear it here to be safe + const unsigned endpt = ep_read(rhport, epn); + if (endpt & _U1EP0_EPSTALL_MASK) { + ep_clear(rhport, endpt, _U1EP0_EPSTALL_MASK); + } + + if (ie) intr_enable(rhport); +} + +//--------------------------------------------------------------------+ +// ISR +//--------------------------------------------------------------------+ +void dcd_int_handler(uint8_t rhport) +{ + uint32_t is = U1IR; + uint32_t msk = U1IE; + + U1IR = is & ~msk; + is &= msk; + + if (is & _U1IR_UERRIF_MASK) { + uint32_t es = U1EIR; + U1EIR = es; + U1IR = is; /* discard any pending events */ + } + + if (is & _U1IR_URSTIF_DETACHIF_MASK) { + U1IR = is; /* discard any pending events */ + process_bus_reset(rhport); + } + + if (is & _U1IR_IDLEIF_MASK) { + // Note Host usually has extra delay after bus reset (without SOF), which could falsely + // detected as Sleep event. Though usbd has debouncing logic so we are good + U1IR = _U1IR_IDLEIF_MASK; + process_bus_sleep(rhport); + } + + if (is & _U1IR_RESUMEIF_MASK) { + U1IR = _U1IR_RESUMEIF_MASK; + process_bus_resume(rhport); + } + + if (is & _U1IR_SOFIF_MASK) { + U1IR = _U1IR_SOFIF_MASK; + dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); + } + + if (is & _U1IR_STALLIF_MASK) { + U1IR = _U1IR_STALLIF_MASK; + process_stall(rhport); + } + + if (is & _U1IR_TRNIF_MASK) { + process_tokdne(rhport); + } + + intr_clear(rhport); + +} + +#endif diff --git a/src/tusb_option.h b/src/tusb_option.h index e7fc68858..4c2dd0258 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -146,6 +146,11 @@ typedef int make_iso_compilers_happy; // PIC #define OPT_MCU_PIC32MZ 1900 ///< MicroChip PIC32MZ family +#define OPT_MCU_PIC32MM 1901 ///< MicroChip PIC32MM family +#define OPT_MCU_PIC32MX 1902 ///< MicroChip PIC32MX family +#define OPT_MCU_PIC32MK 1903 ///< MicroChip PIC32MK family +#define OPT_MCU_PIC24 1910 ///< MicroChip PIC24 family +#define OPT_MCU_DSPIC33 1911 ///< MicroChip DSPIC33 family // BridgeTek #define OPT_MCU_FT90X 2000 ///< BridgeTek FT90x From 0931b52b66864ab680f1e5b52eb0c20d028f5558 Mon Sep 17 00:00:00 2001 From: jmark1m Date: Wed, 7 Sep 2022 15:10:44 -0500 Subject: [PATCH 465/504] Fix bug #1628 by preventing shared irq slots for filling up --- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index e9118c6a3..6ca992954 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -380,6 +380,9 @@ bool hcd_init(uint8_t rhport) // 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; + // Remove shared irq if it was previously added so as not to fill up shared irq slots + irq_remove_handler(USBCTRL_IRQ, hcd_rp2040_irq); + irq_add_shared_handler(USBCTRL_IRQ, hcd_rp2040_irq, PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY); // clear epx and interrupt eps From 7a48b1f0d191093caa59c4fcb5c4f85fa2e53323 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 13 Sep 2022 11:04:48 +0700 Subject: [PATCH 466/504] re-added code in pr 1438 to fix compile with h7 with 1 usb otg --- src/portable/synopsys/dwc2/dwc2_stm32.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index 1187e0d6e..337f611d8 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -64,6 +64,10 @@ // NOTE: H7 with only 1 USB port: H72x / H73x / H7Ax / H7Bx // USB_OTG_FS_PERIPH_BASE and OTG_FS_IRQn not defined + #if (! defined USB2_OTG_FS) + #define USB_OTG_FS_PERIPH_BASE USB1_OTG_HS_PERIPH_BASE + #define OTG_FS_IRQn OTG_HS_IRQn + #endif #elif CFG_TUSB_MCU == OPT_MCU_STM32F7 #include "stm32f7xx.h" From 3133cacc6ab699244617039462f5c3870e16d835 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Tue, 13 Sep 2022 08:10:58 +0200 Subject: [PATCH 467/504] nrf5x: Fix reception of large ISO packets ISO packet size is up to 1023 for full speed device. Upon completion of ISO reception, reported length of incoming packet was truncated to one byte only. This results in incorrect data stream for higher bit rates 48 samples * 4 bytes per sample * 2 channels = 384 bytes of data and 128 was reported. There is no change in logic extending xact_len to uint16_t fixes the issue. --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index f213e9f9f..ca37d799f 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -765,7 +765,7 @@ void dcd_int_handler(uint8_t rhport) if ( tu_bit_test(int_status, USBD_INTEN_ENDEPOUT0_Pos+epnum)) { xfer_td_t* xfer = get_td(epnum, TUSB_DIR_OUT); - uint8_t const xact_len = NRF_USBD->EPOUT[epnum].AMOUNT; + uint16_t const xact_len = NRF_USBD->EPOUT[epnum].AMOUNT; xfer->buffer += xact_len; xfer->actual_len += xact_len; From e80714740ceec841ff4964fe555870cf3ee4f6df Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Tue, 12 Oct 2021 23:29:58 +0900 Subject: [PATCH 468/504] Change images to MJPEG --- examples/device/video_capture/src/images.h | 282 ++++++++++++++++++ examples/device/video_capture/src/main.c | 21 +- .../video_capture/src/usb_descriptors.h | 10 +- src/class/video/video.h | 79 +++++ src/class/video/video_device.c | 175 +++++++++-- 5 files changed, 536 insertions(+), 31 deletions(-) diff --git a/examples/device/video_capture/src/images.h b/examples/device/video_capture/src/images.h index 1b13cfe81..33beff662 100644 --- a/examples/device/video_capture/src/images.h +++ b/examples/device/video_capture/src/images.h @@ -1649,3 +1649,285 @@ static const unsigned char frame_buffer[128 * (96 + 1) * 2] = { 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, }; + +#define color_bar_0_jpg_len 511 +#define color_bar_1_jpg_len 512 +#define color_bar_2_jpg_len 511 +#define color_bar_3_jpg_len 511 +#define color_bar_4_jpg_len 511 +#define color_bar_5_jpg_len 512 +#define color_bar_6_jpg_len 511 +#define color_bar_7_jpg_len 511 + +unsigned char color_bar_0_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x92, 0x8a, 0x00, + 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, + 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, + 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, + 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, + 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, + 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, + 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, + 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, + 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, + 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, + 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, + 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, + 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, + 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, + 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, + 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, + 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, + 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, + 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, + 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, + 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0xff, 0xd9 +}; +unsigned char color_bar_1_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x7d, 0x15, 0x98, + 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, + 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, + 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, + 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, + 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, + 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, + 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, + 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, + 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, + 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, + 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, + 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, + 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, + 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, + 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, + 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, + 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, + 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, + 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, + 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, + 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x7f, 0xff, 0xd9 +}; +unsigned char color_bar_2_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x75, 0x14, 0xcc, + 0xc4, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, + 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, + 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, + 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, + 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, + 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, + 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, + 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, + 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, + 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, + 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, + 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, + 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, + 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, + 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, + 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, + 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, + 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, + 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, + 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, + 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x33, 0xff, 0xd9 +}; +unsigned char color_bar_3_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x5a, 0x2a, 0x08, + 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, + 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, + 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, + 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, + 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, + 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, + 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, + 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, + 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, + 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, + 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, + 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, + 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, + 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, + 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, + 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, + 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, + 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, + 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, + 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, + 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x91, 0xff, 0xd9 +}; +unsigned char color_bar_4_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x4a, 0x2a, 0xcb, + 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, + 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, + 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, + 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, + 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, + 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, + 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, + 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, + 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, + 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, + 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, + 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, + 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, + 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, + 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, + 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, + 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, + 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, + 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, + 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, + 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x9f, 0xff, 0xd9 +}; +unsigned char color_bar_5_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x6d, 0x14, 0x8d, + 0x04, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, + 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, + 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, + 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, + 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, + 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, + 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, + 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, + 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, + 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, + 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, + 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, + 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, + 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, + 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, + 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, + 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, + 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, + 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, + 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, + 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x7f, 0xff, 0xd9 +}; +unsigned char color_bar_6_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x65, 0x15, 0xa0, + 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, + 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, + 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, + 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, + 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, + 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, + 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, + 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, + 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, + 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, + 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, + 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, + 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, + 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, + 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, + 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, + 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, + 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, + 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, + 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, + 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x33, 0xff, 0xd9 +}; +unsigned char color_bar_7_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x8e, 0x8a, 0x00, + 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, + 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, + 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, + 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, + 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, + 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, + 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, + 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, + 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, + 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, + 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, + 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, + 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, + 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, + 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, + 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, + 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, + 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, + 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, + 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, + 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x47, 0xff, 0xd9 +}; diff --git a/examples/device/video_capture/src/main.c b/examples/device/video_capture/src/main.c index 4028352da..362b168d4 100644 --- a/examples/device/video_capture/src/main.c +++ b/examples/device/video_capture/src/main.c @@ -110,8 +110,21 @@ static unsigned tx_busy = 0; static unsigned interval_ms = 1000 / FRAME_RATE; /* YUY2 frame buffer */ -#ifdef CFG_EXAMPLE_VIDEO_READONLY +#if 1 #include "images.h" +static struct { + uint32_t size; + uint8_t const *buffer; +} const frames[] = { + {color_bar_0_jpg_len, color_bar_0_jpg}, + {color_bar_1_jpg_len, color_bar_1_jpg}, + {color_bar_2_jpg_len, color_bar_2_jpg}, + {color_bar_3_jpg_len, color_bar_3_jpg}, + {color_bar_4_jpg_len, color_bar_4_jpg}, + {color_bar_5_jpg_len, color_bar_5_jpg}, + {color_bar_6_jpg_len, color_bar_6_jpg}, + {color_bar_7_jpg_len, color_bar_7_jpg}, +}; #else static uint8_t frame_buffer[FRAME_WIDTH * FRAME_HEIGHT * 16 / 8]; static void fill_color_bar(uint8_t *buffer, unsigned start_position) @@ -168,8 +181,7 @@ void video_task(void) already_sent = 1; start_ms = board_millis(); #ifdef CFG_EXAMPLE_VIDEO_READONLY - tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t) &frame_buffer[(frame_num % (FRAME_WIDTH / 2)) * 4], - FRAME_WIDTH * FRAME_HEIGHT * 16/8); + tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)&frames[frame_num % 8].buffer, frames[frame_num % 8].size); #else fill_color_bar(frame_buffer, frame_num); tud_video_n_frame_xfer(0, 0, (void*)frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16/8); @@ -182,8 +194,7 @@ void video_task(void) start_ms += interval_ms; #ifdef CFG_EXAMPLE_VIDEO_READONLY - tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t) &frame_buffer[(frame_num % (FRAME_WIDTH / 2)) * 4], - FRAME_WIDTH * FRAME_HEIGHT * 16/8); + tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)&frames[frame_num % 8].buffer, frames[frame_num % 8].size); #else fill_color_bar(frame_buffer, frame_num); tud_video_n_frame_xfer(0, 0, (void*)frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16/8); diff --git a/examples/device/video_capture/src/usb_descriptors.h b/examples/device/video_capture/src/usb_descriptors.h index 90537aa06..aa937e168 100644 --- a/examples/device/video_capture/src/usb_descriptors.h +++ b/examples/device/video_capture/src/usb_descriptors.h @@ -90,17 +90,17 @@ enum { /* Video stream header for without still image capture */ \ TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ /*wTotalLength - bLength */\ - TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\ - + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\ + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\ + + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ /*bmaControls(1)*/0), \ /* Video stream format */ \ - TUD_VIDEO_DESC_CS_VS_FMT_YUY2(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ - /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ + 1, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ /* Video stream frame format */ \ - TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT(/*bFrameIndex */1, 0, _width, _height, \ + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT(/*bFrameIndex */1, 0, _width, _height, \ _width * _height * 16, _width * _height * 16 * _fps, \ _width * _height * 16, \ (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ diff --git a/src/class/video/video.h b/src/class/video/video.h index 844746546..e8227ea60 100644 --- a/src/class/video/video.h +++ b/src/class/video/video.h @@ -302,6 +302,45 @@ typedef struct TU_ATTR_PACKED { uint8_t bCopyProtect; } tusb_desc_cs_video_fmt_uncompressed_t; +typedef struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bFormatIndex; + uint8_t bNumFrameDescriptors; + uint8_t bmFlags; + uint8_t bDefaultFrameIndex; + uint8_t bAspectRatioX; + uint8_t bAspectRatioY; + uint8_t bmInterlaceFlags; + uint8_t bCopyProtect; +} tusb_desc_cs_video_fmt_mjpeg_t; + +typedef struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bFormatIndex; + uint32_t dwMaxVideoFrameBufferSize; /* deprecated */ + uint8_t bFormatType; +} tusb_desc_cs_video_fmt_dv_t; + +typedef struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bFormatIndex; + uint8_t bNumFrameDescriptors; + uint8_t guidFormat[16]; + uint8_t bBitsPerPixel; + uint8_t bDefaultFrameIndex; + uint8_t bAspectRatioX; + uint8_t bAspectRatioY; + uint8_t bmInterlaceFlags; + uint8_t bCopyProtect; + uint8_t bVaribaleSize; +} tusb_desc_cs_video_fmt_frame_based_t; + typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; @@ -318,6 +357,24 @@ typedef struct TU_ATTR_PACKED { uint32_t dwFrameInterval[]; } tusb_desc_cs_video_frm_uncompressed_t; +typedef tusb_desc_cs_video_frm_uncompressed_t tusb_desc_cs_video_frm_mjpeg_t; + +typedef struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bFrameIndex; + uint8_t bmCapabilities; + uint16_t wWidth; + uint16_t wHeight; + uint32_t dwMinBitRate; + uint32_t dwMaxBitRate; + uint32_t dwDefaultFrameInterval; + uint8_t bFrameIntervalType; + uint32_t dwBytesPerLine; + uint32_t dwFrameInterval[]; +} tusb_desc_cs_video_frm_frame_based_t; + //--------------------------------------------------------------------+ // Requests //--------------------------------------------------------------------+ @@ -378,8 +435,11 @@ TU_VERIFY_STATIC( sizeof(video_probe_and_commit_control_t) == 48, "size is not c #define TUD_VIDEO_DESC_CS_VS_IN_LEN 13 #define TUD_VIDEO_DESC_CS_VS_OUT_LEN 9 #define TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN 27 +#define TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN 11 #define TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN 38 #define TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_DISC_LEN 26 +#define TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN 38 +#define TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_DISC_LEN 26 #define TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN 6 /* 2.2 compression formats */ @@ -462,6 +522,25 @@ TU_VERIFY_STATIC( sizeof(video_probe_and_commit_control_t) == 48, "size is not c _frmidx, _cap, U16_TO_U8S_LE(_width), U16_TO_U8S_LE(_height), U32_TO_U8S_LE(_minbr), U32_TO_U8S_LE(_maxbr), \ U32_TO_U8S_LE(_maxfrmbufsz), U32_TO_U8S_LE(_frminterval), (TU_ARGS_NUM(__VA_ARGS__)), __VA_ARGS__ +/* Motion-JPEG 3.1.1 Table 3-1 */ +#define TUD_VIDEO_DESC_CS_VS_FMT_MJPEG(_fmtidx, _numfrmdesc, _fixed_sz, _frmidx, _asrx, _asry, _interlace, _cp) \ + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_FORMAT_MJPEG, \ + _fmtidx, _numfrmdesc, _fixed_sz, _frmidx, _asrx, _asry, _interlace, _cp + +/* Motion-JPEG 3.1.1 Table 3-2 and 3-3 */ +#define TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT(_frmidx, _cap, _width, _height, _minbr, _maxbr, _maxfrmbufsz, _frminterval, _minfrminterval, _maxfrminterval, _frmintervalstep) \ + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_FRAME_MJPEG, \ + _frmidx, _cap, U16_TO_U8S_LE(_width), U16_TO_U8S_LE(_height), U32_TO_U8S_LE(_minbr), U32_TO_U8S_LE(_maxbr), \ + U32_TO_U8S_LE(_maxfrmbufsz), U32_TO_U8S_LE(_frminterval), 0, \ + U32_TO_U8S_LE(_minfrminterval), U32_TO_U8S_LE(_maxfrminterval), U32_TO_U8S_LE(_frmintervalstep) + +/* Motion-JPEG 3.1.1 Table 3-2 and 3-4 */ +#define TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_DISC(_frmidx, _cap, _width, _height, _minbr, _maxbr, _maxfrmbufsz, _frminterval, ...) \ + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_DISC_LEN + (TU_ARGS_NUM(__VA_ARGS__)) * 4, \ + TUSB_DESC_CS_INTERFACE, VIDEO_CS_VS_INTERFACE_FRAME_MJPEG, \ + _frmidx, _cap, U16_TO_U8S_LE(_width), U16_TO_U8S_LE(_height), U32_TO_U8S_LE(_minbr), U32_TO_U8S_LE(_maxbr), \ + U32_TO_U8S_LE(_maxfrmbufsz), U32_TO_U8S_LE(_frminterval), (TU_ARGS_NUM(__VA_ARGS__)), __VA_ARGS__ + /* 3.9.2.6 */ #define TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(_color, _trns, _mat) \ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN, \ diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 7636db5fe..39e2e9aac 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -29,6 +29,8 @@ #if (CFG_TUD_ENABLED && CFG_TUD_VIDEO && CFG_TUD_VIDEO_STREAMING) +#include + #include "device/usbd.h" #include "device/usbd_pvt.h" @@ -59,6 +61,30 @@ typedef struct TU_ATTR_PACKED { uint8_t bEntityId; } tusb_desc_cs_video_entity_itf_t; +typedef union { + struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bFormatIndex; + }; + tusb_desc_cs_video_fmt_uncompressed_t uncompressed; + tusb_desc_cs_video_fmt_mjpeg_t mjpeg; + tusb_desc_cs_video_fmt_frame_based_t frame_based; +} tusb_desc_cs_video_fmt_t; + +typedef union { + struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bFrameIndex; + }; + tusb_desc_cs_video_frm_uncompressed_t uncompressed; + tusb_desc_cs_video_frm_mjpeg_t mjpeg; + tusb_desc_cs_video_frm_frame_based_t frame_based; +} tusb_desc_cs_video_frm_t; + /* video streaming interface */ typedef struct TU_ATTR_PACKED { uint8_t index_vc; /* index of bound video control interface */ @@ -167,6 +193,72 @@ static void const* _find_desc(void const *beg, void const *end, uint_fast8_t des return cur; } +/** Find the first descriptor of a given types + * + * @param[in] beg The head of descriptor byte array. + * @param[in] end The tail of descriptor byte array. + * @param[in] ... The target descriptor types. The last type must be 0. + * + * @return The pointer for interface descriptor. + * @retval end did not found interface descriptor */ +static void const* _find_desc_n(void const *beg, void const *end, ...) +{ + uint_fast8_t target = 0; + void const *cur; + for (cur = beg; cur < end && !target; cur = tu_desc_next(cur)) { + uint_fast8_t actual = tu_desc_type(cur); + va_list ap; + va_start(ap, end); + do { + target = va_arg(ap, unsigned); + } while (target && target != actual); + va_end(ap); + } + return cur; +} + +/** Find the first descriptor specified by the arguments + * + * @param[in] beg The head of descriptor byte array. + * @param[in] end The tail of descriptor byte array. + * @param[in] sub_types The target bDescriptorSubtype list. The last elemnt must be 0. + * + * @return The pointer for interface descriptor. + * @retval end did not found interface descriptor */ +static void const* _find_desc_cs(void const *beg, void const *end, uint8_t const *sub_types) +{ + uint_fast8_t target = 0; + void const *cur; + for (cur = beg; cur < end && !target; cur = _find_desc(cur, end, TUSB_DESC_CS_INTERFACE)) { + uint_fast8_t actual = ((uint8_t const *)cur)[2]; + uint8_t const *p = sub_types; + do { + target = *p++; + } while (target && target != actual); + } + return cur; +} + +/** Find the first descriptor specified by the arguments + * + * @param[in] beg The head of descriptor byte array. + * @param[in] end The tail of descriptor byte array. + * @param[in] desc_type The target descriptor type + * @param[in] element_0 The target element following the desc_type + * + * @return The pointer for interface descriptor. + * @retval end did not found interface descriptor */ +static void const* _find_desc_2(void const *beg, void const *end, + uint_fast8_t desc_type, uint_fast8_t element_0) +{ + for (void const *cur = beg; cur < end; cur = _find_desc(cur, end, desc_type)) { + uint8_t const *p = (uint8_t const *)cur; + if (p[2] == element_0) return cur; + cur = tu_desc_next(cur); + } + return end; +} + /** Find the first descriptor specified by the arguments * * @param[in] beg The head of descriptor byte array. @@ -235,14 +327,19 @@ static inline void const* _find_desc_itf(void const *beg, void const *end, uint_ * @retval end did not found endpoint descriptor */ static void const* _find_desc_ep(void const *beg, void const *end) { - for (void const *cur = beg; cur < end; cur = tu_desc_next(cur)) { - uint_fast8_t desc_type = tu_desc_type(cur); - if (TUSB_DESC_ENDPOINT == desc_type) return cur; - if (TUSB_DESC_INTERFACE == desc_type) break; - } + void const *cur = _find_desc_n(beg, end, TUSB_DESC_ENDPOINT, TUSB_DESC_INTERFACE, 0); + if ((cur < end) && (TUSB_DESC_ENDPOINT == tu_desc_type(cur))) + return cur; return end; } +/** Return the end of the video control descriptor. */ +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 desc + vc->std.bLength + vc->ctl.wTotalLength; +} + /** Find the first entity descriptor with the entity ID * specified by the argument belonging to the current video control descriptor. * @@ -253,10 +350,8 @@ static void const* _find_desc_ep(void const *beg, void const *end) * @retval end did not found interface descriptor */ static void const* _find_desc_entity(void const *desc, uint_fast8_t entityid) { - tusb_desc_vc_itf_t const *vc = (tusb_desc_vc_itf_t const*)desc; - void const *beg = vc; - void const *end = beg + vc->std.bLength + vc->ctl.wTotalLength; - for (void const *cur = beg; cur < end; cur = _find_desc(cur, end, TUSB_DESC_CS_INTERFACE)) { + void const *end = _end_of_control_descriptor(desc); + for (void const *cur = desc; cur < end; cur = _find_desc(cur, end, TUSB_DESC_CS_INTERFACE)) { tusb_desc_cs_video_entity_itf_t const *itf = (tusb_desc_cs_video_entity_itf_t const *)cur; if ((VIDEO_CS_ITF_VC_INPUT_TERMINAL <= itf->bDescriptorSubtype && itf->bDescriptorSubtype < VIDEO_CS_ITF_VC_MAX) @@ -276,17 +371,38 @@ static inline void const* _end_of_streaming_descriptor(void const *desc) } /** Find the first format descriptor with the specified format number. */ -static inline tusb_desc_cs_video_fmt_uncompressed_t const *_find_desc_format(void const *beg, void const *end, uint_fast8_t fmtnum) +static inline void const *_find_desc_format(void const *beg, void const *end, uint_fast8_t fmtnum) { - return (tusb_desc_cs_video_fmt_uncompressed_t const*) - _find_desc_3(beg, end, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED, fmtnum); + static uint8_t const sub_types[] = { + VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED, + VIDEO_CS_ITF_VS_FORMAT_MJPEG, + VIDEO_CS_ITF_VS_FORMAT_DV, + VIDEO_CS_ITF_VS_FORMAT_FRAME_BASED, + 0 + }; + while (true) { + uint8_t const *cur = _find_desc_cs(beg, end, sub_types); + if ((end == cur) || (fmtnum == cur[3])) + return cur; + cur = tu_desc_next(cur); + } } /** Find the first frame descriptor with the specified format number. */ -static inline tusb_desc_cs_video_frm_uncompressed_t const *_find_desc_frame(void const *beg, void const *end, uint_fast8_t frmnum) +static inline void const *_find_desc_frame(void const *beg, void const *end, uint_fast8_t frmnum) { - return (tusb_desc_cs_video_frm_uncompressed_t const*) - _find_desc_3(beg, end, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED, frmnum); + static uint8_t const sub_types[] = { + VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED, + VIDEO_CS_ITF_VS_FRAME_MJPEG, + VIDEO_CS_ITF_VS_FRAME_FRAME_BASED, + 0 + }; + while (true) { + uint8_t const *cur = _find_desc_cs(beg, end, sub_types); + if ((end == cur) || (frmnum == ((uint8_t const *)cur)[3])) + return cur; + cur = tu_desc_next(cur); + } } /** Set uniquely determined values to variables that have not been set @@ -307,7 +423,6 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm /* Set the parameters determined by the format */ param->wKeyFrameRate = 1; param->wPFrameRate = 0; - param->wCompQuality = 1; /* 1 to 10000 */ param->wCompWindowSize = 1; /* GOP size? */ param->wDelay = 0; /* milliseconds */ param->dwClockFrequency = 27000000; /* same as MPEG-2 system time clock */ @@ -319,8 +434,18 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm param->bBitDepthLuma = 8; void const *end = _end_of_streaming_descriptor(vs); - tusb_desc_cs_video_fmt_uncompressed_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); + tusb_desc_cs_video_fmt_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); TU_ASSERT(fmt != end); + + switch (fmt->bDescriptorSubtype) { + case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED: + param->wCompQuality = 1; /* 1 to 10000 */ + break; + case VIDEO_CS_ITF_VS_FORMAT_MJPEG; + break; + default: return false; + } + uint_fast8_t frmnum = param->bFrameIndex; TU_ASSERT(frmnum <= fmt->bNumFrameDescriptors); if (!frmnum) { @@ -328,13 +453,21 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm frmnum = 1; param->bFrameIndex = 1; } - tusb_desc_cs_video_frm_uncompressed_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); + tusb_desc_cs_video_frm_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); TU_ASSERT(frm != end); /* Set the parameters determined by the frame */ uint_fast32_t frame_size = param->dwMaxVideoFrameSize; if (!frame_size) { - frame_size = (uint_fast32_t)frm->wWidth * frm->wHeight * fmt->bBitsPerPixel / 8; + switch (fmt->bDescriptorSubtype) { + case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED: + frame_size = (uint_fast32_t)frm->uncompressed.wWidth * frm->uncompressed.wHeight * fmt->uncompressed.bBitsPerPixel / 8; + break; + case VIDEO_CS_ITF_VS_FORMAT_MJPEG; + frame_size = (uint_fast32_t)frm->mjpeg.wWidth * frm->mjpeg.wHeight * 16 / 8; /* YUV422 */ + break; + default: break; + } param->dwMaxVideoFrameSize = frame_size; } @@ -487,7 +620,7 @@ static bool _close_vc_itf(uint8_t rhport, videod_interface_t *self) /* The next descriptor after the class-specific VC interface header descriptor. */ void const *cur = (void const*)vc + vc->std.bLength + vc->ctl.bLength; /* The end of the video control interface descriptor. */ - void const *end = (void const*)vc + vc->std.bLength + vc->ctl.wTotalLength; + void const *end = _end_of_control_descriptor(vc); if (vc->std.bNumEndpoints) { /* Find the notification endpoint descriptor. */ cur = _find_desc(cur, end, TUSB_DESC_ENDPOINT); @@ -519,7 +652,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 = cur + vc->std.bLength + vc->ctl.wTotalLength; + 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; TU_LOG2(" bNumEndpoints %d\n", vc->std.bNumEndpoints); From 1debf6270786a612ad99172db76169e025e124f6 Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Wed, 10 Nov 2021 00:39:51 +0900 Subject: [PATCH 469/504] Fix compile errors --- .../video_capture/src/usb_descriptors.h | 6 ++--- src/class/video/video_device.c | 24 +++++++++++-------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/examples/device/video_capture/src/usb_descriptors.h b/examples/device/video_capture/src/usb_descriptors.h index aa937e168..10bae4750 100644 --- a/examples/device/video_capture/src/usb_descriptors.h +++ b/examples/device/video_capture/src/usb_descriptors.h @@ -53,8 +53,8 @@ enum { /* Interface 1, Alternate 0 */\ + TUD_VIDEO_DESC_STD_VS_LEN\ + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ - + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\ - + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\ + + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\ + + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ /* Interface 1, Alternate 1 */\ + TUD_VIDEO_DESC_STD_VS_LEN\ @@ -98,7 +98,7 @@ enum { /*bmaControls(1)*/0), \ /* Video stream format */ \ TUD_VIDEO_DESC_CS_VS_FMT_MJPEG(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ - 1, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ + /*bmFlags*/0, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ /* Video stream frame format */ \ TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT(/*bFrameIndex */1, 0, _width, _height, \ _width * _height * 16, _width * _height * 16 * _fps, \ diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 39e2e9aac..14eaca9a4 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -67,6 +67,7 @@ typedef union { uint8_t bDescriptorType; uint8_t bDescriptorSubType; uint8_t bFormatIndex; + uint8_t bNumFrameDescriptors; }; tusb_desc_cs_video_fmt_uncompressed_t uncompressed; tusb_desc_cs_video_fmt_mjpeg_t mjpeg; @@ -437,11 +438,11 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm tusb_desc_cs_video_fmt_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); TU_ASSERT(fmt != end); - switch (fmt->bDescriptorSubtype) { + switch (fmt->bDescriptorSubType) { case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED: param->wCompQuality = 1; /* 1 to 10000 */ break; - case VIDEO_CS_ITF_VS_FORMAT_MJPEG; + case VIDEO_CS_ITF_VS_FORMAT_MJPEG: break; default: return false; } @@ -459,11 +460,11 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm /* Set the parameters determined by the frame */ uint_fast32_t frame_size = param->dwMaxVideoFrameSize; if (!frame_size) { - switch (fmt->bDescriptorSubtype) { + switch (fmt->bDescriptorSubType) { case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED: frame_size = (uint_fast32_t)frm->uncompressed.wWidth * frm->uncompressed.wHeight * fmt->uncompressed.bBitsPerPixel / 8; break; - case VIDEO_CS_ITF_VS_FORMAT_MJPEG; + case VIDEO_CS_ITF_VS_FORMAT_MJPEG: frame_size = (uint_fast32_t)frm->mjpeg.wWidth * frm->mjpeg.wHeight * 16 / 8; /* YUV422 */ break; default: break; @@ -473,11 +474,12 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm uint_fast32_t interval = param->dwFrameInterval; if (!interval) { - if ((1 < frm->bFrameIntervalType) || - ((0 == frm->bFrameIntervalType) && (frm->dwFrameInterval[1] != frm->dwFrameInterval[0]))) { + if ((1 < frm->uncompressed.bFrameIntervalType) || + ((0 == frm->uncompressed.bFrameIntervalType) && + (frm->uncompressed.dwFrameInterval[1] != frm->uncompressed.dwFrameInterval[0]))) { return true; } - interval = frm->dwFrameInterval[0]; + interval = frm->uncompressed.dwFrameInterval[0]; param->dwFrameInterval = interval; } uint_fast32_t interval_ms = interval / 10000; @@ -709,6 +711,7 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint video_probe_and_commit_control_t *param = (video_probe_and_commit_control_t *)&stm->ep_buf; tu_memclr(param, sizeof(*param)); + TU_LOG2(" done 0\n"); return _update_streaming_parameters(stm, param); } /* Open endpoints of the new settings. */ @@ -737,6 +740,7 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint hdr->bHeaderLength = sizeof(*hdr); hdr->bmHeaderInfo = 0; + TU_LOG2(" done\n"); return true; } @@ -809,7 +813,7 @@ static int handle_video_ctl_cs_req(uint8_t rhport, uint8_t stage, if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(1 == request->wLength, VIDEO_ERROR_UNKNOWN); TU_VERIFY(tud_control_xfer(rhport, request, &self->power_mode, sizeof(self->power_mode)), VIDEO_ERROR_UNKNOWN); - } else if (stage == CONTROL_STAGE_ACK) { + } else if (stage == CONTROL_STAGE_DATA) { if (tud_video_power_mode_cb) return tud_video_power_mode_cb(ctl_idx, self->power_mode); } return VIDEO_ERROR_NONE; @@ -954,7 +958,7 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, TU_VERIFY(sizeof(video_probe_and_commit_control_t) == request->wLength, VIDEO_ERROR_UNKNOWN); TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); - } else if (stage == CONTROL_STAGE_ACK) { + } else if (stage == CONTROL_STAGE_DATA) { TU_VERIFY(_update_streaming_parameters(self, (video_probe_and_commit_control_t*)self->ep_buf), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE); } @@ -1009,7 +1013,7 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(sizeof(video_probe_and_commit_control_t) == request->wLength, VIDEO_ERROR_UNKNOWN); TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); - } else if (stage == CONTROL_STAGE_ACK) { + } else if (stage == CONTROL_STAGE_DATA) { TU_VERIFY(_update_streaming_parameters(self, (video_probe_and_commit_control_t*)self->ep_buf), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE); if (tud_video_commit_cb) { return tud_video_commit_cb(self->index_vc, self->index_vs, (video_probe_and_commit_control_t*)self->ep_buf); From 6c3c2df82343e1947a7be3c5f0e72a116c1b634e Mon Sep 17 00:00:00 2001 From: Mark K Cowan Date: Sat, 17 Sep 2022 21:27:04 +0300 Subject: [PATCH 470/504] audio_device: prototype added for function referenced before use --- src/class/audio/audio_device.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index a021755ba..a65d605b7 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -447,6 +447,10 @@ static inline uint8_t tu_desc_subtype(void const* desc) } #endif +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP +static bool set_fb_params_freq(audiod_function_t* audio, uint32_t sample_freq, uint32_t mclk_freq); +#endif + bool tud_audio_n_mounted(uint8_t func_id) { TU_VERIFY(func_id < CFG_TUD_AUDIO); From ee832e4e37a0ea35d9c2751ee3600ae7a600cb12 Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Mon, 3 Oct 2022 21:41:58 +0900 Subject: [PATCH 471/504] Fix descriptor searching --- src/class/video/video_device.c | 121 ++++++++------------------------- 1 file changed, 28 insertions(+), 93 deletions(-) diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 14eaca9a4..690e64658 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -29,8 +29,6 @@ #if (CFG_TUD_ENABLED && CFG_TUD_VIDEO && CFG_TUD_VIDEO_STREAMING) -#include - #include "device/usbd.h" #include "device/usbd_pvt.h" @@ -194,72 +192,6 @@ static void const* _find_desc(void const *beg, void const *end, uint_fast8_t des return cur; } -/** Find the first descriptor of a given types - * - * @param[in] beg The head of descriptor byte array. - * @param[in] end The tail of descriptor byte array. - * @param[in] ... The target descriptor types. The last type must be 0. - * - * @return The pointer for interface descriptor. - * @retval end did not found interface descriptor */ -static void const* _find_desc_n(void const *beg, void const *end, ...) -{ - uint_fast8_t target = 0; - void const *cur; - for (cur = beg; cur < end && !target; cur = tu_desc_next(cur)) { - uint_fast8_t actual = tu_desc_type(cur); - va_list ap; - va_start(ap, end); - do { - target = va_arg(ap, unsigned); - } while (target && target != actual); - va_end(ap); - } - return cur; -} - -/** Find the first descriptor specified by the arguments - * - * @param[in] beg The head of descriptor byte array. - * @param[in] end The tail of descriptor byte array. - * @param[in] sub_types The target bDescriptorSubtype list. The last elemnt must be 0. - * - * @return The pointer for interface descriptor. - * @retval end did not found interface descriptor */ -static void const* _find_desc_cs(void const *beg, void const *end, uint8_t const *sub_types) -{ - uint_fast8_t target = 0; - void const *cur; - for (cur = beg; cur < end && !target; cur = _find_desc(cur, end, TUSB_DESC_CS_INTERFACE)) { - uint_fast8_t actual = ((uint8_t const *)cur)[2]; - uint8_t const *p = sub_types; - do { - target = *p++; - } while (target && target != actual); - } - return cur; -} - -/** Find the first descriptor specified by the arguments - * - * @param[in] beg The head of descriptor byte array. - * @param[in] end The tail of descriptor byte array. - * @param[in] desc_type The target descriptor type - * @param[in] element_0 The target element following the desc_type - * - * @return The pointer for interface descriptor. - * @retval end did not found interface descriptor */ -static void const* _find_desc_2(void const *beg, void const *end, - uint_fast8_t desc_type, uint_fast8_t element_0) -{ - for (void const *cur = beg; cur < end; cur = _find_desc(cur, end, desc_type)) { - uint8_t const *p = (uint8_t const *)cur; - if (p[2] == element_0) return cur; - cur = tu_desc_next(cur); - } - return end; -} - /** Find the first descriptor specified by the arguments * * @param[in] beg The head of descriptor byte array. @@ -328,9 +260,11 @@ static inline void const* _find_desc_itf(void const *beg, void const *end, uint_ * @retval end did not found endpoint descriptor */ static void const* _find_desc_ep(void const *beg, void const *end) { - void const *cur = _find_desc_n(beg, end, TUSB_DESC_ENDPOINT, TUSB_DESC_INTERFACE, 0); - if ((cur < end) && (TUSB_DESC_ENDPOINT == tu_desc_type(cur))) - return cur; + for (void const *cur = beg; cur < end; cur = tu_desc_next(cur)) { + uint_fast8_t desc_type = tu_desc_type(cur); + if (TUSB_DESC_ENDPOINT == desc_type) return cur; + if (TUSB_DESC_INTERFACE == desc_type) break; + } return end; } @@ -374,36 +308,36 @@ static inline void const* _end_of_streaming_descriptor(void const *desc) /** Find the first format descriptor with the specified format number. */ static inline void const *_find_desc_format(void const *beg, void const *end, uint_fast8_t fmtnum) { - static uint8_t const sub_types[] = { - VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED, - VIDEO_CS_ITF_VS_FORMAT_MJPEG, - VIDEO_CS_ITF_VS_FORMAT_DV, - VIDEO_CS_ITF_VS_FORMAT_FRAME_BASED, - 0 - }; - while (true) { - uint8_t const *cur = _find_desc_cs(beg, end, sub_types); - if ((end == cur) || (fmtnum == cur[3])) + for (void const *cur = beg; cur < end; cur = _find_desc(cur, end, TUSB_DESC_CS_INTERFACE)) { + uint8_t const *p = (uint8_t const *)cur; + uint_fast8_t fmt = p[2]; + if ((fmt == VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED || + fmt == VIDEO_CS_ITF_VS_FORMAT_MJPEG || + fmt == VIDEO_CS_ITF_VS_FORMAT_DV || + fmt == VIDEO_CS_ITF_VS_FRAME_FRAME_BASED) && + fmtnum == p[3]) { return cur; + } cur = tu_desc_next(cur); } + return end; } /** Find the first frame descriptor with the specified format number. */ static inline void const *_find_desc_frame(void const *beg, void const *end, uint_fast8_t frmnum) { - static uint8_t const sub_types[] = { - VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED, - VIDEO_CS_ITF_VS_FRAME_MJPEG, - VIDEO_CS_ITF_VS_FRAME_FRAME_BASED, - 0 - }; - while (true) { - uint8_t const *cur = _find_desc_cs(beg, end, sub_types); - if ((end == cur) || (frmnum == ((uint8_t const *)cur)[3])) + for (void const *cur = beg; cur < end; cur = _find_desc(cur, end, TUSB_DESC_CS_INTERFACE)) { + uint8_t const *p = (uint8_t const *)cur; + uint_fast8_t frm = p[2]; + if ((frm == VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED || + frm == VIDEO_CS_ITF_VS_FRAME_MJPEG || + frm == VIDEO_CS_ITF_VS_FRAME_FRAME_BASED) && + frmnum == p[3]) { return cur; + } cur = tu_desc_next(cur); } + return end; } /** Set uniquely determined values to variables that have not been set @@ -501,7 +435,8 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * if (!fmtnum) { switch (request) { case VIDEO_REQUEST_GET_MAX: - param->bFormatIndex = _get_desc_vs(stm)->stm.bNumFormats; + if (_get_desc_vs(stm)) + param->bFormatIndex = _get_desc_vs(stm)->stm.bNumFormats; break; case VIDEO_REQUEST_GET_MIN: case VIDEO_REQUEST_GET_DEF: @@ -982,7 +917,7 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, video_probe_and_commit_control_t tmp; tmp = *(video_probe_and_commit_control_t*)&self->ep_buf; TU_VERIFY(_negotiate_streaming_parameters(self, request->bRequest, &tmp), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE); - TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); + TU_VERIFY(tud_control_xfer(rhport, request, &tmp, sizeof(tmp)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; @@ -999,7 +934,7 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(1 == request->wLength, VIDEO_ERROR_UNKNOWN); - TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)(uintptr_t) &_cap_get_set, sizeof(_cap_get_set)), VIDEO_ERROR_UNKNOWN); + TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)(uintptr_t)&_cap_get_set, sizeof(_cap_get_set)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; From 988eeb50c6c962279360b457803859956a0d38e4 Mon Sep 17 00:00:00 2001 From: mingpepe Date: Wed, 5 Oct 2022 21:26:22 +0800 Subject: [PATCH 472/504] Fix typo for log in dcd_rp2040.c --- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index 2003f72fd..4952d29b1 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -88,7 +88,7 @@ static void _hw_endpoint_alloc(struct hw_endpoint *ep, uint8_t transfer_type) uint dpram_offset = hw_data_offset(ep->hw_data_buf); hard_assert(hw_data_offset(next_buffer_ptr) <= USB_DPRAM_MAX); - pico_info(" Alloced %d bytes at offset 0x%x (0x%p)\r\n", size, dpram_offset, ep->hw_data_buf); + pico_info(" Allocated %d bytes at offset 0x%x (0x%p)\r\n", size, dpram_offset, ep->hw_data_buf); // Fill in endpoint control register with buffer offset uint32_t const reg = EP_CTRL_ENABLE_BITS | ((uint)transfer_type << EP_CTRL_BUFFER_TYPE_LSB) | dpram_offset; From 8096afc6dea975e95e0b50dc4b55926236b90b62 Mon Sep 17 00:00:00 2001 From: ReimuNotMoe <34613827+ReimuNotMoe@users.noreply.github.com> Date: Thu, 6 Oct 2022 03:45:51 +0800 Subject: [PATCH 473/504] Microchip PIC24/dsPIC33 device mode support --- src/common/tusb_mcu.h | 5 + src/portable/microchip/pic/dcd_pic.c | 141 ++++++++++++++++++++------- 2 files changed, 113 insertions(+), 33 deletions(-) diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index baa82fc14..514ffcd4d 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -111,6 +111,11 @@ #define TUP_DCD_ENDPOINT_MAX 8 #define TUP_DCD_ENDPOINT_EXCLUSIVE_NUMBER +#elif TU_CHECK_MCU(OPT_MCU_PIC32MX, OPT_MCU_PIC32MM, OPT_MCU_PIC32MK) || \ + TU_CHECK_MCU(OPT_MCU_PIC24, OPT_MCU_DSPIC33) + #define TUP_DCD_ENDPOINT_MAX 16 + #define TUP_DCD_ENDPOINT_EXCLUSIVE_NUMBER + //------------- ST -------------// #elif TU_CHECK_MCU(OPT_MCU_STM32F0) #define TUP_DCD_ENDPOINT_MAX 8 diff --git a/src/portable/microchip/pic/dcd_pic.c b/src/portable/microchip/pic/dcd_pic.c index df9b2ff01..6cf0e6285 100644 --- a/src/portable/microchip/pic/dcd_pic.c +++ b/src/portable/microchip/pic/dcd_pic.c @@ -39,14 +39,10 @@ #if (CFG_TUSB_MCU == OPT_MCU_PIC32MX || CFG_TUSB_MCU == OPT_MCU_PIC32MM || CFG_TUSB_MCU == OPT_MCU_PIC32MK) -#define TU_PIC_HAS_MMU 1 -#define TU_PIC_HAS_HW_RMW 1 #define TU_PIC_INT_SIZE 4 #elif (CFG_TUSB_MCU == OPT_MCU_PIC24 || CFG_TUSB_MCU == OPT_MCU_DSPIC33) -#define TU_PIC_HAS_MMU 0 -#define TU_PIC_HAS_HW_RMW 0 #define TU_PIC_INT_SIZE 2 #else @@ -56,7 +52,7 @@ #endif -#if TU_PIC_HAS_MMU +#if TU_PIC_INT_SIZE == 4 #ifndef KVA_TO_PA #define KVA_TO_PA(kva) ((uint32_t)(kva) & 0x1fffffff) @@ -89,6 +85,8 @@ enum { TOK_PID_SETUP = 0xDu, }; +// The BDT is 8 bytes on 32bit PICs and 4 bytes on 8/16bit PICs +#if TU_PIC_INT_SIZE == 4 typedef struct TU_ATTR_PACKED { union { @@ -119,6 +117,37 @@ typedef struct TU_ATTR_PACKED } buffer_descriptor_t; TU_VERIFY_STATIC( sizeof(buffer_descriptor_t) == 8, "size is not correct" ); +#else +typedef struct TU_ATTR_PACKED +{ + union { + uint16_t head; + + struct { + uint16_t : 10; + uint16_t tok_pid : 4; + uint16_t data : 1; + uint16_t own : 1; + }; + struct { + uint16_t : 10; + uint16_t bdt_stall : 1; + uint16_t dts : 1; + uint16_t ninc : 1; + uint16_t keep : 1; + }; + + struct { + uint16_t bc : 10; + uint16_t : 6; + }; + }; + uint8_t *addr; +} buffer_descriptor_t; + +TU_VERIFY_STATIC( sizeof(buffer_descriptor_t) == 4, "size is not correct" ); +#endif + typedef struct TU_ATTR_PACKED { @@ -142,7 +171,11 @@ typedef struct union { /* [#EP][OUT,IN][EVEN,ODD] */ buffer_descriptor_t bdt[16][2][2]; - uint16_t bda[512]; +#if TU_PIC_INT_SIZE == 4 + uint16_t bda[256]; +#else + uint8_t bda[256]; +#endif }; TU_ATTR_ALIGNED(4) union { endpoint_state_t endpoint[16][2]; @@ -158,7 +191,11 @@ typedef struct // BDT(Buffer Descriptor Table) must be 256-byte aligned CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(512) volatile static dcd_data_t _dcd; +#if TU_PIC_INT_SIZE == 4 TU_VERIFY_STATIC( sizeof(_dcd.bdt) == 512, "size is not correct" ); +#else +TU_VERIFY_STATIC( sizeof(_dcd.bdt) == 256, "size is not correct" ); +#endif #if TU_PIC_INT_SIZE == 4 typedef uint32_t ep_reg_t; @@ -172,7 +209,12 @@ static inline volatile void *ep_addr(uint8_t rhport, uint8_t ep_num) { #else volatile void *ep_reg_base = &U1EP0; #endif - return ep_reg_base + 0x10 * ep_num; +#if TU_PIC_INT_SIZE == 4 + const size_t offset = 0x10; +#else + const size_t offset = 0x2; +#endif + return ep_reg_base + offset * ep_num; } static inline ep_reg_t ep_read(uint8_t rhport, uint8_t ep_num) { @@ -186,7 +228,7 @@ static inline void ep_write(uint8_t rhport, uint8_t ep_num, ep_reg_t val) { } static inline void ep_clear(uint8_t rhport, uint8_t ep_num, ep_reg_t val) { -#if TU_PIC_HAS_HW_RMW +#if TU_PIC_INT_SIZE == 4 volatile ep_reg_t *ep_clr = (ep_addr(rhport, ep_num) + 0x4); *ep_clr = val; #else @@ -197,7 +239,7 @@ static inline void ep_clear(uint8_t rhport, uint8_t ep_num, ep_reg_t val) { } static inline void ep_set(uint8_t rhport, uint8_t ep_num, ep_reg_t val) { -#if TU_PIC_HAS_HW_RMW +#if TU_PIC_INT_SIZE == 4 volatile ep_reg_t *ep_s = (ep_addr(rhport, ep_num) + 0x8); *ep_s = val; #else @@ -278,7 +320,7 @@ static void prepare_next_setup_packet(uint8_t rhport) _dcd.bdt[0][1][in_odd].data = 1; _dcd.bdt[0][1][in_odd ^ 1].data = 0; dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_OUT), - _dcd.setup_packet, sizeof(_dcd.setup_packet)); + _dcd.setup_packet, sizeof(_dcd.setup_packet)); } static void process_stall(uint8_t rhport) @@ -298,7 +340,7 @@ static void process_stall(uint8_t rhport) static void process_tokdne(uint8_t rhport) { - uint32_t s = U1STAT; + ep_reg_t s = U1STAT; U1IR = _U1IR_TRNIF_MASK; @@ -321,7 +363,11 @@ static void process_tokdne(uint8_t rhport) ep->odd = odd ^ 1; if (pid == TOK_PID_SETUP) { dcd_event_setup_received(rhport, (uint8_t *)PA_TO_KVA1(bd->addr), true); +#if TU_PIC_INT_SIZE == 4 U1CONCLR = _U1CON_PKTDIS_TOKBUSY_MASK; +#else + U1CONbits.PKTDIS = 0; +#endif return; } @@ -341,8 +387,8 @@ static void process_tokdne(uint8_t rhport) } const unsigned length = ep->length; dcd_event_xfer_complete(rhport, - tu_edpt_addr(epnum, dir), - length - remaining, XFER_RESULT_SUCCESS, true); + tu_edpt_addr(epnum, dir), + length - remaining, XFER_RESULT_SUCCESS, true); if (0 == epnum && 0 == length) { /* After completion a ZLP of control transfer, * it prepares for the next steup transfer. */ @@ -358,11 +404,16 @@ static void process_tokdne(uint8_t rhport) static void process_bus_reset(uint8_t rhport) { +#if TU_PIC_INT_SIZE == 4 U1PWRCCLR = _U1PWRC_USUSPEND_MASK; U1CONSET = _U1CON_PPBRST_MASK; +#else + U1PWRCbits.USUSPND = 0; + U1CONbits.PPBRST = 1; +#endif U1ADDR = 0; - U1IE = _U1IE_URSTIE_DETACHIE_MASK | _U1IE_TRNIE_MASK | _U1IE_IDLEIE_MASK | + U1IE = _U1IE_URSTIE_MASK | _U1IE_TRNIE_MASK | _U1IE_IDLEIE_MASK | _U1IE_UERRIE_MASK | _U1IE_STALLIE_MASK; U1EP0 = _U1EP0_EPHSHK_MASK | _U1EP0_EPRXEN_MASK | _U1EP0_EPTXEN_MASK; @@ -386,7 +437,11 @@ static void process_bus_reset(uint8_t rhport) tu_memclr(_dcd.endpoint[1], sizeof(_dcd.endpoint) - sizeof(_dcd.endpoint[0])); _dcd.addr = 0; prepare_next_setup_packet(rhport); +#if TU_PIC_INT_SIZE == 4 U1CONCLR = _U1CON_PPBRST_MASK; +#else + U1CONbits.PPBRST = 0; +#endif dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true); } @@ -399,9 +454,15 @@ static void process_bus_sleep(uint8_t rhport) static void process_bus_resume(uint8_t rhport) { // Enable suspend & disable resume interrupt +#if TU_PIC_INT_SIZE == 4 U1PWRCCLR = _U1PWRC_USUSPEND_MASK; U1IECLR = _U1IE_RESUMEIE_MASK; U1IESET = _U1IE_IDLEIE_MASK; +#else + U1PWRCbits.USUSPND = 0; + U1IEbits.RESUMEIE = 0; + U1IEbits.IDLEIE = 1; +#endif dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); } @@ -418,26 +479,29 @@ void dcd_init(uint8_t rhport) TRISBbits.TRISB6 = 1; #endif -#if (CFG_TUSB_MCU == OPT_MCU_PIC32MX) || (CFG_TUSB_MCU == OPT_MCU_PIC32MM) - U1PWRCSET = _U1PWRC_USBPWR_MASK; -#elif CFG_TUSB_MCU == OPT_MCU_PIC32MK - // TODO -#elif (CFG_TUSB_MCU == OPT_MCU_PIC24) || (CFG_TUSB_MCU == OPT_MCU_DSPIC33) - U1PWRCbits.USBPWR = 1; -#endif - tu_memclr(&_dcd, sizeof(_dcd)); +#if TU_PIC_INT_SIZE == 4 + U1PWRCSET = _U1PWRC_USBPWR_MASK; +#else + U1PWRCbits.USBPWR = 1; +#endif + +#if TU_PIC_INT_SIZE == 4 uint32_t bdt_phys = KVA_TO_PA((uintptr_t)_dcd.bdt); U1BDTP1 = (uint8_t)(bdt_phys >> 8); U1BDTP2 = (uint8_t)(bdt_phys >> 16); U1BDTP3 = (uint8_t)(bdt_phys >> 24); +#else + U1BDTP1 = (uint8_t)((uint16_t)(void *)_dcd.bdt >> 8); - U1IE = _U1IE_URSTIE_DETACHIE_MASK; + U1CNFG1bits.PPB = 2; +#endif + + U1IE = _U1IE_URSTIE_MASK; dcd_connect(rhport); - } void dcd_int_enable(uint8_t rhport) @@ -459,18 +523,30 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) void dcd_remote_wakeup(uint8_t rhport) { +#if TU_PIC_INT_SIZE == 4 U1CONSET = _U1CON_RESUME_MASK; - +#else + U1CONbits.RESUME = 1; +#endif unsigned cnt = 25000000 / 1000; while (cnt--) asm volatile("nop"); +#if TU_PIC_INT_SIZE == 4 U1CONCLR = _U1CON_RESUME_MASK; +#else + U1CONbits.RESUME = 0; +#endif } void dcd_connect(uint8_t rhport) { - while (!U1CONbits.USBEN) + while (!U1CONbits.USBEN) { +#if TU_PIC_INT_SIZE == 4 U1CONSET = _U1CON_USBEN_SOFEN_MASK; +#else + U1CONbits.USBEN = 1; +#endif + } } void dcd_disconnect(uint8_t rhport) @@ -502,14 +578,14 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) ep->max_packet_size = tu_edpt_packet_size(ep_desc); + unsigned val = _U1EP0_EPCONDIS_MASK; val |= (xfer != TUSB_XFER_ISOCHRONOUS) ? _U1EP0_EPHSHK_MASK : 0; val |= dir ? _U1EP0_EPTXEN_MASK : _U1EP0_EPRXEN_MASK; - volatile void *ep_reg_base = &U1EP0; - volatile uint32_t *reg_ep = (ep_reg_base + 0x10 * epn); - - *reg_ep |= val; + ep_reg_t tmp = ep_read(rhport, epn); + tmp |= val; + ep_write(rhport, epn, tmp); if (xfer != TUSB_XFER_ISOCHRONOUS) { bd[odd].dts = 1; @@ -569,6 +645,7 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) { + const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir = tu_edpt_dir(ep_addr); endpoint_state_t *ep = &_dcd.endpoint[epn][dir]; @@ -593,7 +670,6 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to } bd->bc = total_bytes >= mps ? mps: total_bytes; bd->addr = (uint8_t *)KVA_TO_PA(buffer); -// __DSB(); bd->own = 1; /* This bit must be set last */ if (ie) intr_enable(rhport); @@ -673,7 +749,7 @@ void dcd_int_handler(uint8_t rhport) U1IR = is; /* discard any pending events */ } - if (is & _U1IR_URSTIF_DETACHIF_MASK) { + if (is & _U1IR_URSTIF_MASK) { U1IR = is; /* discard any pending events */ process_bus_reset(rhport); } @@ -705,7 +781,6 @@ void dcd_int_handler(uint8_t rhport) } intr_clear(rhport); - } #endif From 3499aa2b2113f0098afff9eb2efd6dda78426a1b Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Thu, 6 Oct 2022 21:10:27 +0900 Subject: [PATCH 474/504] Fix pointer --- examples/device/video_capture/src/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/device/video_capture/src/main.c b/examples/device/video_capture/src/main.c index 362b168d4..60c58b853 100644 --- a/examples/device/video_capture/src/main.c +++ b/examples/device/video_capture/src/main.c @@ -110,7 +110,7 @@ static unsigned tx_busy = 0; static unsigned interval_ms = 1000 / FRAME_RATE; /* YUY2 frame buffer */ -#if 1 +#ifdef CFG_EXAMPLE_VIDEO_READONLY #include "images.h" static struct { uint32_t size; @@ -181,7 +181,7 @@ void video_task(void) already_sent = 1; start_ms = board_millis(); #ifdef CFG_EXAMPLE_VIDEO_READONLY - tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)&frames[frame_num % 8].buffer, frames[frame_num % 8].size); + tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)frames[frame_num % 8].buffer, frames[frame_num % 8].size); #else fill_color_bar(frame_buffer, frame_num); tud_video_n_frame_xfer(0, 0, (void*)frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16/8); @@ -194,7 +194,7 @@ void video_task(void) start_ms += interval_ms; #ifdef CFG_EXAMPLE_VIDEO_READONLY - tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)&frames[frame_num % 8].buffer, frames[frame_num % 8].size); + tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)frames[frame_num % 8].buffer, frames[frame_num % 8].size); #else fill_color_bar(frame_buffer, frame_num); tud_video_n_frame_xfer(0, 0, (void*)frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16/8); From 4be7ffd63f972e241325355d239c44e472dc56dc Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Fri, 7 Oct 2022 21:30:03 +0900 Subject: [PATCH 475/504] Fix max payload size to clip at 1023 --- src/class/video/video_device.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 690e64658..a96bee617 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -419,6 +419,8 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm uint_fast32_t interval_ms = interval / 10000; TU_ASSERT(interval_ms); uint_fast32_t payload_size = (frame_size + interval_ms - 1) / interval_ms + 2; + if (CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE < payload_size) + payload_size = CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE; param->dwMaxPayloadTransferSize = payload_size; return true; } @@ -478,10 +480,10 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * break; default: return false; } - param->bFrameIndex = (uint8_t) frmnum; + param->bFrameIndex = (uint8_t)frmnum; /* Set the parameters determined by the frame */ tusb_desc_cs_video_frm_uncompressed_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); - param->dwMaxVideoFrameSize = (uint32_t) (frm->wWidth * frm->wHeight * fmt->bBitsPerPixel / 8); + param->dwMaxVideoFrameSize = (uint32_t)(frm->wWidth * frm->wHeight * fmt->bBitsPerPixel / 8); return true; } @@ -536,11 +538,15 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * param->dwMaxPayloadTransferSize = 0; } else { uint_fast32_t frame_size = param->dwMaxVideoFrameSize; + uint_fast32_t payload_size; if (!interval_ms) { - param->dwMaxPayloadTransferSize = frame_size + 2; + payload_size = frame_size + 2; } else { - param->dwMaxPayloadTransferSize = (frame_size + interval_ms - 1) / interval_ms + 2; + payload_size = (frame_size + interval_ms - 1) / interval_ms + 2; } + if (CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE < payload_size) + payload_size = CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE; + param->dwMaxPayloadTransferSize = payload_size; } return true; } From aed8051f50dfb72187ba3c9a496d6ad2a57da9f8 Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Sat, 8 Oct 2022 21:53:32 +0900 Subject: [PATCH 476/504] Add motion jpeg --- examples/device/video_capture/CMakeLists.txt | 6 ++ examples/device/video_capture/Makefile | 7 +++ examples/device/video_capture/src/images.h | 3 + examples/device/video_capture/src/main.c | 14 +++++ .../video_capture/src/usb_descriptors.c | 10 ++++ .../video_capture/src/usb_descriptors.h | 57 ++++++++++++++++++- 6 files changed, 96 insertions(+), 1 deletion(-) diff --git a/examples/device/video_capture/CMakeLists.txt b/examples/device/video_capture/CMakeLists.txt index cb321f9a8..b92a2b804 100644 --- a/examples/device/video_capture/CMakeLists.txt +++ b/examples/device/video_capture/CMakeLists.txt @@ -12,6 +12,12 @@ family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}) add_executable(${PROJECT}) +if (FORCE_READONLY) +target_compile_definitions(${PROJECT} PRIVATE + CFG_EXAMPLE_VIDEO_READONLY +) +endif() + # Example source target_sources(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c diff --git a/examples/device/video_capture/Makefile b/examples/device/video_capture/Makefile index 69b633fea..b06681538 100644 --- a/examples/device/video_capture/Makefile +++ b/examples/device/video_capture/Makefile @@ -1,6 +1,13 @@ include ../../../tools/top.mk include ../../make.mk +ifeq ($(DISABLE_MJPG),1) +CFLAGS += -DCFG_EXAMPLE_VIDEO_DISABLE_MJPG +endif +ifeq ($(FORCE_READONLY),1) +CFLAGS += -DCFG_EXAMPLE_VIDEO_READONLY +endif + INC += \ src \ $(TOP)/hw \ diff --git a/examples/device/video_capture/src/images.h b/examples/device/video_capture/src/images.h index 33beff662..0398428b3 100644 --- a/examples/device/video_capture/src/images.h +++ b/examples/device/video_capture/src/images.h @@ -1,3 +1,4 @@ +#if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPG) static const unsigned char frame_buffer[128 * (96 + 1) * 2] = { /* 0 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, @@ -1649,6 +1650,7 @@ static const unsigned char frame_buffer[128 * (96 + 1) * 2] = { 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, }; +#else #define color_bar_0_jpg_len 511 #define color_bar_1_jpg_len 512 @@ -1931,3 +1933,4 @@ unsigned char color_bar_7_jpg[] = { 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x47, 0xff, 0xd9 }; +#endif diff --git a/examples/device/video_capture/src/main.c b/examples/device/video_capture/src/main.c index 60c58b853..3ceebe821 100644 --- a/examples/device/video_capture/src/main.c +++ b/examples/device/video_capture/src/main.c @@ -112,6 +112,8 @@ static unsigned interval_ms = 1000 / FRAME_RATE; /* YUY2 frame buffer */ #ifdef CFG_EXAMPLE_VIDEO_READONLY #include "images.h" + +# if !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPG) static struct { uint32_t size; uint8_t const *buffer; @@ -125,6 +127,8 @@ static struct { {color_bar_6_jpg_len, color_bar_6_jpg}, {color_bar_7_jpg_len, color_bar_7_jpg}, }; +# endif + #else static uint8_t frame_buffer[FRAME_WIDTH * FRAME_HEIGHT * 16 / 8]; static void fill_color_bar(uint8_t *buffer, unsigned start_position) @@ -181,7 +185,12 @@ void video_task(void) already_sent = 1; start_ms = board_millis(); #ifdef CFG_EXAMPLE_VIDEO_READONLY +# if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPG) + tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)&frame_buffer[(frame_num % (FRAME_WIDTH / 2)) * 4], + FRAME_WIDTH * FRAME_HEIGHT * 16/8); +# else tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)frames[frame_num % 8].buffer, frames[frame_num % 8].size); +# endif #else fill_color_bar(frame_buffer, frame_num); tud_video_n_frame_xfer(0, 0, (void*)frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16/8); @@ -194,7 +203,12 @@ void video_task(void) start_ms += interval_ms; #ifdef CFG_EXAMPLE_VIDEO_READONLY +# if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPG) + tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)&frame_buffer[(frame_num % (FRAME_WIDTH / 2)) * 4], + FRAME_WIDTH * FRAME_HEIGHT * 16/8); +# else tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)frames[frame_num % 8].buffer, frames[frame_num % 8].size); +# endif #else fill_color_bar(frame_buffer, frame_num); tud_video_n_frame_xfer(0, 0, (void*)frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16/8); diff --git a/examples/device/video_capture/src/usb_descriptors.c b/examples/device/video_capture/src/usb_descriptors.c index 5c97f4fe1..4c63ab924 100644 --- a/examples/device/video_capture/src/usb_descriptors.c +++ b/examples/device/video_capture/src/usb_descriptors.c @@ -75,7 +75,11 @@ uint8_t const * tud_descriptor_device_cb(void) // Configuration Descriptor //--------------------------------------------------------------------+ +#if defined(CFG_EXAMPLE_VIDEO_READONLY) && !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPG) +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_VIDEO_CAPTURE_DESC_MJPG_LEN) +#else #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_VIDEO_CAPTURE_DESC_LEN) +#endif #if TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX) // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number @@ -96,9 +100,15 @@ 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, 0, 500), // IAD for Video Control +#if defined(CFG_EXAMPLE_VIDEO_READONLY) && !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPG) + TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPG(4, EPNUM_VIDEO_IN, + FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, + CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE) +#else TUD_VIDEO_CAPTURE_DESCRIPTOR(4, EPNUM_VIDEO_IN, FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE) +#endif }; // Invoked when received GET CONFIGURATION DESCRIPTOR diff --git a/examples/device/video_capture/src/usb_descriptors.h b/examples/device/video_capture/src/usb_descriptors.h index 10bae4750..631e638c9 100644 --- a/examples/device/video_capture/src/usb_descriptors.h +++ b/examples/device/video_capture/src/usb_descriptors.h @@ -44,6 +44,24 @@ enum { }; #define TUD_VIDEO_CAPTURE_DESC_LEN (\ + TUD_VIDEO_DESC_IAD_LEN\ + /* control */\ + + TUD_VIDEO_DESC_STD_VC_LEN\ + + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\ + + TUD_VIDEO_DESC_CAMERA_TERM_LEN\ + + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\ + /* Interface 1, Alternate 0 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ + + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\ + + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ + /* Interface 1, Alternate 1 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + 7/* Endpoint */\ + ) + +#define TUD_VIDEO_CAPTURE_DESC_MJPG_LEN (\ TUD_VIDEO_DESC_IAD_LEN\ /* control */\ + TUD_VIDEO_DESC_STD_VC_LEN\ @@ -74,6 +92,43 @@ enum { TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfmtdesc, TUD_VIDEO_GUID_I420, 12, _frmidx, _asrx, _asry, _interlace, _cp) #define TUD_VIDEO_CAPTURE_DESCRIPTOR(_stridx, _epin, _width, _height, _fps, _epsize) \ + TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ + /* Video control 0 */ \ + TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ + TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \ + /* wTotalLength - bLength */ \ + TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \ + UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\ + /*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\ + /*wObjectiveFocalLength*/0, /*bmControls*/0), \ + TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ + /* Video stream alt. 0 */ \ + TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 0, _stridx), \ + /* Video stream header for without still image capture */ \ + TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ + /*wTotalLength - bLength */\ + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\ + + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ + /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ + /*bmaControls(1)*/0), \ + /* Video stream format */ \ + TUD_VIDEO_DESC_CS_VS_FMT_YUY2(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ + /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ + /* Video stream frame format */ \ + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT(/*bFrameIndex */1, 0, _width, _height, \ + _width * _height * 16, _width * _height * 16 * _fps, \ + _width * _height * 16, \ + (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ + /* VS alt 1 */\ + TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 1, 1, _stridx), \ + /* EP */ \ + TUD_VIDEO_DESC_EP_ISO(_epin, _epsize, 1) + +#define TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPG(_stridx, _epin, _width, _height, _fps, _epsize) \ TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ /* Video control 0 */ \ TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ @@ -102,7 +157,7 @@ enum { /* Video stream frame format */ \ TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT(/*bFrameIndex */1, 0, _width, _height, \ _width * _height * 16, _width * _height * 16 * _fps, \ - _width * _height * 16, \ + _width * _height * 16 / 8, \ (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ /* VS alt 1 */\ From 8a89365bb2b83f9d84e2308e7809ac7d6f94b4a1 Mon Sep 17 00:00:00 2001 From: LynnL4 Date: Tue, 11 Oct 2022 13:50:07 +0800 Subject: [PATCH 477/504] Add stm32u5xx offical driver. --- .gitmodules | 6 ++++++ hw/mcu/st/cmsis_device_u5 | 1 + hw/mcu/st/stm32u5xx_hal_driver | 1 + 3 files changed, 8 insertions(+) create mode 160000 hw/mcu/st/cmsis_device_u5 create mode 160000 hw/mcu/st/stm32u5xx_hal_driver diff --git a/.gitmodules b/.gitmodules index 044ac24ec..aafb0f520 100644 --- a/.gitmodules +++ b/.gitmodules @@ -149,3 +149,9 @@ [submodule "hw/mcu/raspberry_pi/Pico-PIO-USB"] path = hw/mcu/raspberry_pi/Pico-PIO-USB url = https://github.com/sekigon-gonnoc/Pico-PIO-USB.git +[submodule "/home/ubuntu/tinyusb/hw/mcu/st/cmsis_device_u5"] + path = /home/ubuntu/tinyusb/hw/mcu/st/cmsis_device_u5 + url = https://github.com/STMicroelectronics/cmsis_device_u5 +[submodule "/home/ubuntu/tinyusb/hw/mcu/st/stm32u5xx_hal_driver"] + path = /home/ubuntu/tinyusb/hw/mcu/st/stm32u5xx_hal_driver + url = https://github.com/STMicroelectronics/stm32u5xx_hal_driver diff --git a/hw/mcu/st/cmsis_device_u5 b/hw/mcu/st/cmsis_device_u5 new file mode 160000 index 000000000..bc00f3c9d --- /dev/null +++ b/hw/mcu/st/cmsis_device_u5 @@ -0,0 +1 @@ +Subproject commit bc00f3c9d8a4e25220f84c26d414902cc6bdf566 diff --git a/hw/mcu/st/stm32u5xx_hal_driver b/hw/mcu/st/stm32u5xx_hal_driver new file mode 160000 index 000000000..2e1d4cdb3 --- /dev/null +++ b/hw/mcu/st/stm32u5xx_hal_driver @@ -0,0 +1 @@ +Subproject commit 2e1d4cdb386e33391cb261dfff4fefa92e4aa35a From 16f1554a03a89c51cd033b6a06cb758668f32fda Mon Sep 17 00:00:00 2001 From: tswan-quasi Date: Tue, 11 Oct 2022 09:59:28 -0400 Subject: [PATCH 478/504] lpc55s69 isochronous, dummy address for endpoint buffers to prevent accidental writes --- src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c | 96 ++++++++++++-------- 1 file changed, 59 insertions(+), 37 deletions(-) diff --git a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c index 09ebf3b0d..b0ddebad0 100644 --- a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c +++ b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c @@ -78,8 +78,9 @@ typedef struct { // Max nbytes for each control/bulk/interrupt transfer enum { - NBYTES_CBI_FULLSPEED_MAX = 64, - NBYTES_CBI_HIGHSPEED_MAX = 32767 // can be up to all 15-bit, but only tested with 4096 + NBYTES_CBI_FS_ISO_MAX = 1023, // FS ISO + NBYTES_CBI_FS_MAX = 64, // FS control/bulk/interrupt + NBYTES_CBI_HS_MAX = 32767 // can be up to all 15-bit, but only tested with 4096 }; enum { @@ -174,6 +175,7 @@ typedef struct // For example: LPC55s69 port1 Highspeed must be USB_RAM (0x40100000) // Use CFG_TUSB_MEM_SECTION to place it accordingly. CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(256) static dcd_data_t _dcd; +CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(256) static volatile uint8_t dummy[64]; // TODO temp fix to prevent accidental overwrite due to ep[][].buffer_xx.offset being 0 //--------------------------------------------------------------------+ // Multiple Controllers @@ -225,8 +227,44 @@ static inline uint8_t ep_addr2id(uint8_t ep_addr) //--------------------------------------------------------------------+ // CONTROLLER API //--------------------------------------------------------------------+ + +static void prepare_setup_packet(uint8_t rhport) +{ + if (_dcd_controller[rhport].max_speed == TUSB_SPEED_FULL ) + { + _dcd.ep[0][1].buffer_fs.offset = get_buf_offset(_dcd.setup_packet); + }else + { + _dcd.ep[0][1].buffer_hs.offset = get_buf_offset(_dcd.setup_packet); + } +} + +static void edpt_reset(uint8_t rhport, uint8_t ep_id) +{ + const uint32_t offset = get_buf_offset((void*)dummy); + tu_memclr(&_dcd.ep[ep_id], sizeof(_dcd.ep[ep_id])); + if (_dcd_controller[rhport].max_speed == TUSB_SPEED_FULL ) + { + _dcd.ep[ep_id][0].buffer_fs.offset = _dcd.ep[ep_id][1].buffer_fs.offset = offset; + } + else + { + _dcd.ep[ep_id][0].buffer_hs.offset = _dcd.ep[ep_id][1].buffer_hs.offset = offset; + } +} + +static void edpt_reset_all(uint8_t rhport) +{ + for (uint8_t ep_id = 0; ep_id < 2*_dcd_controller[rhport].ep_pairs; ++ep_id) + { + edpt_reset(rhport, ep_id); + } + prepare_setup_packet(rhport); +} void dcd_init(uint8_t rhport) { + edpt_reset_all(rhport); + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; dcd_reg->EPLISTSTART = (uint32_t) _dcd.ep; @@ -310,18 +348,13 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) { - (void) rhport; - - // TODO not support ISO yet - TU_VERIFY(p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS); - //------------- Prepare Queue Head -------------// uint8_t ep_id = ep_addr2id(p_endpoint_desc->bEndpointAddress); // Check if endpoint is available TU_ASSERT( _dcd.ep[ep_id][0].disable && _dcd.ep[ep_id][1].disable ); - tu_memclr(_dcd.ep[ep_id], 2*sizeof(ep_cmd_sts_t)); + edpt_reset(rhport, ep_id); _dcd.ep[ep_id][0].is_iso = (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS); // Enable EP interrupt @@ -333,19 +366,18 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) void dcd_edpt_close_all (uint8_t rhport) { - (void) rhport; - // TODO implement dcd_edpt_close_all() + for (uint8_t ep_id = 0; ep_id < 2*_dcd_controller[rhport].ep_pairs; ++ep_id) + { + _dcd.ep[ep_id][0].active = _dcd.ep[ep_id][0].active = 0; // TODO proper way is to EPSKIP then wait ep[][].active then write ep[][].disable (see table 778 in LPC55S69 Use Manual) + _dcd.ep[ep_id][0].disable = _dcd.ep[ep_id][1].disable = 1; + } } -static void prepare_setup_packet(uint8_t rhport) +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { - if (_dcd_controller[rhport].max_speed == TUSB_SPEED_FULL ) - { - _dcd.ep[0][1].buffer_fs.offset = get_buf_offset(_dcd.setup_packet);; - }else - { - _dcd.ep[0][1].buffer_hs.offset = get_buf_offset(_dcd.setup_packet);; - } + uint8_t ep_id = ep_addr2id(ep_addr); + _dcd.ep[ep_id][0].active = _dcd.ep[ep_id][0].active = 0; // TODO proper way is to EPSKIP then wait ep[][].active then write ep[][].disable (see table 778 in LPC55S69 Use Manual) + _dcd.ep[ep_id][0].disable = _dcd.ep[ep_id][1].disable = 1; } static void prepare_ep_xfer(uint8_t rhport, uint8_t ep_id, uint16_t buf_offset, uint16_t total_bytes) @@ -354,13 +386,12 @@ static void prepare_ep_xfer(uint8_t rhport, uint8_t ep_id, uint16_t buf_offset, if (_dcd_controller[rhport].max_speed == TUSB_SPEED_FULL ) { - // TODO ISO FullSpeed can have up to 1023 bytes - nbytes = tu_min16(total_bytes, NBYTES_CBI_FULLSPEED_MAX); + nbytes = tu_min16(total_bytes, _dcd.ep[ep_id][0].is_iso ? NBYTES_CBI_FS_ISO_MAX : NBYTES_CBI_FS_MAX); _dcd.ep[ep_id][0].buffer_fs.offset = buf_offset; _dcd.ep[ep_id][0].buffer_fs.nbytes = nbytes; }else { - nbytes = tu_min16(total_bytes, NBYTES_CBI_HIGHSPEED_MAX); + nbytes = tu_min16(total_bytes, NBYTES_CBI_HS_MAX); _dcd.ep[ep_id][0].buffer_hs.offset = buf_offset; _dcd.ep[ep_id][0].buffer_hs.nbytes = nbytes; } @@ -379,7 +410,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to tu_memclr(&_dcd.dma[ep_id], sizeof(xfer_dma_t)); _dcd.dma[ep_id].total_bytes = total_bytes; - prepare_ep_xfer(rhport, ep_id, get_buf_offset(buffer), total_bytes); + prepare_ep_xfer(rhport, ep_id, buffer ? get_buf_offset(buffer) : get_buf_offset((void*)dummy), total_bytes); return true; } @@ -390,6 +421,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to static void bus_reset(uint8_t rhport) { tu_memclr(&_dcd, sizeof(dcd_data_t)); + edpt_reset_all(rhport); // disable all non-control endpoints on bus reset for(uint8_t ep_id = 2; ep_id < 2*MAX_EP_PAIRS; ep_id++) @@ -397,8 +429,6 @@ static void bus_reset(uint8_t rhport) _dcd.ep[ep_id][0].disable = _dcd.ep[ep_id][1].disable = 1; } - prepare_setup_packet(rhport); - dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; dcd_reg->EPINUSE = 0; @@ -506,23 +536,15 @@ void dcd_int_handler(uint8_t rhport) } } - // TODO support suspend & resume if (cmd_stat & CMDSTAT_SUSPEND_CHANGE_MASK) { - if (cmd_stat & CMDSTAT_DEVICE_SUSPEND_MASK) - { // suspend signal, bus idle for more than 3ms - // Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration. - if (cmd_stat & CMDSTAT_DEVICE_ADDR_MASK) - { - dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); - } + // suspend signal, bus idle for more than 3ms + // Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration. + if (cmd_stat & CMDSTAT_DEVICE_ADDR_MASK) + { + dcd_event_bus_signal(rhport, (cmd_stat & CMDSTAT_DEVICE_SUSPEND_MASK) ? DCD_EVENT_SUSPEND : DCD_EVENT_RESUME, true); } } -// else -// { // resume signal -// dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); -// } -// } } // Setup Receive From 2c9b5ddff096b6c734346099b5cd4162db8735c9 Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Wed, 12 Oct 2022 20:07:22 +0900 Subject: [PATCH 479/504] Rename descriptor macros for consistency --- examples/device/video_capture/Makefile | 4 ++-- .../video_capture/src/usb_descriptors.c | 20 +++++++++---------- .../video_capture/src/usb_descriptors.h | 8 ++++---- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/examples/device/video_capture/Makefile b/examples/device/video_capture/Makefile index b06681538..fda66bcc1 100644 --- a/examples/device/video_capture/Makefile +++ b/examples/device/video_capture/Makefile @@ -1,8 +1,8 @@ include ../../../tools/top.mk include ../../make.mk -ifeq ($(DISABLE_MJPG),1) -CFLAGS += -DCFG_EXAMPLE_VIDEO_DISABLE_MJPG +ifeq ($(DISABLE_MJPEG),1) +CFLAGS += -DCFG_EXAMPLE_VIDEO_DISABLE_MJPEG endif ifeq ($(FORCE_READONLY),1) CFLAGS += -DCFG_EXAMPLE_VIDEO_READONLY diff --git a/examples/device/video_capture/src/usb_descriptors.c b/examples/device/video_capture/src/usb_descriptors.c index 4c63ab924..499ee311c 100644 --- a/examples/device/video_capture/src/usb_descriptors.c +++ b/examples/device/video_capture/src/usb_descriptors.c @@ -75,10 +75,10 @@ uint8_t const * tud_descriptor_device_cb(void) // Configuration Descriptor //--------------------------------------------------------------------+ -#if defined(CFG_EXAMPLE_VIDEO_READONLY) && !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPG) -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_VIDEO_CAPTURE_DESC_MJPG_LEN) +#if defined(CFG_EXAMPLE_VIDEO_READONLY) && !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_VIDEO_CAPTURE_DESC_MJPEG_LEN) #else -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_VIDEO_CAPTURE_DESC_LEN) +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_VIDEO_CAPTURE_DESC_UNCOMPR_LEN) #endif #if TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX) @@ -100,14 +100,14 @@ 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, 0, 500), // IAD for Video Control -#if defined(CFG_EXAMPLE_VIDEO_READONLY) && !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPG) - TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPG(4, EPNUM_VIDEO_IN, - FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, - CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE) +#if defined(CFG_EXAMPLE_VIDEO_READONLY) && !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) + TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(4, EPNUM_VIDEO_IN, + FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, + CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE) #else - TUD_VIDEO_CAPTURE_DESCRIPTOR(4, EPNUM_VIDEO_IN, - FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, - CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE) + TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(4, EPNUM_VIDEO_IN, + FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, + CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE) #endif }; diff --git a/examples/device/video_capture/src/usb_descriptors.h b/examples/device/video_capture/src/usb_descriptors.h index 631e638c9..f1ed3c8e9 100644 --- a/examples/device/video_capture/src/usb_descriptors.h +++ b/examples/device/video_capture/src/usb_descriptors.h @@ -43,7 +43,7 @@ enum { ITF_NUM_TOTAL }; -#define TUD_VIDEO_CAPTURE_DESC_LEN (\ +#define TUD_VIDEO_CAPTURE_DESC_UNCOMPR_LEN (\ TUD_VIDEO_DESC_IAD_LEN\ /* control */\ + TUD_VIDEO_DESC_STD_VC_LEN\ @@ -61,7 +61,7 @@ enum { + 7/* Endpoint */\ ) -#define TUD_VIDEO_CAPTURE_DESC_MJPG_LEN (\ +#define TUD_VIDEO_CAPTURE_DESC_MJPEG_LEN (\ TUD_VIDEO_DESC_IAD_LEN\ /* control */\ + TUD_VIDEO_DESC_STD_VC_LEN\ @@ -91,7 +91,7 @@ enum { #define TUD_VIDEO_DESC_CS_VS_FMT_I420(_fmtidx, _numfmtdesc, _frmidx, _asrx, _asry, _interlace, _cp) \ TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfmtdesc, TUD_VIDEO_GUID_I420, 12, _frmidx, _asrx, _asry, _interlace, _cp) -#define TUD_VIDEO_CAPTURE_DESCRIPTOR(_stridx, _epin, _width, _height, _fps, _epsize) \ +#define TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(_stridx, _epin, _width, _height, _fps, _epsize) \ TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ /* Video control 0 */ \ TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ @@ -128,7 +128,7 @@ enum { /* EP */ \ TUD_VIDEO_DESC_EP_ISO(_epin, _epsize, 1) -#define TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPG(_stridx, _epin, _width, _height, _fps, _epsize) \ +#define TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(_stridx, _epin, _width, _height, _fps, _epsize) \ TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ /* Video control 0 */ \ TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ From 53dc9d55b57faa3199711fe82b47195d0369c1d8 Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Wed, 12 Oct 2022 20:41:03 +0900 Subject: [PATCH 480/504] Fix pointer type to calculate streaming parameter --- src/class/video/video_device.c | 63 ++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 21 deletions(-) diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index a96bee617..a6d2724c1 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -74,10 +74,13 @@ typedef union { typedef union { struct TU_ATTR_PACKED { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bDescriptorSubType; - uint8_t bFrameIndex; + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bFrameIndex; + uint8_t bmCapabilities; + uint16_t wWidth; + uint16_t wHeight; }; tusb_desc_cs_video_frm_uncompressed_t uncompressed; tusb_desc_cs_video_frm_mjpeg_t mjpeg; @@ -396,10 +399,10 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm if (!frame_size) { switch (fmt->bDescriptorSubType) { case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED: - frame_size = (uint_fast32_t)frm->uncompressed.wWidth * frm->uncompressed.wHeight * fmt->uncompressed.bBitsPerPixel / 8; + frame_size = (uint_fast32_t)frm->wWidth * frm->wHeight * fmt->uncompressed.bBitsPerPixel / 8; break; case VIDEO_CS_ITF_VS_FORMAT_MJPEG: - frame_size = (uint_fast32_t)frm->mjpeg.wWidth * frm->mjpeg.wHeight * 16 / 8; /* YUV422 */ + frame_size = (uint_fast32_t)frm->wWidth * frm->wHeight * 16 / 8; /* YUV422 */ break; default: break; } @@ -467,7 +470,7 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * tusb_desc_vs_itf_t const *vs = _get_desc_vs(stm); TU_ASSERT(vs); void const *end = _end_of_streaming_descriptor(vs); - tusb_desc_cs_video_fmt_uncompressed_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); + tusb_desc_cs_video_fmt_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); switch (request) { case VIDEO_REQUEST_GET_MAX: frmnum = fmt->bNumFrameDescriptors; @@ -476,14 +479,32 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * frmnum = 1; break; case VIDEO_REQUEST_GET_DEF: - frmnum = fmt->bDefaultFrameIndex; + switch (fmt->bDescriptorSubType) { + case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED: + frmnum = fmt->uncompressed.bDefaultFrameIndex; + break; + case VIDEO_CS_ITF_VS_FORMAT_MJPEG: + frmnum = fmt->mjpeg.bDefaultFrameIndex; + break; + default: return false; + } break; default: return false; } param->bFrameIndex = (uint8_t)frmnum; /* Set the parameters determined by the frame */ - tusb_desc_cs_video_frm_uncompressed_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); - param->dwMaxVideoFrameSize = (uint32_t)(frm->wWidth * frm->wHeight * fmt->bBitsPerPixel / 8); + tusb_desc_cs_video_frm_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); + uint_fast32_t frame_size; + switch (fmt->bDescriptorSubType) { + case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED: + frame_size = (uint_fast32_t)frm->wWidth * frm->wHeight * fmt->uncompressed.bBitsPerPixel / 8; + break; + case VIDEO_CS_ITF_VS_FORMAT_MJPEG: + frame_size = (uint_fast32_t)frm->wWidth * frm->wHeight * 16 / 8; /* YUV422 */ + break; + default: return false; + } + param->dwMaxVideoFrameSize = frame_size; return true; } @@ -491,17 +512,17 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * tusb_desc_vs_itf_t const *vs = _get_desc_vs(stm); TU_ASSERT(vs); void const *end = _end_of_streaming_descriptor(vs); - tusb_desc_cs_video_fmt_uncompressed_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); - tusb_desc_cs_video_frm_uncompressed_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); + tusb_desc_cs_video_fmt_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); + tusb_desc_cs_video_frm_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); uint_fast32_t interval, interval_ms; switch (request) { case VIDEO_REQUEST_GET_MAX: { uint_fast32_t min_interval, max_interval; - uint_fast8_t num_intervals = frm->bFrameIntervalType; - max_interval = num_intervals ? frm->dwFrameInterval[num_intervals - 1]: frm->dwFrameInterval[1]; - min_interval = frm->dwFrameInterval[0]; + uint_fast8_t num_intervals = frm->uncompressed.bFrameIntervalType; + max_interval = num_intervals ? frm->uncompressed.dwFrameInterval[num_intervals - 1]: frm->uncompressed.dwFrameInterval[1]; + min_interval = frm->uncompressed.dwFrameInterval[0]; interval = max_interval; interval_ms = min_interval / 10000; } @@ -509,24 +530,24 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * case VIDEO_REQUEST_GET_MIN: { uint_fast32_t min_interval, max_interval; - uint_fast8_t num_intervals = frm->bFrameIntervalType; - max_interval = num_intervals ? frm->dwFrameInterval[num_intervals - 1]: frm->dwFrameInterval[1]; - min_interval = frm->dwFrameInterval[0]; + uint_fast8_t num_intervals = frm->uncompressed.bFrameIntervalType; + max_interval = num_intervals ? frm->uncompressed.dwFrameInterval[num_intervals - 1]: frm->uncompressed.dwFrameInterval[1]; + min_interval = frm->uncompressed.dwFrameInterval[0]; interval = min_interval; interval_ms = max_interval / 10000; } break; case VIDEO_REQUEST_GET_DEF: - interval = frm->dwDefaultFrameInterval; + interval = frm->uncompressed.dwDefaultFrameInterval; interval_ms = interval / 10000; break; case VIDEO_REQUEST_GET_RES: { - uint_fast8_t num_intervals = frm->bFrameIntervalType; + uint_fast8_t num_intervals = frm->uncompressed.bFrameIntervalType; if (num_intervals) { interval = 0; } else { - interval = frm->dwFrameInterval[2]; + interval = frm->uncompressed.dwFrameInterval[2]; interval_ms = interval / 10000; } } From 930c68278c3825bce91ef324090d25c392844558 Mon Sep 17 00:00:00 2001 From: tswan-quasi Date: Wed, 12 Oct 2022 11:16:35 -0400 Subject: [PATCH 481/504] double cast of pointer to remove error --- src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c index b0ddebad0..7220654e0 100644 --- a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c +++ b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c @@ -241,7 +241,7 @@ static void prepare_setup_packet(uint8_t rhport) static void edpt_reset(uint8_t rhport, uint8_t ep_id) { - const uint32_t offset = get_buf_offset((void*)dummy); + const uint32_t offset = get_buf_offset((void*)(uint32_t)dummy); tu_memclr(&_dcd.ep[ep_id], sizeof(_dcd.ep[ep_id])); if (_dcd_controller[rhport].max_speed == TUSB_SPEED_FULL ) { @@ -410,7 +410,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to tu_memclr(&_dcd.dma[ep_id], sizeof(xfer_dma_t)); _dcd.dma[ep_id].total_bytes = total_bytes; - prepare_ep_xfer(rhport, ep_id, buffer ? get_buf_offset(buffer) : get_buf_offset((void*)dummy), total_bytes); + prepare_ep_xfer(rhport, ep_id, buffer ? get_buf_offset(buffer) : get_buf_offset((void*)(uint32_t)dummy), total_bytes); return true; } From 4238467b2d78fcb11ba63026daa525d1c09e17ac Mon Sep 17 00:00:00 2001 From: LynnL4 Date: Thu, 13 Oct 2022 17:37:28 +0800 Subject: [PATCH 482/504] Add support for STM32U5 mcu --- hw/bsp/board_mcu.h | 3 + .../stm32u575eval/STM32U575AIIXQ_FLASH.ld | 167 ++++++ hw/bsp/stm32u5/boards/stm32u575eval/board.h | 112 ++++ hw/bsp/stm32u5/boards/stm32u575eval/board.mk | 10 + hw/bsp/stm32u5/family.c | 200 +++++++ hw/bsp/stm32u5/family.mk | 45 ++ hw/bsp/stm32u5/stm32u5xx_hal_conf.h | 506 ++++++++++++++++++ src/common/tusb_mcu.h | 5 + src/portable/synopsys/dwc2/dwc2_stm32.h | 6 + src/tusb_option.h | 1 + 10 files changed, 1055 insertions(+) create mode 100644 hw/bsp/stm32u5/boards/stm32u575eval/STM32U575AIIXQ_FLASH.ld create mode 100644 hw/bsp/stm32u5/boards/stm32u575eval/board.h create mode 100644 hw/bsp/stm32u5/boards/stm32u575eval/board.mk create mode 100644 hw/bsp/stm32u5/family.c create mode 100644 hw/bsp/stm32u5/family.mk create mode 100644 hw/bsp/stm32u5/stm32u5xx_hal_conf.h diff --git a/hw/bsp/board_mcu.h b/hw/bsp/board_mcu.h index 5c309a21d..18f071a22 100644 --- a/hw/bsp/board_mcu.h +++ b/hw/bsp/board_mcu.h @@ -98,6 +98,9 @@ #elif CFG_TUSB_MCU == OPT_MCU_STM32WB #include "stm32wbxx.h" +#elif CFG_TUSB_MCU == OPT_MCU_STM32U5 + #include "stm32u5xx.h" + #elif CFG_TUSB_MCU == OPT_MCU_CXD56 // no header needed diff --git a/hw/bsp/stm32u5/boards/stm32u575eval/STM32U575AIIXQ_FLASH.ld b/hw/bsp/stm32u5/boards/stm32u575eval/STM32U575AIIXQ_FLASH.ld new file mode 100644 index 000000000..03c022bc2 --- /dev/null +++ b/hw/bsp/stm32u5/boards/stm32u575eval/STM32U575AIIXQ_FLASH.ld @@ -0,0 +1,167 @@ +/* +****************************************************************************** +** +** File : LinkerScript.ld +** +** Author : STM32CubeIDE +** +** Abstract : Linker script for STM32U575xI Device from STM32U5 series +** 2048Kbytes FLASH +** 784Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +** Copyright (c) 2022 STMicroelectronics. +** All rights reserved. +** +** This software is licensed under terms that can be found in the LICENSE file +** in the root directory of this software component. +** If no LICENSE file comes with this software, it is provided AS-IS. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200 ; /* required amount of heap */ +_Min_Stack_Size = 0x400 ; /* required amount of stack */ + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 768K + SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K +} + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + KEEP(*(.isr_vector)) /* Startup code */ + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + } >FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } >FLASH + + .ARM : + { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32u5/boards/stm32u575eval/board.h b/hw/bsp/stm32u5/boards/stm32u575eval/board.h new file mode 100644 index 000000000..5c348b812 --- /dev/null +++ b/hw/bsp/stm32u5/boards/stm32u575eval/board.h @@ -0,0 +1,112 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2022, Hongtai Liu + * 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 BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +// LED GREEN +#define LED_PORT GPIOB +#define LED_PIN GPIO_PIN_7 +#define LED_STATE_ON 1 + +// // LED +#define BUTTON_PORT GPIOC +#define BUTTON_PIN GPIO_PIN_13 +#define BUTTON_STATE_ACTIVE 1 + +// UART Enable for STLink VCOM +#define UART_DEV USART1 +#define UART_CLK_EN __HAL_RCC_USART1_CLK_ENABLE +#define UART_GPIO_PORT GPIOA +#define UART_GPIO_AF GPIO_AF7_USART1 +#define UART_TX_PIN GPIO_PIN_9 +#define UART_RX_PIN GPIO_PIN_10 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ + +static inline void board_clock_init(void) +{ + + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + + /* Enable Power Clock*/ + __HAL_RCC_PWR_CLK_ENABLE(); + + /** Configure the main internal regulator output voltage + */ + HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1); + + /** Initializes the CPU, AHB and APB busses clocks + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48 | RCC_OSCILLATORTYPE_HSI; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; + RCC_OscInitStruct.PLL.PLLMBOOST = RCC_PLLMBOOST_DIV1; + RCC_OscInitStruct.PLL.PLLM = 1; + RCC_OscInitStruct.PLL.PLLN = 10; + RCC_OscInitStruct.PLL.PLLP = 2; + RCC_OscInitStruct.PLL.PLLQ = 2; + RCC_OscInitStruct.PLL.PLLR = 1; + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLLVCIRANGE_1; + RCC_OscInitStruct.PLL.PLLFRACN = 0; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_CLK48; + PeriphClkInit.IclkClockSelection = RCC_CLK48CLKSOURCE_HSI48; + + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit); + + /** Initializes the CPU, AHB and APB busses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_PCLK3; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1; + + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4); +} + + +#ifdef __cplusplus +} +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/stm32u5/boards/stm32u575eval/board.mk b/hw/bsp/stm32u5/boards/stm32u575eval/board.mk new file mode 100644 index 000000000..19cd2a5b0 --- /dev/null +++ b/hw/bsp/stm32u5/boards/stm32u575eval/board.mk @@ -0,0 +1,10 @@ +CFLAGS += \ + -DSTM32U575xx \ + +# All source paths should be relative to the top level. +LD_FILE = $(BOARD_PATH)/STM32U575AIIXQ_FLASH.ld + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32u575xx.s + +# For flash-jlink target +JLINK_DEVICE = stm32u575 diff --git a/hw/bsp/stm32u5/family.c b/hw/bsp/stm32u5/family.c new file mode 100644 index 000000000..9bc94cfa3 --- /dev/null +++ b/hw/bsp/stm32u5/family.c @@ -0,0 +1,200 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2022, Hongtai Liu + * 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 "stm32u5xx_hal.h" +#include "bsp/board.h" +#include "board.h" + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void OTG_FS_IRQHandler(void) +{ + tud_int_handler(0); +} + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ + +UART_HandleTypeDef UartHandle; + +void board_init(void) +{ + + board_clock_init(); + + // Enable All GPIOs clocks + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOE_CLK_ENABLE(); + __HAL_RCC_GPIOF_CLK_ENABLE(); + __HAL_RCC_GPIOG_CLK_ENABLE(); + __HAL_RCC_GPIOH_CLK_ENABLE(); + + UART_CLK_EN(); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(OTG_FS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); +#endif + + GPIO_InitTypeDef GPIO_InitStruct; + + // LED + GPIO_InitStruct.Pin = LED_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct); + + // Button + GPIO_InitStruct.Pin = BUTTON_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); + + // IOSV bit MUST be set to access GPIO port G[2:15] */ + HAL_PWREx_EnableVddIO2(); + + // Uart + GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = UART_GPIO_AF; + HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); + + UartHandle.Instance = UART_DEV; + UartHandle.Init.BaudRate = CFG_BOARD_UART_BAUDRATE; + UartHandle.Init.WordLength = UART_WORDLENGTH_8B; + UartHandle.Init.StopBits = UART_STOPBITS_1; + UartHandle.Init.Parity = UART_PARITY_NONE; + UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; + UartHandle.Init.Mode = UART_MODE_TX_RX; + UartHandle.Init.OverSampling = UART_OVERSAMPLING_16; + UartHandle.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; + UartHandle.Init.ClockPrescaler = UART_PRESCALER_DIV1; + UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; + + HAL_UART_Init(&UartHandle); + + /* Configure USB FS GPIOs */ + /* Configure DM DP Pins */ + GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_USB; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Configure ID pin */ + GPIO_InitStruct.Pin = GPIO_PIN_10; + GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Alternate = GPIO_AF10_USB; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + +#if OTG_FS_VBUS_SENSE + // Configure VBUS Pin + GPIO_InitStruct.Pin = GPIO_PIN_9; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + // Enable VBUS sense (B device) via pin PA9 + USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_VBDEN; +#else + // Disable VBUS sense (B device) via pin PA9 + USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_VBDEN; + + // B-peripheral session valid override enable + USB_OTG_FS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN; + USB_OTG_FS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL; +#endif // vbus sense + + /* Enable USB power on Pwrctrl CR2 register */ + HAL_PWREx_EnableVddUSB(); + + /* USB_OTG_FS clock enable */ + __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); +} + +uint32_t board_button_read(void) +{ + return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); +} + +int board_uart_read(uint8_t *buf, int len) +{ + (void)buf; + (void)len; + return 0; +} + +int board_uart_write(void const *buf, int len) +{ + HAL_UART_Transmit(&UartHandle, (uint8_t *)(uintptr_t)buf, len, 0xffff); + return len; +} + +#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; +} +#endif + +void HardFault_Handler(void) +{ + asm("bkpt"); +} + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void) +{ +} diff --git a/hw/bsp/stm32u5/family.mk b/hw/bsp/stm32u5/family.mk new file mode 100644 index 000000000..1cfb81e43 --- /dev/null +++ b/hw/bsp/stm32u5/family.mk @@ -0,0 +1,45 @@ +ST_FAMILY = u5 +DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/st/cmsis_device_$(ST_FAMILY) hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) +ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +include $(TOP)/$(BOARD_PATH)/board.mk + +CFLAGS += \ + -flto \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m33 \ + -mfloat-abi=hard \ + -mfpu=fpv5-sp-d16 \ + -nostdlib -nostartfiles \ + -DCFG_TUSB_MCU=OPT_MCU_STM32U5 + +# suppress warning caused by vendor mcu driver +CFLAGS += -Wno-error=maybe-uninitialized -Wno-error=cast-align -Wno-error=undef -Wno-error=unused-parameter + +#src/portable/st/synopsys/dcd_synopsys.c +SRC_C += \ + src/portable/synopsys/dwc2/dcd_dwc2.c \ + $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c + +INC += \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + $(TOP)/$(ST_CMSIS)/Include \ + $(TOP)/$(ST_HAL_DRIVER)/Inc \ + $(TOP)/$(BOARD_PATH) + +# For freeRTOS port source +FREERTOS_PORT = ARM_CM33_NTZ/non_secure + +# flash target using on-board stlink +flash: flash-stlink diff --git a/hw/bsp/stm32u5/stm32u5xx_hal_conf.h b/hw/bsp/stm32u5/stm32u5xx_hal_conf.h new file mode 100644 index 000000000..15dffa813 --- /dev/null +++ b/hw/bsp/stm32u5/stm32u5xx_hal_conf.h @@ -0,0 +1,506 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32u5xx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + * Copyright (c) 2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32U5xx_HAL_CONF_H +#define STM32U5xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ + +#define HAL_MODULE_ENABLED + +/*#define HAL_ADC_MODULE_ENABLED */ +/*#define HAL_MDF_MODULE_ENABLED */ +/*#define HAL_COMP_MODULE_ENABLED */ +/*#define HAL_CORDIC_MODULE_ENABLED */ +/*#define HAL_CRC_MODULE_ENABLED */ +/*#define HAL_CRYP_MODULE_ENABLED */ +/*#define HAL_DAC_MODULE_ENABLED */ +/*#define HAL_DMA2D_MODULE_ENABLED */ +/*#define HAL_DSI_MODULE_ENABLED */ +/*#define HAL_FDCAN_MODULE_ENABLED */ +/*#define HAL_FMAC_MODULE_ENABLED */ +/*#define HAL_GFXMMU_MODULE_ENABLED */ +/*#define HAL_GPU2D_MODULE_ENABLED */ +/*#define HAL_GTZC_MODULE_ENABLED */ +/*#define HAL_HASH_MODULE_ENABLED */ +/*#define HAL_HRTIM_MODULE_ENABLED */ +/*#define HAL_IRDA_MODULE_ENABLED */ +/*#define HAL_IWDG_MODULE_ENABLED */ +/*#define HAL_I2C_MODULE_ENABLED */ +/*#define HAL_I2S_MODULE_ENABLED */ +/*#define HAL_LPTIM_MODULE_ENABLED */ +/*#define HAL_LTDC_MODULE_ENABLED */ +/*#define HAL_NAND_MODULE_ENABLED */ +/*#define HAL_NOR_MODULE_ENABLED */ +/*#define HAL_OPAMP_MODULE_ENABLED */ +#define HAL_OSPI_MODULE_ENABLED +/*#define HAL_OTFDEC_MODULE_ENABLED */ +#define HAL_PCD_MODULE_ENABLED +/*#define HAL_PKA_MODULE_ENABLED */ +/*#define HAL_QSPI_MODULE_ENABLED */ +/*#define HAL_RNG_MODULE_ENABLED */ +/*#define HAL_RTC_MODULE_ENABLED */ +/*#define HAL_SAI_MODULE_ENABLED */ +/*#define HAL_CRYP_MODULE_ENABLED */ +/*#define HAL_SD_MODULE_ENABLED */ +/*#define HAL_MMC_MODULE_ENABLED */ +/*#define HAL_SMARTCARD_MODULE_ENABLED */ +/*#define HAL_SMBUS_MODULE_ENABLED */ +/*#define HAL_SPI_MODULE_ENABLED */ +/*#define HAL_SRAM_MODULE_ENABLED */ +/*#define HAL_TIM_MODULE_ENABLED */ +/*#define HAL_TSC_MODULE_ENABLED */ +/*#define HAL_RAMCFG_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/*#define HAL_USART_MODULE_ENABLED */ +/*#define HAL_WWDG_MODULE_ENABLED */ +/*#define HAL_DCMI_MODULE_ENABLED */ +/*#define HAL_PSSI_MODULE_ENABLED */ +#define HAL_ICACHE_MODULE_ENABLED +/*#define HAL_DCACHE_MODULE_ENABLED */ +#define HAL_PCD_MODULE_ENABLED +/*#define HAL_HCD_MODULE_ENABLED */ +/*#define HAL_XSPI_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED + +/* ########################## Oscillator Values adaptation ####################*/ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE 16000000UL /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT 100UL /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal Multiple Speed oscillator (MSI) default value. + * This value is the default MSI range value after Reset. + */ +#if !defined (MSI_VALUE) + #define MSI_VALUE 4000000UL /*!< Value of the Internal oscillator in Hz*/ +#endif /* MSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE 16000000UL /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI48) value for USB FS, SDMMC and RNG. + * This internal oscillator is mainly dedicated to provide a high precision clock to + * the USB peripheral by means of a special Clock Recovery System (CRS) circuitry. + * When the CRS is not used, the HSI48 RC oscillator runs on it default frequency + * which is subject to manufacturing process variations. + */ +#if !defined (HSI48_VALUE) + #define HSI48_VALUE 48000000UL /*!< Value of the Internal High Speed oscillator for USB FS/SDMMC/RNG in Hz. + The real value my vary depending on manufacturing process variations.*/ +#endif /* HSI48_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE 32000UL /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature.*/ +/** + * @brief External Low Speed oscillator (LSE) value. + * This value is used by the UART, RTC HAL module to compute the system frequency + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE 32768UL /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT 5000UL /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for SAI1 peripheral + * This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source + * frequency. + */ +#if !defined (EXTERNAL_SAI1_CLOCK_VALUE) + #define EXTERNAL_SAI1_CLOCK_VALUE 48000UL /*!< Value of the SAI1 External clock source in Hz*/ +#endif /* EXTERNAL_SAI1_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ + +#define VDD_VALUE 3300UL /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY (15UL) /*!< tick interrupt priority (lowest by default) */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U /*!< Enable prefetch */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ + +/* #define USE_FULL_ASSERT 1U */ + +/* ################## Register callback feature configuration ############### */ +/** + * @brief Set below the peripheral configuration to "1U" to add the support + * of HAL callback registration/unregistration feature for the HAL + * driver(s). This allows user application to provide specific callback + * functions thanks to HAL_PPP_RegisterCallback() rather than overwriting + * the default weak callback functions (see each stm32u5xx_hal_ppp.h file + * for possible callback identifiers defined in HAL_PPP_CallbackIDTypeDef + * for each PPP peripheral). + */ +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_COMP_REGISTER_CALLBACKS 0U /* COMP register callback disabled */ +#define USE_HAL_CORDIC_REGISTER_CALLBACKS 0U /* CORDIC register callback disabled */ +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ +#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */ +#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */ +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ +#define USE_HAL_FDCAN_REGISTER_CALLBACKS 0U /* FDCAN register callback disabled */ +#define USE_HAL_FMAC_REGISTER_CALLBACKS 0U /* FMAC register callback disabled */ +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_GFXMMU_REGISTER_CALLBACKS 0U /* GFXMMU register callback disabled */ +#define USE_HAL_GPU2D_REGISTER_CALLBACKS 0U /* GPU2D register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_IWDG_REGISTER_CALLBACKS 0U /* IWDG register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ +#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */ +#define USE_HAL_MDF_REGISTER_CALLBACKS 0U /* MDF register callback disabled */ +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_OPAMP_REGISTER_CALLBACKS 0U /* MDIO register callback disabled */ +#define USE_HAL_OTFDEC_REGISTER_CALLBACKS 0U /* OTFDEC register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_PKA_REGISTER_CALLBACKS 0U /* PKA register callback disabled */ +#define USE_HAL_RAMCFG_REGISTER_CALLBACKS 0U /* RAMCFG register callback disabled */ +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ +#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ +#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_TSC_REGISTER_CALLBACKS 0U /* TSC register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver + * Activated: CRC code is present inside driver + * Deactivated: CRC code cleaned from driver + */ +#define USE_SPI_CRC 0U + +/* ################## SDMMC peripheral configuration ######################### */ + +#define USE_SD_TRANSCEIVER 0U /*!< use uSD Transceiver */ + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32u5xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32u5xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_ICACHE_MODULE_ENABLED + #include "stm32u5xx_hal_icache.h" +#endif /* HAL_ICACHE_MODULE_ENABLED */ + +#ifdef HAL_DCACHE_MODULE_ENABLED + #include "stm32u5xx_hal_dcache.h" +#endif /* HAL_DCACHE_MODULE_ENABLED */ + +#ifdef HAL_GTZC_MODULE_ENABLED + #include "stm32u5xx_hal_gtzc.h" +#endif /* HAL_GTZC_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32u5xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32u5xx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DSI_MODULE_ENABLED +#include "stm32u5xx_hal_dsi.h" +#endif /* HAL_DSI_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32u5xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_PKA_MODULE_ENABLED + #include "stm32u5xx_hal_pka.h" +#endif /* HAL_PKA_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32u5xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED + #include "stm32u5xx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32u5xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32u5xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32u5xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32u5xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32u5xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32u5xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_MMC_MODULE_ENABLED + #include "stm32u5xx_hal_mmc.h" +#endif /* HAL_MMC_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32u5xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32u5xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32u5xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32u5xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED +#include "stm32u5xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED +#include "stm32u5xx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_OPAMP_MODULE_ENABLED +#include "stm32u5xx_hal_opamp.h" +#endif /* HAL_OPAMP_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32u5xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_OSPI_MODULE_ENABLED + #include "stm32u5xx_hal_ospi.h" +#endif /* HAL_OSPI_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32u5xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32u5xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32u5xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32u5xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32u5xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32u5xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32u5xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_TSC_MODULE_ENABLED + #include "stm32u5xx_hal_tsc.h" +#endif /* HAL_TSC_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32u5xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32u5xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32u5xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32u5xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32u5xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32u5xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32u5xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_CORDIC_MODULE_ENABLED + #include "stm32u5xx_hal_cordic.h" +#endif /* HAL_CORDIC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32u5xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32u5xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_FDCAN_MODULE_ENABLED + #include "stm32u5xx_hal_fdcan.h" +#endif /* HAL_FDCAN_MODULE_ENABLED */ + +#ifdef HAL_FMAC_MODULE_ENABLED + #include "stm32u5xx_hal_fmac.h" +#endif /* HAL_FMAC_MODULE_ENABLED */ + +#ifdef HAL_GFXMMU_MODULE_ENABLED + #include "stm32u5xx_hal_gfxmmu.h" +#endif /* HAL_GFXMMU_MODULE_ENABLED */ + +#ifdef HAL_GPU2D_MODULE_ENABLED + #include "stm32u5xx_hal_gpu2d.h" +#endif /* HAL_GPU2D_MODULE_ENABLED */ + +#ifdef HAL_OTFDEC_MODULE_ENABLED + #include "stm32u5xx_hal_otfdec.h" +#endif /* HAL_OTFDEC_MODULE_ENABLED */ + +#ifdef HAL_PSSI_MODULE_ENABLED + #include "stm32u5xx_hal_pssi.h" +#endif /* HAL_PSSI_MODULE_ENABLED */ + +#ifdef HAL_RAMCFG_MODULE_ENABLED + #include "stm32u5xx_hal_ramcfg.h" +#endif /* HAL_RAMCFG_MODULE_ENABLED */ + +#ifdef HAL_MDF_MODULE_ENABLED + #include "stm32u5xx_hal_mdf.h" +#endif /* HAL_MDF_MODULE_ENABLED */ + +#ifdef HAL_XSPI_MODULE_ENABLED + #include "stm32u5xx_hal_xspi.h" +#endif /* HAL_XSPI_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t *file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32U5xx_HAL_CONF_H */ + diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 514ffcd4d..86c68baf8 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -189,6 +189,11 @@ #elif TU_CHECK_MCU(OPT_MCU_STM32WB) #define TUP_DCD_ENDPOINT_MAX 8 +#elif TU_CHECK_MCU(OPT_MCU_STM32U5) + #define TUP_USBIP_DWC2 + #define TUP_USBIP_DWC2_STM32 + #define TUP_DCD_ENDPOINT_MAX 6 + //------------- Sony -------------// #elif TU_CHECK_MCU(OPT_MCU_CXD56) #define TUP_DCD_ENDPOINT_MAX 7 diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index 337f611d8..ea786362e 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -82,6 +82,12 @@ #define EP_MAX_FS 6 #define EP_FIFO_SIZE_FS 1280 +#elif CFG_TUSB_MCU == OPT_MCU_STM32U5 + #include "stm32u5xx.h" + #define USB_OTG_FS_PERIPH_BASE USB_OTG_FS_BASE + #define EP_MAX_FS 6 + #define EP_FIFO_SIZE_FS 1280 + #else #error "Unsupported MCUs" #endif diff --git a/src/tusb_option.h b/src/tusb_option.h index 4c2dd0258..f95ae6273 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -84,6 +84,7 @@ typedef int make_iso_compilers_happy; #define OPT_MCU_STM32G0 310 ///< ST G0 #define OPT_MCU_STM32G4 311 ///< ST G4 #define OPT_MCU_STM32WB 312 ///< ST WB +#define OPT_MCU_STM32U5 313 ///< ST U5 // Sony #define OPT_MCU_CXD56 400 ///< SONY CXD56 From 2c1ff2673baaeefc6520d25e87d5ca5e6b2093db Mon Sep 17 00:00:00 2001 From: tswan-quasi Date: Thu, 13 Oct 2022 11:48:30 -0400 Subject: [PATCH 483/504] (void) rhport for unused parameter --- src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c index 7220654e0..1f29abbb8 100644 --- a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c +++ b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c @@ -375,6 +375,8 @@ void dcd_edpt_close_all (uint8_t rhport) void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { + (void) rhport; + uint8_t ep_id = ep_addr2id(ep_addr); _dcd.ep[ep_id][0].active = _dcd.ep[ep_id][0].active = 0; // TODO proper way is to EPSKIP then wait ep[][].active then write ep[][].disable (see table 778 in LPC55S69 Use Manual) _dcd.ep[ep_id][0].disable = _dcd.ep[ep_id][1].disable = 1; @@ -403,8 +405,6 @@ static void prepare_ep_xfer(uint8_t rhport, uint8_t ep_id, uint16_t buf_offset, bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) { - (void) rhport; - uint8_t const ep_id = ep_addr2id(ep_addr); tu_memclr(&_dcd.dma[ep_id], sizeof(xfer_dma_t)); From 3f45f3767240dccfccbf9b013a9109912bfa2b5c Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 17 Oct 2022 23:13:24 +0700 Subject: [PATCH 484/504] minor rename --- src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c index 1f29abbb8..51baaf224 100644 --- a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c +++ b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c @@ -78,7 +78,8 @@ typedef struct { // Max nbytes for each control/bulk/interrupt transfer enum { - NBYTES_CBI_FS_ISO_MAX = 1023, // FS ISO + NBYTES_ISO_FS_MAX = 1023, // FS ISO + NBYTES_ISO_HS_MAX = 1024, // HS ISO NBYTES_CBI_FS_MAX = 64, // FS control/bulk/interrupt NBYTES_CBI_HS_MAX = 32767 // can be up to all 15-bit, but only tested with 4096 }; @@ -113,6 +114,8 @@ enum { typedef union TU_ATTR_PACKED { // Full and High speed has different bit layout for buffer_offset and nbytes + // TODO FS/HS layout depends on the max speed of controller e.g + // lpc55s69 PORT0 is only FS but actually has the same layout as HS on port1 // Buffer (aligned 64) = DATABUFSTART [31:22] | buffer_offset [21:6] volatile struct { @@ -388,7 +391,7 @@ static void prepare_ep_xfer(uint8_t rhport, uint8_t ep_id, uint16_t buf_offset, if (_dcd_controller[rhport].max_speed == TUSB_SPEED_FULL ) { - nbytes = tu_min16(total_bytes, _dcd.ep[ep_id][0].is_iso ? NBYTES_CBI_FS_ISO_MAX : NBYTES_CBI_FS_MAX); + nbytes = tu_min16(total_bytes, _dcd.ep[ep_id][0].is_iso ? NBYTES_ISO_FS_MAX : NBYTES_CBI_FS_MAX); _dcd.ep[ep_id][0].buffer_fs.offset = buf_offset; _dcd.ep[ep_id][0].buffer_fs.nbytes = nbytes; }else From a49ca795afc9008085d905e6fb43f511dca7be7c Mon Sep 17 00:00:00 2001 From: Tomas Rezucha Date: Tue, 18 Oct 2022 08:05:13 +0200 Subject: [PATCH 485/504] esp: Fix Isochronous transfers On ESP32-S2/S3 ISO transfers must be configured for even or odd frame. Closes https://github.com/hathach/tinyusb/issues/1382 --- src/portable/espressif/esp32sx/dcd_esp32sx.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/portable/espressif/esp32sx/dcd_esp32sx.c b/src/portable/espressif/esp32sx/dcd_esp32sx.c index a30fca0d8..0b75af627 100644 --- a/src/portable/espressif/esp32sx/dcd_esp32sx.c +++ b/src/portable/espressif/esp32sx/dcd_esp32sx.c @@ -59,6 +59,7 @@ typedef struct { uint16_t queued_len; uint16_t max_size; bool short_packet; + uint8_t interval; } xfer_ctl_t; static const char *TAG = "TUSB:DCD"; @@ -267,6 +268,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_edpt) xfer_ctl_t *xfer = XFER_CTL_BASE(epnum, dir); xfer->max_size = tu_edpt_packet_size(desc_edpt); + xfer->interval = desc_edpt->bInterval; if (dir == TUSB_DIR_OUT) { out_ep[epnum].doepctl |= USB_USBACTEP1_M | @@ -379,6 +381,13 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to USB0.in_ep_reg[epnum].dieptsiz = (num_packets << USB_D_PKTCNT0_S) | total_bytes; USB0.in_ep_reg[epnum].diepctl |= USB_D_EPENA1_M | USB_D_CNAK1_M; // Enable | CNAK + // For ISO endpoint with interval=1 set correct DATA0/DATA1 bit for next frame + if ((USB0.in_ep_reg[epnum].diepctl & USB_D_EPTYPE0_M) == (1 << USB_D_EPTYPE1_S) && xfer->interval == 1) { + // Take odd/even bit from frame counter. + uint32_t const odd_frame_now = (USB0.dsts & (1u << USB_SOFFN_S)); + USB0.in_ep_reg[epnum].diepctl |= (odd_frame_now ? USB_DI_SETD0PID1 : USB_DI_SETD1PID1); + } + // Enable fifo empty interrupt only if there are something to put in the fifo. if(total_bytes != 0) { USB0.dtknqr4_fifoemptymsk |= (1 << epnum); @@ -387,6 +396,13 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to // Each complete packet for OUT xfers triggers XFRC. USB0.out_ep_reg[epnum].doeptsiz |= USB_PKTCNT0_M | ((xfer->max_size & USB_XFERSIZE0_V) << USB_XFERSIZE0_S); USB0.out_ep_reg[epnum].doepctl |= USB_EPENA0_M | USB_CNAK0_M; + + // For ISO endpoint with interval=1 set correct DATA0/DATA1 bit for next frame + if ((USB0.out_ep_reg[epnum].doepctl & USB_D_EPTYPE0_M) == (1 << USB_D_EPTYPE1_S) && xfer->interval == 1) { + // Take odd/even bit from frame counter. + uint32_t const odd_frame_now = (USB0.dsts & (1u << USB_SOFFN_S)); + USB0.out_ep_reg[epnum].doepctl |= (odd_frame_now ? USB_DO_SETD0PID1 : USB_DO_SETD1PID1); + } } return true; } From 8f88ff559eb930b26233d19ae9df75f3a5c6a786 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 18 Oct 2022 15:14:45 +0200 Subject: [PATCH 486/504] Fix typo in getting_started guide Fixes: 1234111 ("add get-deps target") --- docs/reference/getting_started.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/getting_started.rst b/docs/reference/getting_started.rst index 3cdb46849..e328757ba 100644 --- a/docs/reference/getting_started.rst +++ b/docs/reference/getting_started.rst @@ -61,7 +61,7 @@ To build example, first change directory to an example folder. $ cd examples/device/cdc_msc -Before building, we need to download MCU driver submodule to provide low-level MCU peripheral's driver first. Run the ``get-dpes`` target in one of the example folder as follow. You only need to do this once per mcu +Before building, we need to download MCU driver submodule to provide low-level MCU peripheral's driver first. Run the ``get-deps`` target in one of the example folder as follow. You only need to do this once per mcu .. code-block:: From 19208cd88dc57e6a385dbd4ce04cd9ad394c96c0 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Thu, 20 Oct 2022 11:04:49 +0200 Subject: [PATCH 487/504] stm32u5: Fix submodules paths Local paths were commited to submodule definitions This just removes prefix for submodules path and name --- .gitmodules | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitmodules b/.gitmodules index aafb0f520..dcac0d9ab 100644 --- a/.gitmodules +++ b/.gitmodules @@ -149,9 +149,9 @@ [submodule "hw/mcu/raspberry_pi/Pico-PIO-USB"] path = hw/mcu/raspberry_pi/Pico-PIO-USB url = https://github.com/sekigon-gonnoc/Pico-PIO-USB.git -[submodule "/home/ubuntu/tinyusb/hw/mcu/st/cmsis_device_u5"] - path = /home/ubuntu/tinyusb/hw/mcu/st/cmsis_device_u5 +[submodule "hw/mcu/st/cmsis_device_u5"] + path = hw/mcu/st/cmsis_device_u5 url = https://github.com/STMicroelectronics/cmsis_device_u5 -[submodule "/home/ubuntu/tinyusb/hw/mcu/st/stm32u5xx_hal_driver"] - path = /home/ubuntu/tinyusb/hw/mcu/st/stm32u5xx_hal_driver +[submodule "hw/mcu/st/stm32u5xx_hal_driver"] + path = hw/mcu/st/stm32u5xx_hal_driver url = https://github.com/STMicroelectronics/stm32u5xx_hal_driver From fe4278554b04c3446b30f28fdb6aaad908f8fa48 Mon Sep 17 00:00:00 2001 From: tswan-quasi Date: Thu, 20 Oct 2022 11:02:57 -0400 Subject: [PATCH 488/504] dummy buffer only on EP0 OUT ZLPs --- src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c | 21 ++++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c index 51baaf224..ed6c14f17 100644 --- a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c +++ b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c @@ -178,7 +178,7 @@ typedef struct // For example: LPC55s69 port1 Highspeed must be USB_RAM (0x40100000) // Use CFG_TUSB_MEM_SECTION to place it accordingly. CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(256) static dcd_data_t _dcd; -CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(256) static volatile uint8_t dummy[64]; // TODO temp fix to prevent accidental overwrite due to ep[][].buffer_xx.offset being 0 +CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(256) static volatile uint8_t dummy[8] = { 0 }; // a fix for EP0 OUT ZLPs overwriting the buffer //--------------------------------------------------------------------+ // Multiple Controllers @@ -244,16 +244,7 @@ static void prepare_setup_packet(uint8_t rhport) static void edpt_reset(uint8_t rhport, uint8_t ep_id) { - const uint32_t offset = get_buf_offset((void*)(uint32_t)dummy); tu_memclr(&_dcd.ep[ep_id], sizeof(_dcd.ep[ep_id])); - if (_dcd_controller[rhport].max_speed == TUSB_SPEED_FULL ) - { - _dcd.ep[ep_id][0].buffer_fs.offset = _dcd.ep[ep_id][1].buffer_fs.offset = offset; - } - else - { - _dcd.ep[ep_id][0].buffer_hs.offset = _dcd.ep[ep_id][1].buffer_hs.offset = offset; - } } static void edpt_reset_all(uint8_t rhport) @@ -413,7 +404,11 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to tu_memclr(&_dcd.dma[ep_id], sizeof(xfer_dma_t)); _dcd.dma[ep_id].total_bytes = total_bytes; - prepare_ep_xfer(rhport, ep_id, buffer ? get_buf_offset(buffer) : get_buf_offset((void*)(uint32_t)dummy), total_bytes); + if (!buffer && !ep_id) // for EP0 OUT ZLPs to prevent overwrites to buffer + { + buffer = (uint8_t*)(uint32_t)dummy; + } + prepare_ep_xfer(rhport, ep_id, get_buf_offset(buffer), total_bytes); return true; } @@ -426,8 +421,8 @@ static void bus_reset(uint8_t rhport) tu_memclr(&_dcd, sizeof(dcd_data_t)); edpt_reset_all(rhport); - // disable all non-control endpoints on bus reset - for(uint8_t ep_id = 2; ep_id < 2*MAX_EP_PAIRS; ep_id++) + // disable all endpoints as epecified by LPC55S69 UM Table 778 + for(uint8_t ep_id = 0; ep_id < 2*MAX_EP_PAIRS; ep_id++) { _dcd.ep[ep_id][0].disable = _dcd.ep[ep_id][1].disable = 1; } From 0b5504708172aa269653924da95e358720aabf7d Mon Sep 17 00:00:00 2001 From: tswan-quasi Date: Thu, 20 Oct 2022 11:04:49 -0400 Subject: [PATCH 489/504] typo fix --- src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c index ed6c14f17..80d85fa46 100644 --- a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c +++ b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c @@ -421,7 +421,7 @@ static void bus_reset(uint8_t rhport) tu_memclr(&_dcd, sizeof(dcd_data_t)); edpt_reset_all(rhport); - // disable all endpoints as epecified by LPC55S69 UM Table 778 + // disable all endpoints as specified by LPC55S69 UM Table 778 for(uint8_t ep_id = 0; ep_id < 2*MAX_EP_PAIRS; ep_id++) { _dcd.ep[ep_id][0].disable = _dcd.ep[ep_id][1].disable = 1; From 4ec1643bdbca34d0e6d575646ed556087bac5d6e Mon Sep 17 00:00:00 2001 From: Mark K Cowan Date: Thu, 20 Oct 2022 22:45:58 +0300 Subject: [PATCH 490/504] do not apply storage attributes to member of struct --- src/class/audio/audio_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index a021755ba..0eccf282d 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -341,7 +341,7 @@ typedef struct // Audio control interrupt buffer - no FIFO - 6 Bytes according to UAC 2 specification (p. 74) #if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN - CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ep_int_ctr_buf[CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE]; + uint8_t ep_int_ctr_buf[CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE]; #endif // Decoding parameters - parameters are set when alternate AS interface is set by host From 35e1a27c950c4b25106c074d0b66220d099e54a7 Mon Sep 17 00:00:00 2001 From: tswan-quasi Date: Fri, 21 Oct 2022 15:06:30 -0400 Subject: [PATCH 491/504] unused (void) cast --- src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c index 80d85fa46..7825d287f 100644 --- a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c +++ b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c @@ -244,6 +244,7 @@ static void prepare_setup_packet(uint8_t rhport) static void edpt_reset(uint8_t rhport, uint8_t ep_id) { + (void) rhport; tu_memclr(&_dcd.ep[ep_id], sizeof(_dcd.ep[ep_id])); } From e3b7ed9ae966be1cb41165343ef30c6523ed5771 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 24 Oct 2022 18:43:21 +0700 Subject: [PATCH 492/504] use dummy for all ZLP for ip3511, fix lpc55 build with DEBUG=1 --- hw/bsp/lpc55/family.mk | 1 + src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/hw/bsp/lpc55/family.mk b/hw/bsp/lpc55/family.mk index 1af1d076e..9d6702b94 100644 --- a/hw/bsp/lpc55/family.mk +++ b/hw/bsp/lpc55/family.mk @@ -43,6 +43,7 @@ SRC_C += \ $(MCU_DIR)/drivers/fsl_power.c \ $(MCU_DIR)/drivers/fsl_reset.c \ $(SDK_DIR)/drivers/lpc_gpio/fsl_gpio.c \ + $(SDK_DIR)/drivers/common/fsl_common_arm.c \ $(SDK_DIR)/drivers/flexcomm/fsl_flexcomm.c \ $(SDK_DIR)/drivers/flexcomm/fsl_usart.c \ lib/sct_neopixel/sct_neopixel.c diff --git a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c index 7825d287f..9b490c48c 100644 --- a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c +++ b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c @@ -178,7 +178,9 @@ typedef struct // For example: LPC55s69 port1 Highspeed must be USB_RAM (0x40100000) // Use CFG_TUSB_MEM_SECTION to place it accordingly. CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(256) static dcd_data_t _dcd; -CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(256) static volatile uint8_t dummy[8] = { 0 }; // a fix for EP0 OUT ZLPs overwriting the buffer + +// Dummy buffer to fix ZLPs overwriting the buffer (probably an USB/DMA controller bug) +CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(64) static uint8_t dummy[8]; //--------------------------------------------------------------------+ // Multiple Controllers @@ -405,10 +407,14 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to tu_memclr(&_dcd.dma[ep_id], sizeof(xfer_dma_t)); _dcd.dma[ep_id].total_bytes = total_bytes; - if (!buffer && !ep_id) // for EP0 OUT ZLPs to prevent overwrites to buffer + if (!buffer) { + // Although having no data, ZLPs can cause buffer overwritten to zeroes. + // Probably due to USB/DMA controller side effect/bug. + // Assigned buffer offset to (valid) dummy to prevent overwriting to DATABUFSTART buffer = (uint8_t*)(uint32_t)dummy; } + prepare_ep_xfer(rhport, ep_id, get_buf_offset(buffer), total_bytes); return true; From 815c2cc9959cc9a127d4ff64f65743d4ac8713ce Mon Sep 17 00:00:00 2001 From: Mark K Cowan Date: Mon, 24 Oct 2022 20:36:45 +0300 Subject: [PATCH 493/504] keep alignment spec --- src/class/audio/audio_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 0eccf282d..2b22834b6 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -341,7 +341,7 @@ typedef struct // Audio control interrupt buffer - no FIFO - 6 Bytes according to UAC 2 specification (p. 74) #if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN - uint8_t ep_int_ctr_buf[CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE]; + CFG_TUSB_MEM_ALIGN uint8_t ep_int_ctr_buf[CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE]; #endif // Decoding parameters - parameters are set when alternate AS interface is set by host From 38cdeb9e606b23071cd0bd9c505c09bc8df26bc4 Mon Sep 17 00:00:00 2001 From: Henrik Fegran Date: Thu, 3 Nov 2022 20:23:27 +0100 Subject: [PATCH 494/504] Fixed wrong FreeRTOS port for EFM32GG12 --- hw/bsp/sltb009a/board.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/bsp/sltb009a/board.mk b/hw/bsp/sltb009a/board.mk index f5c240ca2..ddafa8a2b 100644 --- a/hw/bsp/sltb009a/board.mk +++ b/hw/bsp/sltb009a/board.mk @@ -35,7 +35,7 @@ INC += \ $(TOP)/hw/bsp/$(BOARD) # For freeRTOS port source -FREERTOS_PORT = ARM_CM3 +FREERTOS_PORT = ARM_CM4F # For flash-jlink target JLINK_DEVICE = EFM32GG12B810F1024 From d2c9b8bcfba42ebc0023154493383b8bcb892020 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Nov 2022 16:14:35 +0700 Subject: [PATCH 495/504] fix -wconversion-int and add minor comment --- src/common/tusb_types.h | 8 ++++++-- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 18 ++++++++++-------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index cfa24bd82..e11f08dd1 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -513,15 +513,19 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_edpt_packet_size(tusb_desc_endpo return tu_le16toh(desc_ep->wMaxPacketSize) & TU_GENMASK(10, 0); } -static inline const char *tu_edpt_dir_str(tusb_dir_t dir) { +#if CFG_TUSB_DEBUG +TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_dir_str(tusb_dir_t dir) +{ static const char *str[] = {"out", "in"}; return str[dir]; } -static inline const char *tu_edpt_type_str(tusb_xfer_type_t t) { +TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_type_str(tusb_xfer_type_t t) +{ static const char *str[] = {"control", "isochronous", "bulk", "interrupt"}; return str[t]; } +#endif //--------------------------------------------------------------------+ // Descriptor helper diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 1125d30b6..10237d1f9 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -138,10 +138,10 @@ static void __tusb_irq_path_func(hw_handle_buff_status)(void) _handle_buff_status_bit(bit, ep); } - // Check interrupt endpoints + // Check "interrupt" (asynchronous) endpoints for both IN and OUT for (uint i = 1; i <= USB_HOST_INTERRUPT_ENDPOINTS && remaining_buffers; i++) { - // EPX is bit 0 + // EPX is bit 0 & 1 // IEP1 IN is bit 2 // IEP1 OUT is bit 3 // IEP2 IN is bit 4 @@ -149,7 +149,8 @@ static void __tusb_irq_path_func(hw_handle_buff_status)(void) // IEP3 IN is bit 6 // IEP3 OUT is bit 7 // etc - for(int j = 0; j < 2; j++){ + for(uint j = 0; j < 2; j++) + { bit = 1 << (i*2+j); if (remaining_buffers & bit) { @@ -279,6 +280,8 @@ static struct hw_endpoint *_hw_endpoint_allocate(uint8_t transfer_type) if (transfer_type != TUSB_XFER_CONTROL) { + // 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(); pico_info("Allocate %s ep %d\n", tu_edpt_type_str(transfer_type), ep->interrupt_num); assert(ep); @@ -344,11 +347,10 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t if (ep != &epx) { // Endpoint has its own addr_endp and interrupt bits to be setup! - // This is an interrupt endpoint - // so need to set up interrupt endpoint address control register with: - // device address - // endpoint number / direction - // preamble + // 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)); if (dir == TUSB_DIR_OUT) From cb0ca6151bda002d8c9c6650ed8d5b225614e0e2 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Nov 2022 17:08:02 +0700 Subject: [PATCH 496/504] remove CFG_TUSB_DEBUG from tinyusb_common_base --- hw/bsp/rp2040/family.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index 31e97d9af..5dba9dc39 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -55,7 +55,7 @@ if (NOT TARGET _rp2040_family_inclusion_marker) target_compile_definitions(tinyusb_common_base INTERFACE CFG_TUSB_MCU=OPT_MCU_RP2040 CFG_TUSB_OS=OPT_OS_PICO - CFG_TUSB_DEBUG=${TINYUSB_DEBUG_LEVEL} + #CFG_TUSB_DEBUG=${TINYUSB_DEBUG_LEVEL} ) #------------------------------------ From 44e19aa3c7ce7436a9722a609ca45530d3e1cb70 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 6 Nov 2022 14:44:18 +0700 Subject: [PATCH 497/504] rename PIO_USB_PIN_DP to PIO_USB_DP_PIN and change from 2 to 20 & moved to board.h add support for PIO_USB_VBUSEN_PIN and its state. --- hw/bsp/rp2040/board.h | 12 ++++++++++++ hw/bsp/rp2040/family.c | 11 +++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/hw/bsp/rp2040/board.h b/hw/bsp/rp2040/board.h index 237f29dc2..56b8fec84 100644 --- a/hw/bsp/rp2040/board.h +++ b/hw/bsp/rp2040/board.h @@ -46,6 +46,18 @@ #define UART_RX_PIN PICO_DEFAULT_UART_RX_PIN #endif +// PIO_USB_DP_PIN_DEFAULT is 0, which conflict with UART, change to other pin +#ifndef PIO_USB_DP_PIN +#define PIO_USB_DP_PIN 20 +#endif + +// VBUS enable pin and its active state +// #define PIO_USB_VBUSEN_PIN 22 + +#ifndef PIO_USB_VBUSEN_STATE +#define PIO_USB_VBUSEN_STATE 1 +#endif + #ifdef __cplusplus } #endif diff --git a/hw/bsp/rp2040/family.c b/hw/bsp/rp2040/family.c index 90e2192c0..ee5a73ff6 100644 --- a/hw/bsp/rp2040/family.c +++ b/hw/bsp/rp2040/family.c @@ -39,9 +39,6 @@ #include "pio_usb.h" #endif -// PIO_USB_DP_PIN_DEFAULT is 0, which conflict with UART, change to 2 -#define PICO_PIO_USB_PIN_DP 2 - #ifdef BUTTON_BOOTSEL // This example blinks the Picoboard LED when the BOOTSEL button is pressed. // @@ -138,10 +135,16 @@ void board_init(void) // Set the system clock to a multiple of 120mhz for bitbanging USB with pico-usb set_sys_clock_khz(120000, true); +#ifdef PIO_USB_VBUSEN_PIN + gpio_init(PIO_USB_VBUSEN_PIN); + gpio_set_dir(PIO_USB_VBUSEN_PIN, GPIO_OUT); + gpio_put(PIO_USB_VBUSEN_PIN, PIO_USB_VBUSEN_STATE); +#endif + // rp2040 use pico-pio-usb for host tuh_configure() can be used to passed pio configuration to the host stack // Note: tuh_configure() must be called before tuh_init() pio_usb_configuration_t pio_cfg = PIO_USB_DEFAULT_CONFIG; - pio_cfg.pin_dp = PICO_PIO_USB_PIN_DP; + pio_cfg.pin_dp = PIO_USB_DP_PIN; tuh_configure(BOARD_TUH_RHPORT, TUH_CFGID_RPI_PIO_USB_CONFIGURATION, &pio_cfg); #endif From a061bc41733047468b624fb33dc0811d1eb984e4 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 6 Nov 2022 14:46:44 +0700 Subject: [PATCH 498/504] bump up pico-pio-usb --- hw/mcu/raspberry_pi/Pico-PIO-USB | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/mcu/raspberry_pi/Pico-PIO-USB b/hw/mcu/raspberry_pi/Pico-PIO-USB index 92bd3b4c3..f78dc9b2c 160000 --- a/hw/mcu/raspberry_pi/Pico-PIO-USB +++ b/hw/mcu/raspberry_pi/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit 92bd3b4c3ad2fce36166e4a357749b6d4fe9013b +Subproject commit f78dc9b2c7fa9b82587e43babdc1d21294a32985 From b92015544490ed6fd8891db59c4cb88365f0f137 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 6 Nov 2022 14:56:05 +0700 Subject: [PATCH 499/504] minor clean up --- .github/workflows/build_arm.yml | 8 ++++---- .github/workflows/build_esp.yml | 7 ++++--- .github/workflows/build_msp430.yml | 7 ++++--- .github/workflows/build_renesas.yml | 7 ++++--- .github/workflows/build_riscv.yml | 7 ++++--- 5 files changed, 20 insertions(+), 16 deletions(-) diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml index a321948e3..56804da8a 100644 --- a/.github/workflows/build_arm.yml +++ b/.github/workflows/build_arm.yml @@ -99,10 +99,10 @@ jobs: - name: Linker Map run: | pip install linkermap/ - # find -quit to only print map of 1 board per example - for ex in `ls -d examples/*/*/`; do \ - find ${ex} -name *.map -print -quit | \ - xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"'; \ + # find -quit to only print linkermap of 1 board per example + for ex in `ls -d examples/*/*/` + do + find ${ex} -name *.map -print -quit | xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"' done # Following steps are for Hardware Test with self-hosted diff --git a/.github/workflows/build_esp.yml b/.github/workflows/build_esp.yml index 6a46773b2..417887172 100644 --- a/.github/workflows/build_esp.yml +++ b/.github/workflows/build_esp.yml @@ -43,7 +43,8 @@ jobs: - name: Linker Map run: | pip install linkermap/ - for ex in `ls -d examples/device/*/`; do \ - find ${ex} -maxdepth 3 -name *.map -print -quit | \ - xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"'; \ + # find -quit to only print linkermap of 1 board per example + for ex in `ls -d examples/device/*/` + do + find ${ex} -maxdepth 3 -name *.map -print -quit | xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"' done diff --git a/.github/workflows/build_msp430.yml b/.github/workflows/build_msp430.yml index ea93f09a0..731febb03 100644 --- a/.github/workflows/build_msp430.yml +++ b/.github/workflows/build_msp430.yml @@ -61,7 +61,8 @@ jobs: - name: Linker Map run: | pip install linkermap/ - for ex in `ls -d examples/device/*/`; do \ - find ${ex} -name *.map -print -quit | \ - xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"'; \ + # find -quit to only print linkermap of 1 board per example + for ex in `ls -d examples/device/*/` + do + find ${ex} -name *.map -print -quit | xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"' done diff --git a/.github/workflows/build_renesas.yml b/.github/workflows/build_renesas.yml index 2563d3549..4de42f935 100644 --- a/.github/workflows/build_renesas.yml +++ b/.github/workflows/build_renesas.yml @@ -62,7 +62,8 @@ jobs: - name: Linker Map run: | pip install linkermap/ - for ex in `ls -d examples/device/*/`; do \ - find ${ex} -name *.map -print -quit | \ - xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"'; \ + # find -quit to only print linkermap of 1 board per example + for ex in `ls -d examples/device/*/` + do + find ${ex} -name *.map -print -quit | xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"' done diff --git a/.github/workflows/build_riscv.yml b/.github/workflows/build_riscv.yml index 90dc35206..9362da893 100644 --- a/.github/workflows/build_riscv.yml +++ b/.github/workflows/build_riscv.yml @@ -62,7 +62,8 @@ jobs: - name: Linker Map run: | pip install linkermap/ - for ex in `ls -d examples/device/*/`; do \ - find ${ex} -name *.map -print -quit | \ - xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"'; \ + # find -quit to only print linkermap of 1 board per example + for ex in `ls -d examples/device/*/` + do + find ${ex} -name *.map -print -quit | xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"' done From fee90f353f426d6fafe323534ad7d91918d4b98d Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 6 Nov 2022 15:17:00 +0700 Subject: [PATCH 500/504] bump up setup python action to v4 --- .github/workflows/build_aarch64.yml | 2 +- .github/workflows/build_arm.yml | 2 +- .github/workflows/build_esp.yml | 2 +- .github/workflows/build_msp430.yml | 2 +- .github/workflows/build_renesas.yml | 2 +- .github/workflows/build_riscv.yml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build_aarch64.yml b/.github/workflows/build_aarch64.yml index b4ea8a0eb..d610d6eff 100644 --- a/.github/workflows/build_aarch64.yml +++ b/.github/workflows/build_aarch64.yml @@ -21,7 +21,7 @@ jobs: - 'broadcom_64bit' steps: - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 - name: Checkout TinyUSB uses: actions/checkout@v3 diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml index 56804da8a..4d27ba729 100644 --- a/.github/workflows/build_arm.yml +++ b/.github/workflows/build_arm.yml @@ -65,7 +65,7 @@ jobs: - 'xmc4000' steps: - name: Setup Python - uses: actions/setup-python@v3 + uses: actions/setup-python@v4 - name: Install ARM GCC uses: carlosperate/arm-none-eabi-gcc-action@v1 diff --git a/.github/workflows/build_esp.yml b/.github/workflows/build_esp.yml index 417887172..162226cc5 100644 --- a/.github/workflows/build_esp.yml +++ b/.github/workflows/build_esp.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 - name: Pull ESP-IDF docker run: docker pull espressif/idf:latest diff --git a/.github/workflows/build_msp430.yml b/.github/workflows/build_msp430.yml index 731febb03..b43d9e740 100644 --- a/.github/workflows/build_msp430.yml +++ b/.github/workflows/build_msp430.yml @@ -18,7 +18,7 @@ jobs: - 'msp430' steps: - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 - name: Checkout TinyUSB uses: actions/checkout@v3 diff --git a/.github/workflows/build_renesas.yml b/.github/workflows/build_renesas.yml index 4de42f935..c8920c7f7 100644 --- a/.github/workflows/build_renesas.yml +++ b/.github/workflows/build_renesas.yml @@ -18,7 +18,7 @@ jobs: - 'rx' steps: - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 - name: Checkout TinyUSB uses: actions/checkout@v3 diff --git a/.github/workflows/build_riscv.yml b/.github/workflows/build_riscv.yml index 9362da893..a0e09190b 100644 --- a/.github/workflows/build_riscv.yml +++ b/.github/workflows/build_riscv.yml @@ -19,7 +19,7 @@ jobs: - 'gd32vf103' steps: - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 - name: Checkout TinyUSB uses: actions/checkout@v3 From ca4ae61c1ce79f36e540fa4848b9e575a21e71d3 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 6 Nov 2022 22:06:22 +0700 Subject: [PATCH 501/504] use gh cli instead of action for workflow dispatch --- .github/workflows/build_aarch64.yml | 2 ++ .github/workflows/build_arm.yml | 9 +++++---- .github/workflows/build_esp.yml | 2 ++ .github/workflows/build_renesas.yml | 2 ++ .github/workflows/build_riscv.yml | 2 ++ 5 files changed, 13 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build_aarch64.yml b/.github/workflows/build_aarch64.yml index d610d6eff..18989a5e9 100644 --- a/.github/workflows/build_aarch64.yml +++ b/.github/workflows/build_aarch64.yml @@ -22,6 +22,8 @@ jobs: steps: - name: Setup Python uses: actions/setup-python@v4 + with: + python-version: '3.x' - name: Checkout TinyUSB uses: actions/checkout@v3 diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml index 4d27ba729..12853b72b 100644 --- a/.github/workflows/build_arm.yml +++ b/.github/workflows/build_arm.yml @@ -66,6 +66,8 @@ jobs: steps: - name: Setup Python uses: actions/setup-python@v4 + with: + python-version: '3.x' - name: Install ARM GCC uses: carlosperate/arm-none-eabi-gcc-action@v1 @@ -121,10 +123,9 @@ jobs: - name: Trigger Hardware Test if: matrix.family == 'rp2040' && github.repository_owner == 'hathach' - uses: benc-uk/workflow-dispatch@v1 - with: - workflow: Hardware Test - token: ${{ secrets.TRIGGER_SELF_HOSTED }} + env: + GH_TOKEN: ${{ secrets.API_TOKEN_GITHUB }} + run: gh workflow run test_hardware.yml -r $GITHUB_REF # --------------------------------------- # Build all no-family (orphaned) boards diff --git a/.github/workflows/build_esp.yml b/.github/workflows/build_esp.yml index 162226cc5..51d91de49 100644 --- a/.github/workflows/build_esp.yml +++ b/.github/workflows/build_esp.yml @@ -24,6 +24,8 @@ jobs: steps: - name: Setup Python uses: actions/setup-python@v4 + with: + python-version: '3.x' - name: Pull ESP-IDF docker run: docker pull espressif/idf:latest diff --git a/.github/workflows/build_renesas.yml b/.github/workflows/build_renesas.yml index c8920c7f7..d212708f7 100644 --- a/.github/workflows/build_renesas.yml +++ b/.github/workflows/build_renesas.yml @@ -19,6 +19,8 @@ jobs: steps: - name: Setup Python uses: actions/setup-python@v4 + with: + python-version: '3.x' - name: Checkout TinyUSB uses: actions/checkout@v3 diff --git a/.github/workflows/build_riscv.yml b/.github/workflows/build_riscv.yml index a0e09190b..96b8c676b 100644 --- a/.github/workflows/build_riscv.yml +++ b/.github/workflows/build_riscv.yml @@ -20,6 +20,8 @@ jobs: steps: - name: Setup Python uses: actions/setup-python@v4 + with: + python-version: '3.x' - name: Checkout TinyUSB uses: actions/checkout@v3 From 5d13eb8e7a715b3dd02ef485808d82145870b90c Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 6 Nov 2022 22:33:55 +0700 Subject: [PATCH 502/504] move test_hardware into build_arm --- .github/workflows/build_arm.yml | 72 ++++++++++++++++++++++++++++- .github/workflows/test_hardware.yml | 69 --------------------------- 2 files changed, 70 insertions(+), 71 deletions(-) delete mode 100644 .github/workflows/test_hardware.yml diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml index 12853b72b..00de92fa6 100644 --- a/.github/workflows/build_arm.yml +++ b/.github/workflows/build_arm.yml @@ -126,7 +126,7 @@ jobs: env: GH_TOKEN: ${{ secrets.API_TOKEN_GITHUB }} run: gh workflow run test_hardware.yml -r $GITHUB_REF - + # --------------------------------------- # Build all no-family (orphaned) boards # --------------------------------------- @@ -145,7 +145,9 @@ jobs: steps: - name: Setup Python - uses: actions/setup-python@v3 + uses: actions/setup-python@v4 + with: + python-version: '3.x' - name: Install ARM GCC uses: carlosperate/arm-none-eabi-gcc-action@v1 @@ -160,3 +162,69 @@ jobs: - name: Build run: python3 tools/build_board.py ${{ matrix.example }} + + # --------------------------------------- + # Hardware in the loop (HIL) + # Current self-hosted instance is running on an RPI4 with + # - pico + pico-probe connected via USB + # - pico-probe is /dev/ttyACM0 + # --------------------------------------- + hw-test: + # Limit the run to only hathach due to limited resource on RPI4 + if: github.repository_owner == 'hathach' + needs: build-arm + runs-on: [self-hosted, Linux, ARM64] + + steps: + - name: Clean workspace + run: | + echo "Cleaning up previous run" + rm -rf "${{ github.workspace }}" + mkdir -p "${{ github.workspace }}" + + - name: Download rp2040 Artifacts + uses: actions/download-artifact@v3 + with: + name: rp2040 + + - name: Create flash.sh + run: | + touch flash.sh + chmod +x flash.sh + echo > flash.sh 'openocd -f "interface/picoprobe.cfg" -f "target/rp2040.cfg" -c "program $1 reset exit"' + + - name: Test cdc_dual_ports + run: | + ./flash.sh cdc_dual_ports.elf + while (! ([ -e /dev/ttyACM1 ] && [ -e /dev/ttyACM2 ])) && [ $SECONDS -le 5 ]; do :; done + test -e /dev/ttyACM1 && echo "ttyACM1 exists" + test -e /dev/ttyACM2 && echo "ttyACM2 exists" + + - name: Test cdc_msc + run: | + ./flash.sh cdc_msc.elf + readme='/media/pi/TinyUSB MSC/README.TXT' + while (! ([ -e /dev/ttyACM1 ] && [ -f "$readme" ])) && [ $SECONDS -le 5 ]; do :; done + test -e /dev/ttyACM1 && echo "ttyACM1 exists" + test -f "$readme" && echo "$readme exists" + cat "$readme" + + - name: Test dfu + run: | + ./flash.sh dfu.elf + while (! (dfu-util -l | grep "Found DFU")) && [ $SECONDS -le 5 ]; do :; done + dfu-util -d cafe -a 0 -U dfu0 + dfu-util -d cafe -a 1 -U dfu1 + grep "TinyUSB DFU! - Partition 0" dfu0 + grep "TinyUSB DFU! - Partition 1" dfu1 + + - name: Test dfu_runtime + run: | + ./flash.sh dfu_runtime.elf + while (! (dfu-util -l | grep "Found Runtime")) && [ $SECONDS -le 5 ]; do :; done + +# - name: Test hid_boot_interface +# run: | +# ./flash.sh hid_boot_interface.elf +# while (! (dfu-util -l | grep "Found Runtime")) && [ $SECONDS -le 5 ]; do :; done + diff --git a/.github/workflows/test_hardware.yml b/.github/workflows/test_hardware.yml deleted file mode 100644 index 7a6e2a470..000000000 --- a/.github/workflows/test_hardware.yml +++ /dev/null @@ -1,69 +0,0 @@ -name: Hardware Test -on: - workflow_dispatch: - -# Hardware in the loop (HIL) -# Current self-hosted instance is running on an RPI4 with -# - pico + pico-probe connected via USB -# - pico-probe is /dev/ttyACM0 - -jobs: - hw-test: - # Limit the run to only hathach due to limited resource on RPI4 - if: github.repository_owner == 'hathach' - runs-on: [self-hosted, Linux, ARM64] - - steps: - - name: Clean workspace - run: | - echo "Cleaning up previous run" - rm -rf "${{ github.workspace }}" - mkdir -p "${{ github.workspace }}" - - - name: Download rp2040 Artifacts - uses: dawidd6/action-download-artifact@v2 - with: - workflow: build_arm.yml - name: rp2040 - - - name: Create flash.sh - run: | - touch flash.sh - chmod +x flash.sh - echo > flash.sh 'openocd -f "interface/picoprobe.cfg" -f "target/rp2040.cfg" -c "program $1 reset exit"' - - - name: Test cdc_dual_ports - run: | - ./flash.sh cdc_dual_ports.elf - while (! ([ -e /dev/ttyACM1 ] && [ -e /dev/ttyACM2 ])) && [ $SECONDS -le 5 ]; do :; done - test -e /dev/ttyACM1 && echo "ttyACM1 exists" - test -e /dev/ttyACM2 && echo "ttyACM2 exists" - - - name: Test cdc_msc - run: | - ./flash.sh cdc_msc.elf - readme='/media/pi/TinyUSB MSC/README.TXT' - while (! ([ -e /dev/ttyACM1 ] && [ -f "$readme" ])) && [ $SECONDS -le 5 ]; do :; done - test -e /dev/ttyACM1 && echo "ttyACM1 exists" - test -f "$readme" && echo "$readme exists" - cat "$readme" - - - name: Test dfu - run: | - ./flash.sh dfu.elf - while (! (dfu-util -l | grep "Found DFU")) && [ $SECONDS -le 5 ]; do :; done - dfu-util -d cafe -a 0 -U dfu0 - dfu-util -d cafe -a 1 -U dfu1 - grep "TinyUSB DFU! - Partition 0" dfu0 - grep "TinyUSB DFU! - Partition 1" dfu1 - - - name: Test dfu_runtime - run: | - ./flash.sh dfu_runtime.elf - while (! (dfu-util -l | grep "Found Runtime")) && [ $SECONDS -le 5 ]; do :; done - -# - name: Test hid_boot_interface -# run: | -# ./flash.sh hid_boot_interface.elf -# while (! (dfu-util -l | grep "Found Runtime")) && [ $SECONDS -le 5 ]; do :; done - \ No newline at end of file From a0dc9008a7c125b3f5e3b0bc565a06cce3d83863 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 6 Nov 2022 22:39:09 +0700 Subject: [PATCH 503/504] remove trigger hardware step --- .github/workflows/build_arm.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml index 00de92fa6..4d513d7ba 100644 --- a/.github/workflows/build_arm.yml +++ b/.github/workflows/build_arm.yml @@ -121,11 +121,11 @@ jobs: path: | *.elf - - name: Trigger Hardware Test - if: matrix.family == 'rp2040' && github.repository_owner == 'hathach' - env: - GH_TOKEN: ${{ secrets.API_TOKEN_GITHUB }} - run: gh workflow run test_hardware.yml -r $GITHUB_REF +# - name: Trigger Hardware Test +# if: matrix.family == 'rp2040' && github.repository_owner == 'hathach' +# env: +# GH_TOKEN: ${{ secrets.API_TOKEN_GITHUB }} +# run: gh workflow run test_hardware.yml -r $GITHUB_REF # --------------------------------------- # Build all no-family (orphaned) boards From 030b50dce3434aa94cb7428c3e752133ac274ce5 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 6 Nov 2022 23:19:34 +0700 Subject: [PATCH 504/504] final clean up --- .github/workflows/build_arm.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml index 4d513d7ba..53f73a48f 100644 --- a/.github/workflows/build_arm.yml +++ b/.github/workflows/build_arm.yml @@ -121,12 +121,6 @@ jobs: path: | *.elf -# - name: Trigger Hardware Test -# if: matrix.family == 'rp2040' && github.repository_owner == 'hathach' -# env: -# GH_TOKEN: ${{ secrets.API_TOKEN_GITHUB }} -# run: gh workflow run test_hardware.yml -r $GITHUB_REF - # --------------------------------------- # Build all no-family (orphaned) boards # ---------------------------------------