diff --git a/examples/device/cdc_dual_ports/src/usb_descriptors.c b/examples/device/cdc_dual_ports/src/usb_descriptors.c index cda1b63b6a..4eb8c7c272 100644 --- a/examples/device/cdc_dual_ports/src/usb_descriptors.c +++ b/examples/device/cdc_dual_ports/src/usb_descriptors.c @@ -108,6 +108,17 @@ enum #define EPNUM_CDC_1_OUT 0x05 #define EPNUM_CDC_1_IN 0x86 +#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X + // FT9XX doesn't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_CDC_0_NOTIF 0x81 + #define EPNUM_CDC_0_OUT 0x02 + #define EPNUM_CDC_0_IN 0x83 + + #define EPNUM_CDC_1_NOTIF 0x84 + #define EPNUM_CDC_1_OUT 0x05 + #define EPNUM_CDC_1_IN 0x86 + #else #define EPNUM_CDC_0_NOTIF 0x81 #define EPNUM_CDC_0_OUT 0x02 diff --git a/examples/device/dynamic_configuration/src/usb_descriptors.c b/examples/device/dynamic_configuration/src/usb_descriptors.c index 457f774d09..092229b995 100644 --- a/examples/device/dynamic_configuration/src/usb_descriptors.c +++ b/examples/device/dynamic_configuration/src/usb_descriptors.c @@ -145,6 +145,19 @@ enum #define EPNUM_1_MSC_OUT 0x01 #define EPNUM_1_MSC_IN 0x82 +#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X + // FT9XX doesn't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_0_CDC_NOTIF 0x81 + #define EPNUM_0_CDC_OUT 0x02 + #define EPNUM_0_CDC_IN 0x83 + + #define EPNUM_0_MIDI_OUT 0x04 + #define EPNUM_0_MIDI_IN 0x85 + + #define EPNUM_1_MSC_OUT 0x01 + #define EPNUM_1_MSC_IN 0x82 + #else #define EPNUM_0_CDC_NOTIF 0x81 #define EPNUM_0_CDC_OUT 0x02 diff --git a/examples/device/msc_dual_lun/src/usb_descriptors.c b/examples/device/msc_dual_lun/src/usb_descriptors.c index 68a671c91d..d8dbb5ce33 100644 --- a/examples/device/msc_dual_lun/src/usb_descriptors.c +++ b/examples/device/msc_dual_lun/src/usb_descriptors.c @@ -90,6 +90,12 @@ enum #define EPNUM_MSC_OUT 0x01 #define EPNUM_MSC_IN 0x82 +#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X + // FT9XX doesn't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_MSC_OUT 0x01 + #define EPNUM_MSC_IN 0x82 + #else #define EPNUM_MSC_OUT 0x01 #define EPNUM_MSC_IN 0x81 diff --git a/examples/device/uac2_headset/src/usb_descriptors.c b/examples/device/uac2_headset/src/usb_descriptors.c index 10f5cbd279..07c86b9032 100644 --- a/examples/device/uac2_headset/src/usb_descriptors.c +++ b/examples/device/uac2_headset/src/usb_descriptors.c @@ -93,6 +93,12 @@ uint8_t const * tud_descriptor_device_cb(void) #define EPNUM_AUDIO_IN 0x01 #define EPNUM_AUDIO_OUT 0x02 +#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X + // FT9XX doesn't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_AUDIO_IN 0x01 + #define EPNUM_AUDIO_OUT 0x02 + #else #define EPNUM_AUDIO_IN 0x01 #define EPNUM_AUDIO_OUT 0x01 diff --git a/examples/device/webusb_serial/src/usb_descriptors.c b/examples/device/webusb_serial/src/usb_descriptors.c index cafe2c22b1..99f5caaf92 100644 --- a/examples/device/webusb_serial/src/usb_descriptors.c +++ b/examples/device/webusb_serial/src/usb_descriptors.c @@ -97,6 +97,13 @@ enum #define EPNUM_CDC_OUT 3 #define EPNUM_VENDOR_IN 4 #define EPNUM_VENDOR_OUT 5 +#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X + // FT9XX doesn't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_CDC_IN 2 + #define EPNUM_CDC_OUT 3 + #define EPNUM_VENDOR_IN 4 + #define EPNUM_VENDOR_OUT 5 #else #define EPNUM_CDC_IN 2 #define EPNUM_CDC_OUT 2 diff --git a/hw/bsp/brtmm90x/boards/mm900evxb/board.h b/hw/bsp/brtmm90x/boards/mm900evxb/board.h index 57936fda58..7717791086 100644 --- a/hw/bsp/brtmm90x/boards/mm900evxb/board.h +++ b/hw/bsp/brtmm90x/boards/mm900evxb/board.h @@ -27,21 +27,53 @@ #ifndef BOARD_H_ #define BOARD_H_ -// Note: This definition file covers all MM900EV1B, MM900EV2B, and MM900EV3B boards. +// Note: This definition file covers all MM900EV1B, MM900EV2B, MM900EV3B, +// MM900EV-Lite boards. // Each of these boards has an FT900 device. #ifdef __cplusplus extern "C" { #endif -#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 +// UART to use on this board. +#ifndef BOARD_UART +#define BOARD_UART UART0 +#endif + +// UART is on connector CN1. +#ifndef BOARD_GPIO_UART0_TX +#define BOARD_GPIO_UART0_TX 48 // Pin 4 of CN1. +#endif +#ifndef BOARD_GPIO_UART0_RX +#define BOARD_GPIO_UART0_RX 49 // Pin 6 of CN1. +#endif + +// LED is connected to pins 17 (signal) and 15 (GND) of CN1. +#ifndef BOARD_GPIO_LED +#define BOARD_GPIO_LED 35 +#endif +#ifndef BOARD_GPIO_LED_STATE_ON +#define BOARD_GPIO_LED_STATE_ON 1 +#endif +// Button is connected to pins 13 (signal) and 15 (GND) of CN1. +#ifndef BOARD_GPIO_BUTTON +#define BOARD_GPIO_BUTTON 56 +#endif +// Button is pulled up and grounded for active. +#ifndef BOARD_GPIO_BUTTON_STATE_ACTIVE +#define BOARD_GPIO_BUTTON_STATE_ACTIVE 0 +#endif -#define GPIO_REMOTE_WAKEUP +// Enable the Remote Wakeup signalling. +// Remote wakeup is wired to pin 40 of CN1. +#ifndef BOARD_GPIO_REMOTE_WAKEUP +#define BOARD_GPIO_REMOTE_WAKEUP 18 +#endif + +// USB VBus signal is connected directly to the FT900. +#ifndef BOARD_USBD_VBUS_DTC_PIN +#define BOARD_USBD_VBUS_DTC_PIN 3 +#endif #ifdef __cplusplus } diff --git a/hw/bsp/brtmm90x/family.c b/hw/bsp/brtmm90x/family.c index 6b3c1f56cb..3b6b039049 100644 --- a/hw/bsp/brtmm90x/family.c +++ b/hw/bsp/brtmm90x/family.c @@ -27,15 +27,15 @@ #include "bsp/board.h" #include "board.h" -#include #include +#include #if CFG_TUD_ENABLED -int8_t board_ft90x_vbus(void); // Board specific implementation of VBUS detection for USB device. -extern void ft90x_usbd_pm_ISR(uint16_t pmcfg); // Interrupt handler for USB device power management +int8_t board_ft9xx_vbus(void); // Board specific implementation of VBUS detection for USB device. +extern void ft9xx_usbd_pm_ISR(uint16_t pmcfg); // Interrupt handler for USB device power management #endif -#ifdef GPIO_REMOTE_WAKEUP +#ifdef BOARD_GPIO_REMOTE_WAKEUP void gpio_ISR(void); #endif void timer_ISR(void); @@ -49,12 +49,17 @@ void board_pm_ISR(void); 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 */ + // Set BOARD_UART GPIO function pins for TXD and RXD. +#ifdef BOARD_GPIO_UART_TX + gpio_function(BOARD_GPIO_UART_TX, pad_uart0_txd); /* UART0 TXD */ +#endif +#ifdef BOARD_GPIO_UART_RX + gpio_function(BOARD_GPIO_UART_RX, pad_uart0_rxd); /* UART0 RXD */ +#endif + uart_open(BOARD_UART, /* Device */ 1, /* Prescaler = 1 */ UART_DIVIDER_19200_BAUD, /* Divider = 1302 */ uart_data_bits_8, /* No. Data Bits */ @@ -64,12 +69,17 @@ void board_init(void) // Use sizeof to avoid pulling in strlen unnecessarily. board_uart_write(WELCOME_MSG, sizeof(WELCOME_MSG)); -#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 */ - gpio_dir(GPIO_ETH_LED1, pad_dir_output); +#ifdef BOARD_GPIO_LED + gpio_function(BOARD_GPIO_LED, pad_func_0); + gpio_idrive(BOARD_GPIO_LED, pad_drive_12mA); + gpio_dir(BOARD_GPIO_LED, pad_dir_output); +#endif + +#ifdef BOARD_GPIO_BUTTON + gpio_function(BOARD_GPIO_BUTTON, pad_func_0); + // Pull up if active low. Down if active high. + gpio_pull(BOARD_GPIO_BUTTON, (BOARD_GPIO_BUTTON_STATE_ACTIVE == 0)?pad_pull_pullup:pad_pull_pulldown); + gpio_dir(BOARD_GPIO_BUTTON, pad_dir_input); #endif sys_enable(sys_device_timer_wdt); @@ -82,26 +92,26 @@ void board_init(void) // 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); + gpio_interrupt_disable(BOARD_USBD_VBUS_DTC_PIN); + gpio_function(BOARD_USBD_VBUS_DTC_PIN, pad_vbus_dtc); + gpio_pull(BOARD_USBD_VBUS_DTC_PIN, pad_pull_pulldown); + gpio_dir(BOARD_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. +#ifdef BOARD_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); + gpio_dir(BOARD_GPIO_REMOTE_WAKEUP, pad_dir_input); + gpio_pull(BOARD_GPIO_REMOTE_WAKEUP, 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); + gpio_interrupt_enable(BOARD_GPIO_REMOTE_WAKEUP, gpio_int_edge_falling); #endif - uart_disable_interrupt(UART0, uart_interrupt_tx); - uart_disable_interrupt(UART0, uart_interrupt_rx); + uart_disable_interrupt(BOARD_UART, uart_interrupt_tx); + uart_disable_interrupt(BOARD_UART, uart_interrupt_rx); // Enable all peripheral interrupts. interrupt_enable_globally(); @@ -117,10 +127,10 @@ void timer_ISR(void) } } -#ifdef GPIO_REMOTE_WAKEUP +#ifdef BOARD_GPIO_REMOTE_WAKEUP void gpio_ISR(void) { - if (gpio_is_interrupted(GPIO_REMOTE_WAKEUP_PIN)) + if (gpio_is_interrupted(BOARD_GPIO_REMOTE_WAKEUP)) { } } @@ -153,16 +163,16 @@ void board_pm_ISR(void) ) { #if CFG_TUD_ENABLED - ft90x_usbd_pm_ISR(pmcfg); + ft9xx_usbd_pm_ISR(pmcfg); #endif } #endif } #if CFG_TUD_ENABLED -int8_t board_ft90x_vbus(void) +int8_t board_ft9xx_vbus(void) { - return gpio_read(USBD_VBUS_DTC_PIN); + return gpio_read(BOARD_USBD_VBUS_DTC_PIN); } #endif @@ -173,20 +183,33 @@ int8_t board_ft90x_vbus(void) // Turn LED on or off void board_led_write(bool state) { - gpio_write(GPIO_ETH_LED0, state); +#ifdef BOARD_GPIO_LED + gpio_write(BOARD_GPIO_LED, (state == 0)?(BOARD_GPIO_LED_STATE_ON?0:1):BOARD_GPIO_LED_STATE_ON); +#endif } // Get the current state of button // a '1' means active (pressed), a '0' means inactive. uint32_t board_button_read(void) { - return 0; + uint32_t state = 0; +#ifdef BOARD_GPIO_BUTTON + state = (gpio_read(BOARD_GPIO_BUTTON) == BOARD_GPIO_BUTTON_STATE_ACTIVE)?1:0; +#endif + return state; } // Get characters from UART int board_uart_read(uint8_t *buf, int len) { - int r = uart_readn(UART0, (uint8_t *)buf, len); + int r = 0; + +#ifdef BOARD_UART + if (uart_rx_has_data(BOARD_UART)) + { + r = uart_readn(BOARD_UART, (uint8_t *)buf, len); + } +#endif return r; } @@ -194,10 +217,14 @@ int board_uart_read(uint8_t *buf, int len) // Send characters to UART int board_uart_write(void const *buf, int len) { + int r = 0; + +#ifdef BOARD_UART #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); + r = uart_writen(BOARD_UART, (uint8_t *)((const void *)buf), len); #pragma GCC diagnostic pop +#endif return r; } @@ -213,3 +240,18 @@ uint32_t board_millis(void) return safe_ms; } + +// Restart the program +// Called in the event of a watchdog timeout +void chip_reboot(void) +{ + // SOFT reset + __asm__("call 0"); + #if 0 + // HARD reset + // Initiates data transfer from Flash Memory to Data Memory (DBG_CMDF2D3) + // followed by a system reboot + dbg_memory_copy(0xfe, 0, 0, 255); +#endif +} + diff --git a/hw/bsp/brtmm90x/family.mk b/hw/bsp/brtmm90x/family.mk index 3933f15cc3..0ddf47a3af 100644 --- a/hw/bsp/brtmm90x/family.mk +++ b/hw/bsp/brtmm90x/family.mk @@ -3,12 +3,12 @@ CROSS_COMPILE = ft32-elf- SKIP_NANOLIB = 1 # Set to use FT90X prebuilt libraries. -FT90X_PREBUILT_LIBS = 0 -ifeq ($(FT90X_PREBUILT_LIBS),1) +FT9XX_PREBUILT_LIBS = 0 +ifeq ($(FT9XX_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 +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 @@ -16,12 +16,12 @@ else 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/ft90x-sdk/Source -INC += $(TOP)/$(FT9XX_SDK)/include +INC += "$(TOP)/$(FT9XX_SDK)/include" endif # Add include files which are within the TinyUSB directory structure. INC += \ - $(TOP)/$(BOARD_PATH) + $(TOP)/$(BOARD_PATH) # Add required C Compiler flags for FT90X. CFLAGS += \ @@ -30,14 +30,14 @@ CFLAGS += \ -fvar-tracking-assignments \ -fmessage-length=0 \ -ffunction-sections \ - -DCFG_TUSB_MCU=OPT_MCU_FT90X + -DCFG_TUSB_MCU=OPT_MCU_FT90X + +# Maximum USB device speed supported by the board +CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED # lwip/src/core/raw.c:334:43: error: declaration of 'recv' shadows a global declaration CFLAGS += -Wno-error=shadow -# 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)) \ @@ -48,7 +48,7 @@ LDFLAGS += $(addprefix -L,$(LDINC)) \ SRC_C += src/portable/bridgetek/ft9xx/dcd_ft9xx.c # Linker library. -ifneq ($(FT90X_PREBUILT_LIBS),1) +ifneq ($(FT9XX_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 diff --git a/hw/mcu/bridgetek/ft9xx/ft90x-sdk b/hw/mcu/bridgetek/ft9xx/ft90x-sdk index e8122eb6bd..91060164af 160000 --- a/hw/mcu/bridgetek/ft9xx/ft90x-sdk +++ b/hw/mcu/bridgetek/ft9xx/ft90x-sdk @@ -1 +1 @@ -Subproject commit e8122eb6bd6286a1fe31f175a3e3eb0e7770c3e3 +Subproject commit 91060164afe239fcb394122e8bf9eb24d3194eb1 diff --git a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c index 261a3c9c22..efca5bdcb4 100644 --- a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c +++ b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c @@ -38,9 +38,6 @@ #include #include -#include "board.h" -#include "bsp/board.h" - #define USBD_USE_STREAMS #include "device/dcd.h" @@ -50,17 +47,21 @@ //--------------------------------------------------------------------+ // Board code will determine the state of VBUS from USB host. -extern int8_t board_ft90x_vbus(void); +extern int8_t board_ft9xx_vbus(void); +extern int board_uart_write(void const *buf, int len); // Static array to store an incoming SETUP request for processing by tinyusb. -static uint8_t _ft90x_setup_packet[8]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN +static uint8_t _ft9xx_setup_packet[8]; -struct ft90x_xfer_state +struct ft9xx_xfer_state { + volatile uint8_t ready; // OUT Transfer has been received and waiting for transfer. 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. + + 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. @@ -68,24 +69,24 @@ struct ft90x_xfer_state 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]; +static struct ft9xx_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). +void _ft9xx_usbd_ISR(void); // Interrupt handler for USB device. +void ft9xx_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); +static uint16_t _ft9xx_edpt_xfer_out(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes); +static uint16_t _ft9xx_edpt_xfer_in(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes); +static void _ft9xx_reset_edpts(void); +static inline void _ft9xx_phy_enable(bool en); +static void _ft9xx_usb_speed(void); +static void _dcd_ft9xx_attach(void); +static void _dcd_ft9xx_detach(void) __attribute__((unused)); +static uint16_t _ft9xx_dusb_in(uint8_t ep_number, const uint8_t *buffer, uint16_t length); +static uint16_t _ft9xx_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t length); // Internal functions. @@ -93,7 +94,7 @@ static uint16_t _ft90x_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t len // 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) +static uint16_t _ft9xx_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; @@ -108,7 +109,7 @@ static uint16_t _ft90x_edpt_xfer_out(uint8_t ep_number, uint8_t *buffer, uint16_ //; // Send the first packet of max packet size - xfer_bytes = _ft90x_dusb_out(ep_number, (uint8_t *)buffer, xfer_bytes); + xfer_bytes = _ft9xx_dusb_out(ep_number, (uint8_t *)buffer, xfer_bytes); if (ep_number == USBD_EP_0) { // Set flags to indicate data ready. @@ -126,7 +127,7 @@ static uint16_t _ft90x_edpt_xfer_out(uint8_t ep_number, uint8_t *buffer, uint16_ // 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) +static uint16_t _ft9xx_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; @@ -154,17 +155,24 @@ static uint16_t _ft90x_edpt_xfer_in(uint8_t ep_number, uint8_t *buffer, uint16_t } else { - uint8_t sr_reg; // If there is data to transmit then wait until the IN buffer // for the endpoint is empty. - do + // This does not apply to interrupt endpoints. + if (ep_xfer[ep_number].type != TUSB_XFER_INTERRUPT) { - sr_reg = USBD_EP_SR_REG(ep_number); - } while (sr_reg & MASK_USBD_EPxSR_INPRDY); - + uint8_t sr_reg; + 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); + // Do not send a ZLP for interrupt endpoints. + if ((ep_xfer[ep_number].type != TUSB_XFER_INTERRUPT) || (xfer_bytes > 0)) + { + xfer_bytes = _ft9xx_dusb_in(ep_number, (uint8_t *)buffer, xfer_bytes); + } if (ep_number == USBD_EP_0) { @@ -190,13 +198,13 @@ static uint16_t _ft90x_edpt_xfer_in(uint8_t ep_number, uint8_t *buffer, uint16_t // 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) +static void _ft9xx_reset_edpts(void) { // Disable all endpoints and remove configuration values. for (int i = 1; i < USBD_MAX_ENDPOINT_COUNT; i++) { // Clear settings. - tu_memclr(&ep_xfer[i], sizeof(struct ft90x_xfer_state)); + tu_memclr(&ep_xfer[i], sizeof(struct ft9xx_xfer_state)); // Disable hardware. USBD_EP_CR_REG(i) = 0; } @@ -206,7 +214,7 @@ static void _ft90x_reset_edpts(void) } // Enable or disable the USB PHY. -static inline void _ft90x_phy_enable(bool en) +static inline void _ft9xx_phy_enable(bool en) { if (en) SYS->PMCFG_L |= MASK_SYS_PMCFG_DEV_PHY_EN; @@ -215,7 +223,7 @@ static inline void _ft90x_phy_enable(bool en) } // Safely connect to the USB. -static void _dcd_ft90x_attach(void) +static void _dcd_ft9xx_attach(void) { uint8_t reg; @@ -271,7 +279,7 @@ static void _dcd_ft90x_attach(void) } // Gracefully disconnect from the USB. -static void _dcd_ft90x_detach(void) +static void _dcd_ft9xx_detach(void) { // Disable device connect/disconnect/host reset detection. SYS->PMCFG_L = SYS->PMCFG_L & (~MASK_SYS_PMCFG_DEV_DETECT_EN); @@ -313,7 +321,7 @@ static void _dcd_ft90x_detach(void) // Determine the speed of the USB to which we are connected. // Set the speed of the PHY accordingly. // High speed can be disabled through CFG_TUSB_RHPORT0_MODE or CFG_TUD_MAX_SPEED settings. -static void _ft90x_usb_speed(void) +static void _ft9xx_usb_speed(void) { uint8_t fctrl_val; @@ -376,7 +384,7 @@ static void _ft90x_usb_speed(void) // 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) +static uint16_t _ft9xx_dusb_in(uint8_t ep_number, const uint8_t *buffer, uint16_t length) { uint16_t bytes_read = 0; uint16_t buff_size = length; @@ -433,7 +441,7 @@ static uint16_t _ft90x_dusb_in(uint8_t ep_number, const uint8_t *buffer, uint16_ // 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) +static uint16_t _ft9xx_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t length) { #ifdef USBD_USE_STREAMS volatile uint8_t *data_reg; @@ -511,11 +519,11 @@ static uint16_t _ft90x_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t len // Initialize controller to device mode void dcd_init(uint8_t rhport) { - TU_LOG2("FT90x initialisation\r\n"); + TU_LOG2("FT9xx initialisation\r\n"); - _dcd_ft90x_attach(); + _dcd_ft9xx_attach(); - interrupt_attach(interrupt_usb_device, (int8_t)interrupt_usb_device, _ft90x_usbd_ISR); + interrupt_attach(interrupt_usb_device, (int8_t)interrupt_usb_device, _ft9xx_usbd_ISR); dcd_connect(rhport); } @@ -524,7 +532,7 @@ void dcd_init(uint8_t rhport) void dcd_int_enable(uint8_t rhport) { (void)rhport; - TU_LOG3("FT90x int enable\r\n"); + TU_LOG3("FT9xx int enable\r\n"); // Peripheral devices interrupt enable. interrupt_enable_globally(); @@ -534,7 +542,7 @@ void dcd_int_enable(uint8_t rhport) void dcd_int_disable(uint8_t rhport) { (void)rhport; - TU_LOG3("FT90x int disable\r\n"); + TU_LOG3("FT9xx int disable\r\n"); // Peripheral devices interrupt disable. interrupt_disable_globally(); @@ -600,18 +608,18 @@ void dcd_remote_wakeup(uint8_t rhport) void dcd_connect(uint8_t rhport) { (void)rhport; - TU_LOG2("FT90x connect\r\n"); + TU_LOG2("FT9xx connect\r\n"); CRITICAL_SECTION_BEGIN // Is device connected? - if (board_ft90x_vbus()) + if (board_ft9xx_vbus()) { // Clear/disable address register. USBD_REG(faddr) = 0; - _ft90x_phy_enable(true); + _ft9xx_phy_enable(true); // Determine bus speed and signal speed to tusb. - _ft90x_usb_speed(); + _ft9xx_usb_speed(); } // Setup the control endpoint only. @@ -636,17 +644,17 @@ void dcd_connect(uint8_t rhport) USBD_REG(epie) = (MASK_USBD_EPIE_EP0IE); // Restore default endpoint state. - _ft90x_reset_edpts(); + _ft9xx_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"); + TU_LOG2("FT9xx disconnect\r\n"); // Disable the USB PHY. - _ft90x_phy_enable(false); + _ft9xx_phy_enable(false); } void dcd_sof_enable(uint8_t rhport, bool en) @@ -674,12 +682,12 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc) 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'); + TU_LOG2("FT9xx 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); + TU_LOG1("FT9xx endpoint not valid: requested %d max %d\r\n", ep_number, USBD_MAX_ENDPOINT_COUNT); return false; } @@ -691,7 +699,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc) } if (ep_reg_size > USBD_EP_MAX_SIZE_1024) { - TU_LOG1("FT90x endpoint size not valid: requested %d max 1024\r\n", ep_size); + TU_LOG1("FT9xx 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 @@ -706,9 +714,9 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc) 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 + // On FT9xx, 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); + TU_LOG1("FT9xx endpoint %d already assigned\r\n", ep_number); return false; } @@ -732,23 +740,28 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc) } } } - // The control endpoint is taken into account as well. - total_ram -= ep_xfer[0].buff_size; + + if (sys_check_ft900_revB()) + { + // The control endpoint is taken into account as well on RevB silicon. + 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); + TU_LOG1("FT9xx 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) + if (ep_type == TUSB_XFER_BULK) ep_reg_data |= (USBD_EP_DIS_BULK << BIT_USBD_EP_CONTROL_DIS); - else if (ep_type == USBD_EP_INT) + else if (ep_type == TUSB_XFER_INTERRUPT) ep_reg_data |= (USBD_EP_DIS_INT << BIT_USBD_EP_CONTROL_DIS); - else if (ep_type == USBD_EP_ISOC) + else if (ep_type == TUSB_XFER_ISOCHRONOUS) 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) @@ -756,9 +769,9 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc) // Do not perform double buffering. //if ( != USBD_DB_OFF) //ep_reg_data |= MASK_USBD_EPxCR_DB; - // Set the control endpoint for this endpoint. + // Set the control register for this endpoint. USBD_EP_CR_REG(ep_number) = ep_reg_data; - TU_LOG2("FT90x endpoint setting %x\r\n", ep_reg_data); + TU_LOG2("FT9xx endpoint setting %x\r\n", ep_reg_data); } else { @@ -766,14 +779,15 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc) USBD_EP_CR_REG(USBD_EP_0) = (ep_reg_size << BIT_USBD_EP0_MAX_SIZE); } + CRITICAL_SECTION_BEGIN // 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].ready = 0; ep_xfer[ep_number].valid = 0; ep_xfer[ep_number].buff_ptr = NULL; ep_xfer[ep_number].total_size = 0; @@ -788,7 +802,7 @@ void dcd_edpt_close_all(uint8_t rhport) { (void)rhport; // Reset the endpoint configurations. - _ft90x_reset_edpts(); + _ft9xx_reset_edpts(); } // Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack @@ -796,7 +810,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to { (void)rhport; uint8_t ep_number = tu_edpt_number(ep_addr); - uint8_t dir = tu_edpt_dir(ep_addr); + uint8_t ep_dir = tu_edpt_dir(ep_addr); uint16_t xfer_bytes; bool status = false; @@ -806,19 +820,17 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to // 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; + ep_xfer[USBD_EP_0].dir = ep_dir; } else { @@ -827,18 +839,53 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to USBD_REG(epie) = USBD_REG(epie) | (1 << ep_number); } - if (dir == TUSB_DIR_IN) + if (ep_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); + xfer_bytes = _ft9xx_edpt_xfer_in(ep_number, buffer, total_bytes); ep_xfer[ep_number].buff_ptr += xfer_bytes; ep_xfer[ep_number].remain_size -= xfer_bytes; + + // Tell the interrupt handler to signal dcd_event_xfer_complete on completion. + ep_xfer[ep_number].valid = 1; } + else // (dir == TUSB_DIR_OUT) + { + // For OUT transfers on the control endpoint. + // The host may already have performed the first data transfer after the SETUP packet + // before the transfer is setup for it. + if (ep_xfer[ep_number].ready) + { + // We have received a data packet on the endpoint without a transfer + // being initialised. This can be because the host has sent this packet before + // a new transfer has been initiated on the endpoint. + // We will now stream the data from the FIFO. + ep_xfer[ep_number].ready = 0; + + // Transfer incoming data from an OUT packet to the buffer. + xfer_bytes = _ft9xx_edpt_xfer_out(ep_number, buffer, total_bytes); + + // Report completion of the transfer. + dcd_event_xfer_complete(BOARD_TUD_RHPORT, ep_number /*| TUSB_DIR_OUT_MASK */, xfer_bytes, XFER_RESULT_SUCCESS, false); + } + else + { + // Tell the interrupt handler to wait for the packet to be received and + // then report the transfer complete with dcd_event_xfer_complete. + ep_xfer[ep_number].valid = 1; + } + } + status = true; + } + else + { + // Note: should not arrive here. } + CRITICAL_SECTION_END - + return status; } @@ -889,6 +936,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) USBD_EP_SR_REG(ep_number) = MASK_USBD_EPxSR_CLR_TOGGLE; // Allow transfers to restart. + ep_xfer[ep_number].ready = 0; ep_xfer[ep_number].valid = 0; ep_xfer[ep_number].remain_size = 0; CRITICAL_SECTION_END @@ -897,9 +945,9 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) // Interrupt handling. -void _ft90x_usbd_ISR(void) +void _ft9xx_usbd_ISR(void) { - tud_int_handler(BOARD_TUD_RHPORT); // Resolves to dcd_int_handler(). + dcd_int_handler(BOARD_TUD_RHPORT); } void dcd_int_handler(uint8_t rhport) @@ -936,7 +984,7 @@ void dcd_int_handler(uint8_t rhport) if (cmif & MASK_USBD_CMIF_RSTIRQ) //Handle Reset interrupt { // Reset endpoints to default state. - _ft90x_reset_edpts(); + _ft9xx_reset_edpts(); dcd_event_bus_reset(BOARD_TUD_RHPORT, _speed, true); } if (cmif & MASK_USBD_CMIF_SUSIRQ) //Handle Suspend interrupt @@ -962,7 +1010,6 @@ void dcd_int_handler(uint8_t rhport) { // 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) { @@ -976,16 +1023,19 @@ void dcd_int_handler(uint8_t rhport) USBD_EP_SR_REG(USBD_EP_0) = MASK_USBD_EP0SR_STALL; } - // Host has sent a SETUP packet. Receive this into the setup packet store. - _ft90x_dusb_out(USBD_EP_0, (uint8_t *)_ft90x_setup_packet, sizeof(USB_device_request)); + // Host has sent a SETUP packet. Receive this into the SETUP packet store. + _ft9xx_dusb_out(USBD_EP_0, (uint8_t *)_ft9xx_setup_packet, sizeof(USB_device_request)); // Send the packet to tinyusb. - dcd_event_setup_received(BOARD_TUD_RHPORT, _ft90x_setup_packet, true); + dcd_event_setup_received(BOARD_TUD_RHPORT, _ft9xx_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. + // Any SETUP packet will clear the incoming FIFO. + ep_xfer[USBD_EP_0].ready = 0; + + // Allow new DATA and ACK transfers on the control endpoint. ep_xfer[USBD_EP_0].valid = 0; return; } @@ -998,15 +1048,29 @@ void dcd_int_handler(uint8_t rhport) // 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); + { + xfer_bytes = _ft9xx_edpt_xfer_out(USBD_EP_0, ep_xfer[USBD_EP_0].buff_ptr, xfer_bytes); } // Now signal completion of data packet. - dcd_event_xfer_complete(BOARD_TUD_RHPORT, (ep_xfer[USBD_EP_0].dir ? TUSB_DIR_IN_MASK : 0), xfer_bytes, XFER_RESULT_SUCCESS, true); + dcd_event_xfer_complete(BOARD_TUD_RHPORT, USBD_EP_0 | (ep_xfer[USBD_EP_0].dir ? TUSB_DIR_IN_MASK : 0), + xfer_bytes, XFER_RESULT_SUCCESS, true); + + // Incoming FIFO has been cleared. + ep_xfer[USBD_EP_0].ready = 0; // Allow new transfers on the control endpoint. ep_xfer[USBD_EP_0].valid = 0; } + // No transfer is in flight for EP0. + else + { + // We have received a data packet on the control endpoint without a transfer + // being initialised. This can be because the host has sent this packet before + // a new transfer has been initiated on the control endpoint. + // We will record that there is data in the FIFO for dcd_edpt_xfer to obtain + // once the transfer is initiated. + ep_xfer[USBD_EP_0].ready = 1; + } } } else // !(epif & MASK_USBD_EPIF_EP0IRQ) @@ -1026,7 +1090,6 @@ void dcd_int_handler(uint8_t rhport) 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); @@ -1034,10 +1097,15 @@ void dcd_int_handler(uint8_t rhport) // 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, + xfer_bytes = _ft9xx_edpt_xfer_out(ep_number, + ep_xfer[ep_number].buff_ptr, (uint16_t)ep_xfer[ep_number].remain_size); + // Report each OUT packet received to the stack. + dcd_event_xfer_complete(BOARD_TUD_RHPORT, + ep_number /* | TUSB_DIR_OUT_MASK */, + xfer_bytes, XFER_RESULT_SUCCESS, true); + ep_xfer[ep_number].buff_ptr += xfer_bytes; ep_xfer[ep_number].remain_size -= xfer_bytes; } @@ -1046,27 +1114,45 @@ void dcd_int_handler(uint8_t rhport) { if (ep_xfer[ep_number].remain_size > 0) { - xfer_bytes = _ft90x_edpt_xfer_in(ep_number, - (uint8_t *)ep_xfer[ep_number].buff_ptr, + xfer_bytes = _ft9xx_edpt_xfer_in(ep_number, + 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; } + + if (ep_xfer[ep_number].remain_size == 0) + { + dcd_event_xfer_complete(BOARD_TUD_RHPORT, + ep_number | TUSB_DIR_IN_MASK, + ep_xfer[ep_number].total_size, XFER_RESULT_SUCCESS, true); + } } // When the transfer is complete... if (ep_xfer[ep_number].remain_size == 0) { - // Signal tinyUSB. - dcd_event_xfer_complete(BOARD_TUD_RHPORT, ep_number | ep_dirmask, ep_xfer[ep_number].total_size, XFER_RESULT_SUCCESS, true); - - // Allow new transfers on this endpoint. + // Finish this transfer and 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)); } + + ep_xfer[ep_number].ready = 0; + } + // No OUT transfer is in flight for this endpoint. + else + { + if (ep_xfer[ep_number].dir == TUSB_DIR_OUT) + { + // We will record that there is data in the FIFO for dcd_edpt_xfer to obtain + // once the transfer is initiated. + // Strictly this should not happen for a non-control endpoint. Interrupts + // are disabled when there are no transfers setup for an endpoint. + ep_xfer[ep_number].ready = 1; + } } } } @@ -1075,7 +1161,7 @@ void dcd_int_handler(uint8_t rhport) // Power management interrupt handler. // This handles USB device related power management interrupts only. -void ft90x_usbd_pm_ISR(void) +void ft9xx_usbd_pm_ISR(void) { uint16_t pmcfg = SYS->PMCFG_H;