From 9ccfb384e8dcbed314c25af698969bb5a17f3810 Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Thu, 24 Nov 2022 12:17:55 +0000 Subject: [PATCH 01/10] Update to v2.6.0 library --- 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 e8122eb6b..c810d1312 160000 --- a/hw/mcu/bridgetek/ft9xx/ft90x-sdk +++ b/hw/mcu/bridgetek/ft9xx/ft90x-sdk @@ -1 +1 @@ -Subproject commit e8122eb6bd6286a1fe31f175a3e3eb0e7770c3e3 +Subproject commit c810d1312ded923c3c2ed9035c97bd0db4f35b5f From 1fce76ad472fe1936eedea0688960c76bd42fd40 Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Mon, 28 Nov 2022 17:41:00 +0000 Subject: [PATCH 02/10] Fix issue with the CDC SetLineCoding request The SetLineCoding would fail as host would send the SETUP OUT phase before tinyUSB had setup a transaction for it. ft9xx port would ignore the transfer since there was no valid transaction setup for it. One SETUP data phase packet is cached now. --- .../cdc_dual_ports/src/usb_descriptors.c | 2 +- hw/bsp/brtmm90x/family.c | 17 +++- hw/bsp/brtmm90x/family.mk | 10 +-- hw/mcu/bridgetek/ft9xx/ft90x-sdk | 2 +- src/portable/bridgetek/ft9xx/dcd_ft9xx.c | 82 +++++++++++++++---- 5 files changed, 87 insertions(+), 26 deletions(-) diff --git a/examples/device/cdc_dual_ports/src/usb_descriptors.c b/examples/device/cdc_dual_ports/src/usb_descriptors.c index cda1b63b6..9f212c78f 100644 --- a/examples/device/cdc_dual_ports/src/usb_descriptors.c +++ b/examples/device/cdc_dual_ports/src/usb_descriptors.c @@ -97,7 +97,7 @@ enum #define EPNUM_CDC_1_OUT 0x05 #define EPNUM_CDC_1_IN 0x85 -#elif CFG_TUSB_MCU == OPT_MCU_SAMG || CFG_TUSB_MCU == OPT_MCU_SAMX7X +#elif CFG_TUSB_MCU == OPT_MCU_SAMG || CFG_TUSB_MCU == OPT_MCU_SAMX7X || CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X // SAMG & SAME70 don't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_CDC_0_NOTIF 0x81 diff --git a/hw/bsp/brtmm90x/family.c b/hw/bsp/brtmm90x/family.c index 6b3c1f56c..77a03e909 100644 --- a/hw/bsp/brtmm90x/family.c +++ b/hw/bsp/brtmm90x/family.c @@ -27,8 +27,8 @@ #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. @@ -213,3 +213,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 3933f15cc..a476cfc06 100644 --- a/hw/bsp/brtmm90x/family.mk +++ b/hw/bsp/brtmm90x/family.mk @@ -21,7 +21,7 @@ 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)) \ diff --git a/hw/mcu/bridgetek/ft9xx/ft90x-sdk b/hw/mcu/bridgetek/ft9xx/ft90x-sdk index c810d1312..0ea80ceaf 160000 --- a/hw/mcu/bridgetek/ft9xx/ft90x-sdk +++ b/hw/mcu/bridgetek/ft9xx/ft90x-sdk @@ -1 +1 @@ -Subproject commit c810d1312ded923c3c2ed9035c97bd0db4f35b5f +Subproject commit 0ea80ceafdf32e4e496cacc94178417e2ef4bf9c diff --git a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c index 2445593fe..080d633fa 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" @@ -53,14 +50,20 @@ extern int8_t board_ft90x_vbus(void); // Static array to store an incoming SETUP request for processing by tinyusb. +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t _ft90x_setup_packet[8]; +// Static array to store one SETUP DATA packet until required by dcd_edpt_xfer. +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN +static uint8_t _ft90x_ctrl_buf[CFG_TUD_ENDPOINT0_SIZE]; +static uint8_t _ft90x_ctrl_buf_complete; + struct ft90x_xfer_state { 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. @@ -766,13 +769,13 @@ 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].valid = 0; ep_xfer[ep_number].buff_ptr = NULL; @@ -809,12 +812,9 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to // 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) { @@ -835,10 +835,33 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to 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 + { + // 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_number == USBD_EP_0) && (_ft90x_ctrl_buf_complete)) + { + // Pull the received data packet from the packet cache and complete the transfer + // immediately. + memcpy(buffer, _ft90x_ctrl_buf, _ft90x_ctrl_buf_complete); + dcd_event_xfer_complete(BOARD_TUD_RHPORT, TUSB_DIR_OUT, _ft90x_ctrl_buf_complete, XFER_RESULT_SUCCESS, false); + } + else + { + // Tell the interrupt handler to wait for the packet to be received. + ep_xfer[ep_number].valid = 1; + } + } + status = true; } + CRITICAL_SECTION_END - + return status; } @@ -899,7 +922,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) void _ft90x_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) @@ -962,7 +985,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,7 +998,7 @@ void dcd_int_handler(uint8_t rhport) USBD_EP_SR_REG(USBD_EP_0) = MASK_USBD_EP0SR_STALL; } - // Host has sent a SETUP packet. Recieve this into the setup packet store. + // 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. @@ -985,6 +1007,9 @@ void dcd_int_handler(uint8_t rhport) // Clear the interrupt that signals a SETUP packet is received. USBD_EP_SR_REG(USBD_EP_0) = (MASK_USBD_EP0SR_SETUP); + // Invalidate cache packet. + _ft90x_ctrl_buf_complete = 0; + // Allow new transfers on the control endpoint. ep_xfer[USBD_EP_0].valid = 0; return; @@ -998,15 +1023,36 @@ 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 = _ft90x_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); + // Invalidate cache packet. + _ft90x_ctrl_buf_complete = 0; + // Allow new transfers on the control endpoint. ep_xfer[USBD_EP_0].valid = 0; } + 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 cache upto the maximum packet size for the control endpoint and + // use it later in dcd_edpt_xfer. + xfer_bytes = CFG_TUD_ENDPOINT0_SIZE; + + // Transfer incoming data from an OUT packet to the cache packet. + xfer_bytes = _ft90x_edpt_xfer_out(USBD_EP_0, _ft90x_ctrl_buf, xfer_bytes); + + // Set the size of the cache packet. + _ft90x_ctrl_buf_complete = xfer_bytes; + } + + // Clear the interrupt that signals a SETUP DATA packet is received. + USBD_EP_SR_REG(USBD_EP_0) = (MASK_USBD_EP0SR_OPRDY); } } else // !(epif & MASK_USBD_EPIF_EP0IRQ) @@ -1035,7 +1081,7 @@ void dcd_int_handler(uint8_t rhport) 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, + ep_xfer[ep_number].buff_ptr, (uint16_t)ep_xfer[ep_number].remain_size); ep_xfer[ep_number].buff_ptr += xfer_bytes; @@ -1047,7 +1093,7 @@ 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, + ep_xfer[ep_number].buff_ptr, (uint16_t)ep_xfer[ep_number].remain_size); ep_xfer[ep_number].buff_ptr += xfer_bytes; From 7d8d3eca730552355b5ad442f58b5a6b070d4d03 Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Tue, 29 Nov 2022 18:49:23 +0000 Subject: [PATCH 03/10] Fix transfers issues with FT9xx Correct USB FIFO use for setup data phases (OUT transfers). We cannot stop traffic on the control endpoint so we set a flag and pull data from host when tinyUSB requests it from the USB FIFO. Extend this for all endpoints although currently not required. Rename all instances of ft90x which can apply to ft93x as ft9xx. Add support for the cdc_dual_ports example for ft9xx. Add LED pin definition for board LED in a simple to access place on the Bridgetek MM900EVx boards. --- .../cdc_dual_ports/src/usb_descriptors.c | 12 +- hw/bsp/brtmm90x/boards/mm900evxb/board.h | 18 +- hw/bsp/brtmm90x/family.c | 22 +- hw/bsp/brtmm90x/family.mk | 6 +- src/portable/bridgetek/ft9xx/dcd_ft9xx.c | 225 ++++++++++-------- 5 files changed, 167 insertions(+), 116 deletions(-) diff --git a/examples/device/cdc_dual_ports/src/usb_descriptors.c b/examples/device/cdc_dual_ports/src/usb_descriptors.c index 9f212c78f..5a8dea553 100644 --- a/examples/device/cdc_dual_ports/src/usb_descriptors.c +++ b/examples/device/cdc_dual_ports/src/usb_descriptors.c @@ -97,7 +97,7 @@ enum #define EPNUM_CDC_1_OUT 0x05 #define EPNUM_CDC_1_IN 0x85 -#elif CFG_TUSB_MCU == OPT_MCU_SAMG || CFG_TUSB_MCU == OPT_MCU_SAMX7X || CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X +#elif CFG_TUSB_MCU == OPT_MCU_SAMG || CFG_TUSB_MCU == OPT_MCU_SAMX7X // SAMG & SAME70 don't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_CDC_0_NOTIF 0x81 @@ -108,6 +108,16 @@ 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_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_0_NOTIF 0x81 #define EPNUM_CDC_0_OUT 0x02 diff --git a/hw/bsp/brtmm90x/boards/mm900evxb/board.h b/hw/bsp/brtmm90x/boards/mm900evxb/board.h index 57936fda5..930cb9d33 100644 --- a/hw/bsp/brtmm90x/boards/mm900evxb/board.h +++ b/hw/bsp/brtmm90x/boards/mm900evxb/board.h @@ -27,20 +27,28 @@ #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 +// UART is on connector CN1. +#define GPIO_UART0_TX 48 // Pin 4 of CN1. +#define GPIO_UART0_RX 49 // Pin 6 of CN1. + +// LED is connected to pins 4 (signal) and 2 (GND) of CN2. +#define GPIO_LED 36 + +// Remote wakeup is wired to pin 40 of CN1. #define GPIO_REMOTE_WAKEUP_PIN 18 + +// USB VBus signal is connected directly to the FT900. #define USBD_VBUS_DTC_PIN 3 +// Enable the Remote Wakeup signalling. #define GPIO_REMOTE_WAKEUP #ifdef __cplusplus diff --git a/hw/bsp/brtmm90x/family.c b/hw/bsp/brtmm90x/family.c index 77a03e909..cc28cb69b 100644 --- a/hw/bsp/brtmm90x/family.c +++ b/hw/bsp/brtmm90x/family.c @@ -31,8 +31,8 @@ #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 @@ -64,12 +64,10 @@ 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 GPIO_LED + gpio_function(GPIO_LED, pad_func_0); /* CN2 connector pin 4 */ + gpio_idrive(GPIO_LED, pad_drive_12mA); + gpio_dir(GPIO_LED, pad_dir_output); #endif sys_enable(sys_device_timer_wdt); @@ -153,14 +151,14 @@ 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); } @@ -173,7 +171,11 @@ int8_t board_ft90x_vbus(void) // Turn LED on or off void board_led_write(bool state) { +#if 0 gpio_write(GPIO_ETH_LED0, state); +#else + gpio_write(GPIO_LED, state); +#endif } // Get the current state of button diff --git a/hw/bsp/brtmm90x/family.mk b/hw/bsp/brtmm90x/family.mk index a476cfc06..f45e27cb5 100644 --- a/hw/bsp/brtmm90x/family.mk +++ b/hw/bsp/brtmm90x/family.mk @@ -3,8 +3,8 @@ 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 @@ -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/src/portable/bridgetek/ft9xx/dcd_ft9xx.c b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c index 080d633fa..50f7018db 100644 --- a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c +++ b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c @@ -47,20 +47,17 @@ //--------------------------------------------------------------------+ // 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); // Static array to store an incoming SETUP request for processing by tinyusb. CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN -static uint8_t _ft90x_setup_packet[8]; +static uint8_t _ft9xx_setup_packet[8]; -// Static array to store one SETUP DATA packet until required by dcd_edpt_xfer. -CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN -static uint8_t _ft90x_ctrl_buf[CFG_TUD_ENDPOINT0_SIZE]; -static uint8_t _ft90x_ctrl_buf_complete; - -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. + 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. @@ -71,24 +68,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. @@ -96,7 +93,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; @@ -111,7 +108,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. @@ -129,7 +126,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; @@ -167,7 +164,7 @@ static uint16_t _ft90x_edpt_xfer_in(uint8_t ep_number, uint8_t *buffer, uint16_t } - xfer_bytes = _ft90x_dusb_in(ep_number, (uint8_t *)buffer, xfer_bytes); + xfer_bytes = _ft9xx_dusb_in(ep_number, (uint8_t *)buffer, xfer_bytes); if (ep_number == USBD_EP_0) { @@ -193,13 +190,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; } @@ -209,7 +206,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; @@ -218,7 +215,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; @@ -274,7 +271,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); @@ -316,7 +313,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; @@ -379,7 +376,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; @@ -436,7 +433,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; @@ -514,11 +511,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); } @@ -527,7 +524,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(); @@ -537,7 +534,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(); @@ -603,18 +600,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. @@ -639,17 +636,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) @@ -677,12 +674,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; } @@ -694,7 +691,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 @@ -709,9 +706,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; } @@ -723,7 +720,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc) 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 + // The total RAM allocated should always be a positive number as this // algorithm should not let it go below zero. for (int i = 1; i < USBD_MAX_ENDPOINT_COUNT; i++) { @@ -735,14 +732,19 @@ 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; } @@ -761,7 +763,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc) //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); + TU_LOG2("FT9xx endpoint setting %x\r\n", ep_reg_data); } else { @@ -777,6 +779,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc) ep_xfer[ep_number].buff_size = ep_buff_size; // 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; @@ -791,7 +794,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 @@ -799,7 +802,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; @@ -809,6 +812,7 @@ 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) { @@ -818,7 +822,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to if (ep_number == USBD_EP_0) { - ep_xfer[USBD_EP_0].dir = dir; + ep_xfer[USBD_EP_0].dir = ep_dir; } else { @@ -827,11 +831,11 @@ 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; @@ -839,26 +843,37 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to // Tell the interrupt handler to signal dcd_event_xfer_complete on completion. ep_xfer[ep_number].valid = 1; } - else + 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_number == USBD_EP_0) && (_ft90x_ctrl_buf_complete)) + if (ep_xfer[ep_number].ready) { - // Pull the received data packet from the packet cache and complete the transfer - // immediately. - memcpy(buffer, _ft90x_ctrl_buf, _ft90x_ctrl_buf_complete); - dcd_event_xfer_complete(BOARD_TUD_RHPORT, TUSB_DIR_OUT, _ft90x_ctrl_buf_complete, XFER_RESULT_SUCCESS, false); + // 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. + // 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 @@ -912,6 +927,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 @@ -920,7 +936,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) // Interrupt handling. -void _ft90x_usbd_ISR(void) +void _ft9xx_usbd_ISR(void) { dcd_int_handler(BOARD_TUD_RHPORT); } @@ -959,7 +975,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 @@ -999,18 +1015,18 @@ void dcd_int_handler(uint8_t rhport) } // 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)); + _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); - // Invalidate cache packet. - _ft90x_ctrl_buf_complete = 0; + // Any SETUP packet will clear the incoming FIFO. + ep_xfer[USBD_EP_0].ready = 0; - // Allow new transfers on the control endpoint. + // Allow new DATA and ACK transfers on the control endpoint. ep_xfer[USBD_EP_0].valid = 0; return; } @@ -1024,35 +1040,28 @@ 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, 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); - // Invalidate cache packet. - _ft90x_ctrl_buf_complete = 0; + // 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 cache upto the maximum packet size for the control endpoint and - // use it later in dcd_edpt_xfer. - xfer_bytes = CFG_TUD_ENDPOINT0_SIZE; - - // Transfer incoming data from an OUT packet to the cache packet. - xfer_bytes = _ft90x_edpt_xfer_out(USBD_EP_0, _ft90x_ctrl_buf, xfer_bytes); - - // Set the size of the cache packet. - _ft90x_ctrl_buf_complete = xfer_bytes; + // 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; } - - // Clear the interrupt that signals a SETUP DATA packet is received. - USBD_EP_SR_REG(USBD_EP_0) = (MASK_USBD_EP0SR_OPRDY); } } else // !(epif & MASK_USBD_EPIF_EP0IRQ) @@ -1072,7 +1081,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); @@ -1080,10 +1088,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, + 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; } @@ -1092,27 +1105,45 @@ void dcd_int_handler(uint8_t rhport) { if (ep_xfer[ep_number].remain_size > 0) { - xfer_bytes = _ft90x_edpt_xfer_in(ep_number, + 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; + } } } } @@ -1121,7 +1152,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; From fe63e30a4408dacc714ad9fcf39cf6fcf7c7d865 Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Wed, 30 Nov 2022 11:46:13 +0000 Subject: [PATCH 04/10] Add FT9xx for cdc_dual_ports Fix handling of interrupt endpoints. i.e. no ZLPs. Fix the assignation of endpoint types. Add button support for MM900evx boards. On board support do not block for UART input. --- .../cdc_dual_ports/src/usb_descriptors.c | 11 ++++--- hw/bsp/brtmm90x/boards/mm900evxb/board.h | 2 ++ hw/bsp/brtmm90x/family.c | 31 +++++++++++++++---- src/portable/bridgetek/ft9xx/dcd_ft9xx.c | 29 +++++++++++------ 4 files changed, 52 insertions(+), 21 deletions(-) diff --git a/examples/device/cdc_dual_ports/src/usb_descriptors.c b/examples/device/cdc_dual_ports/src/usb_descriptors.c index 5a8dea553..4eb8c7c27 100644 --- a/examples/device/cdc_dual_ports/src/usb_descriptors.c +++ b/examples/device/cdc_dual_ports/src/usb_descriptors.c @@ -111,12 +111,13 @@ enum #elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X // FT9XX doesn't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together - #define EPNUM_CDC_NOTIF 0x81 - #define EPNUM_CDC_OUT 0x02 - #define EPNUM_CDC_IN 0x83 + #define EPNUM_CDC_0_NOTIF 0x81 + #define EPNUM_CDC_0_OUT 0x02 + #define EPNUM_CDC_0_IN 0x83 - #define EPNUM_MSC_OUT 0x04 - #define EPNUM_MSC_IN 0x85 + #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 diff --git a/hw/bsp/brtmm90x/boards/mm900evxb/board.h b/hw/bsp/brtmm90x/boards/mm900evxb/board.h index 930cb9d33..76813b116 100644 --- a/hw/bsp/brtmm90x/boards/mm900evxb/board.h +++ b/hw/bsp/brtmm90x/boards/mm900evxb/board.h @@ -41,6 +41,8 @@ // LED is connected to pins 4 (signal) and 2 (GND) of CN2. #define GPIO_LED 36 +// Button is connected to pins 6 (signal) and 2 (GND) of CN2. +#define GPIO_BUTTON 37 // Remote wakeup is wired to pin 40 of CN1. #define GPIO_REMOTE_WAKEUP_PIN 18 diff --git a/hw/bsp/brtmm90x/family.c b/hw/bsp/brtmm90x/family.c index cc28cb69b..8155c0afc 100644 --- a/hw/bsp/brtmm90x/family.c +++ b/hw/bsp/brtmm90x/family.c @@ -49,11 +49,16 @@ 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. +#ifdef GPIO_UART0_TX gpio_function(GPIO_UART0_TX, pad_uart0_txd); /* UART0 TXD */ +#endif +#ifdef GPIO_UART0_RX gpio_function(GPIO_UART0_RX, pad_uart0_rxd); /* UART0 RXD */ +#endif uart_open(UART0, /* Device */ 1, /* Prescaler = 1 */ UART_DIVIDER_19200_BAUD, /* Divider = 1302 */ @@ -65,11 +70,17 @@ void board_init(void) board_uart_write(WELCOME_MSG, sizeof(WELCOME_MSG)); #ifdef GPIO_LED - gpio_function(GPIO_LED, pad_func_0); /* CN2 connector pin 4 */ + gpio_function(GPIO_LED, pad_func_0); gpio_idrive(GPIO_LED, pad_drive_12mA); gpio_dir(GPIO_LED, pad_dir_output); #endif +#ifdef GPIO_BUTTON + gpio_function(GPIO_BUTTON, pad_func_0); + gpio_pull(GPIO_BUTTON, pad_pull_pullup); + gpio_dir(GPIO_BUTTON, pad_dir_input); +#endif + sys_enable(sys_device_timer_wdt); /* Timer A = 1ms */ timer_prescaler(timer_select_a, 1000); @@ -171,9 +182,7 @@ int8_t board_ft9xx_vbus(void) // Turn LED on or off void board_led_write(bool state) { -#if 0 - gpio_write(GPIO_ETH_LED0, state); -#else +#ifdef GPIO_LED gpio_write(GPIO_LED, state); #endif } @@ -182,13 +191,23 @@ void board_led_write(bool state) // a '1' means active (pressed), a '0' means inactive. uint32_t board_button_read(void) { - return 0; + uint32_t state = 0; +#ifdef GPIO_BUTTON + state = gpio_read(GPIO_BUTTON); + state = !state; +#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; + + if (uart_rx_has_data(UART0)) + { + r = uart_readn(UART0, (uint8_t *)buf, len); + } return r; } diff --git a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c index 50f7018db..fabe7910b 100644 --- a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c +++ b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c @@ -48,6 +48,7 @@ // Board code will determine the state of VBUS from USB host. 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. CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN @@ -154,17 +155,24 @@ static uint16_t _ft9xx_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 = _ft9xx_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) { @@ -749,11 +757,11 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc) } // 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) @@ -761,7 +769,7 @@ 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("FT9xx endpoint setting %x\r\n", ep_reg_data); } @@ -858,6 +866,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to // 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); } From 1437ad1dfb5b48169f680253707821bd9751fc65 Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Wed, 30 Nov 2022 12:15:27 +0000 Subject: [PATCH 05/10] Add endpoint definitions for more example projects. --- .../dynamic_configuration/src/usb_descriptors.c | 13 +++++++++++++ examples/device/msc_dual_lun/src/usb_descriptors.c | 6 ++++++ examples/device/uac2_headset/src/usb_descriptors.c | 6 ++++++ examples/device/webusb_serial/src/usb_descriptors.c | 7 +++++++ 4 files changed, 32 insertions(+) diff --git a/examples/device/dynamic_configuration/src/usb_descriptors.c b/examples/device/dynamic_configuration/src/usb_descriptors.c index 457f774d0..092229b99 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 68a671c91..d8dbb5ce3 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 10f5cbd27..07c86b903 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 cafe2c22b..99f5caaf9 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 From d3c4f66d3587f4a733ba974d6ab4f4cb96ffde29 Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Wed, 30 Nov 2022 12:49:15 +0000 Subject: [PATCH 06/10] Fix script issues with paths including spaces from env variable. $(FT90X_TOOLCHAIN) or even $(TOP) may have spaces. Quote to fix. --- hw/bsp/brtmm90x/family.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/bsp/brtmm90x/family.mk b/hw/bsp/brtmm90x/family.mk index f45e27cb5..0ddf47a3a 100644 --- a/hw/bsp/brtmm90x/family.mk +++ b/hw/bsp/brtmm90x/family.mk @@ -8,7 +8,7 @@ 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,7 +16,7 @@ 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. From 8cce9385e20986e0f59f9b1ee54331a09d3193de Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Wed, 30 Nov 2022 16:18:07 +0000 Subject: [PATCH 07/10] More configurable board options --- hw/bsp/brtmm90x/boards/mm900evxb/board.h | 50 +++++++++++---- hw/bsp/brtmm90x/family.c | 80 +++++++++++++----------- 2 files changed, 80 insertions(+), 50 deletions(-) diff --git a/hw/bsp/brtmm90x/boards/mm900evxb/board.h b/hw/bsp/brtmm90x/boards/mm900evxb/board.h index 76813b116..191803ddf 100644 --- a/hw/bsp/brtmm90x/boards/mm900evxb/board.h +++ b/hw/bsp/brtmm90x/boards/mm900evxb/board.h @@ -35,23 +35,47 @@ extern "C" { #endif +#include + +// UART to use on this board. +#ifndef BOARD_UART +#define BOARD_UART UART0 +#endif + // UART is on connector CN1. -#define GPIO_UART0_TX 48 // Pin 4 of CN1. -#define GPIO_UART0_RX 49 // Pin 6 of 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 4 (signal) and 2 (GND) of CN2. -#define GPIO_LED 36 -// Button is connected to pins 6 (signal) and 2 (GND) of CN2. -#define GPIO_BUTTON 37 - -// Remote wakeup is wired to pin 40 of CN1. -#define GPIO_REMOTE_WAKEUP_PIN 18 - -// USB VBus signal is connected directly to the FT900. -#define USBD_VBUS_DTC_PIN 3 +// 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 // Enable the Remote Wakeup signalling. -#define GPIO_REMOTE_WAKEUP +// 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 8155c0afc..3b6b03904 100644 --- a/hw/bsp/brtmm90x/family.c +++ b/hw/bsp/brtmm90x/family.c @@ -35,7 +35,7 @@ int8_t board_ft9xx_vbus(void); // Board specific implementation of VBUS detectio 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); @@ -52,14 +52,14 @@ void board_init(void) // Enable the UART Device. sys_enable(sys_device_uart0); - // Set UART0 GPIO functions to UART0_TXD and UART0_RXD. -#ifdef GPIO_UART0_TX - gpio_function(GPIO_UART0_TX, pad_uart0_txd); /* UART0 TXD */ + // 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 GPIO_UART0_RX - gpio_function(GPIO_UART0_RX, pad_uart0_rxd); /* UART0 RXD */ +#ifdef BOARD_GPIO_UART_RX + gpio_function(BOARD_GPIO_UART_RX, pad_uart0_rxd); /* UART0 RXD */ #endif - uart_open(UART0, /* Device */ + uart_open(BOARD_UART, /* Device */ 1, /* Prescaler = 1 */ UART_DIVIDER_19200_BAUD, /* Divider = 1302 */ uart_data_bits_8, /* No. Data Bits */ @@ -69,16 +69,17 @@ void board_init(void) // Use sizeof to avoid pulling in strlen unnecessarily. board_uart_write(WELCOME_MSG, sizeof(WELCOME_MSG)); -#ifdef GPIO_LED - gpio_function(GPIO_LED, pad_func_0); - gpio_idrive(GPIO_LED, pad_drive_12mA); - gpio_dir(GPIO_LED, 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 GPIO_BUTTON - gpio_function(GPIO_BUTTON, pad_func_0); - gpio_pull(GPIO_BUTTON, pad_pull_pullup); - gpio_dir(GPIO_BUTTON, pad_dir_input); +#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); @@ -91,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(); @@ -126,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)) { } } @@ -171,7 +172,7 @@ void board_pm_ISR(void) #if CFG_TUD_ENABLED int8_t board_ft9xx_vbus(void) { - return gpio_read(USBD_VBUS_DTC_PIN); + return gpio_read(BOARD_USBD_VBUS_DTC_PIN); } #endif @@ -182,8 +183,8 @@ int8_t board_ft9xx_vbus(void) // Turn LED on or off void board_led_write(bool state) { -#ifdef GPIO_LED - gpio_write(GPIO_LED, 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 } @@ -192,9 +193,8 @@ void board_led_write(bool state) uint32_t board_button_read(void) { uint32_t state = 0; -#ifdef GPIO_BUTTON - state = gpio_read(GPIO_BUTTON); - state = !state; +#ifdef BOARD_GPIO_BUTTON + state = (gpio_read(BOARD_GPIO_BUTTON) == BOARD_GPIO_BUTTON_STATE_ACTIVE)?1:0; #endif return state; } @@ -204,10 +204,12 @@ int board_uart_read(uint8_t *buf, int len) { int r = 0; - if (uart_rx_has_data(UART0)) +#ifdef BOARD_UART + if (uart_rx_has_data(BOARD_UART)) { - r = uart_readn(UART0, (uint8_t *)buf, len); + r = uart_readn(BOARD_UART, (uint8_t *)buf, len); } +#endif return r; } @@ -215,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; } From 9f440e5c6946f46d2fa09af1f4c42768ac64ef78 Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Thu, 15 Dec 2022 10:27:49 +0000 Subject: [PATCH 08/10] Update SDK for FT9xx to include 3rdparty sources --- 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 0ea80ceaf..91060164a 160000 --- a/hw/mcu/bridgetek/ft9xx/ft90x-sdk +++ b/hw/mcu/bridgetek/ft9xx/ft90x-sdk @@ -1 +1 @@ -Subproject commit 0ea80ceafdf32e4e496cacc94178417e2ef4bf9c +Subproject commit 91060164afe239fcb394122e8bf9eb24d3194eb1 From 6dd40603f92a04d695b78a3ee6c0276525960aef Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 30 Jan 2023 11:46:52 +0700 Subject: [PATCH 09/10] fix typo --- src/portable/bridgetek/ft9xx/dcd_ft9xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c index f4c9b2b27..efca5bdcb 100644 --- a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c +++ b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c @@ -1023,7 +1023,7 @@ void dcd_int_handler(uint8_t rhport) USBD_EP_SR_REG(USBD_EP_0) = MASK_USBD_EP0SR_STALL; } - // Host has sent a SETUP packet. Recieve this into the SETUP packet store. + // 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. From 63e6aea5ac4aed5a7b405a42c888cec66432ee26 Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Mon, 30 Jan 2023 10:04:34 +0000 Subject: [PATCH 10/10] Removed unrequired header file from debugging. --- hw/bsp/brtmm90x/boards/mm900evxb/board.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/hw/bsp/brtmm90x/boards/mm900evxb/board.h b/hw/bsp/brtmm90x/boards/mm900evxb/board.h index 191803ddf..771779108 100644 --- a/hw/bsp/brtmm90x/boards/mm900evxb/board.h +++ b/hw/bsp/brtmm90x/boards/mm900evxb/board.h @@ -35,8 +35,6 @@ extern "C" { #endif -#include - // UART to use on this board. #ifndef BOARD_UART #define BOARD_UART UART0