From 62c613f6d2d4e3e2cf0918f75e302d48a3df673e Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Tue, 5 Oct 2021 13:54:47 +0100 Subject: [PATCH 01/53] 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 02/53] 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 03/53] 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 04/53] 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 05/53] 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 06/53] 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 07/53] 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 08/53] 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 09/53] 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 ef879e8a8a43dfa34160f50d7f432c3140dec7fa Mon Sep 17 00:00:00 2001 From: Valentin Milea Date: Mon, 6 Dec 2021 18:49:58 +0200 Subject: [PATCH 10/53] 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 5039a5e54c184d6cc281890b6f328caef116bce7 Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Wed, 8 Dec 2021 09:34:29 +0000 Subject: [PATCH 11/53] 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 12/53] 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 13/53] 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 79f1f4e171393397f25e884792ecc33b2480e050 Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Wed, 8 Dec 2021 11:17:05 +0000 Subject: [PATCH 14/53] 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 15/53] 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 16/53] 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 8d373b08879ac382c59dcbfb2d351d4af35e3d00 Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Wed, 15 Dec 2021 12:23:58 +0000 Subject: [PATCH 17/53] 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 5c5ecea6f17aae16808533aa248671069cdc5fa5 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Sun, 26 Dec 2021 22:19:07 +0100 Subject: [PATCH 18/53] 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 19/53] 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 20/53] 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 21/53] 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 22/53] 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 23/53] 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 24/53] 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 2f69649bb6a2dcd583b52005dc946e08580323fd Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Sun, 26 Dec 2021 21:50:48 +0100 Subject: [PATCH 25/53] 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 26/53] [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 27/53] 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 28/53] 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 29/53] 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 30/53] 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 31/53] 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 32/53] 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 33/53] 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 34/53] 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 35/53] 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 36/53] 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 37/53] 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 38/53] 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 39/53] 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 40/53] 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 41/53] 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 42/53] 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 43/53] 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 44/53] 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 45/53] 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 46/53] 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 47/53] 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 48/53] 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 49/53] 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 50/53] 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 51/53] 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 52/53] 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 3b66bbf6d5a1122a67b970288713febc740dbe49 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 19 Jan 2022 19:12:21 +0700 Subject: [PATCH 53/53] 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