From fe63e30a4408dacc714ad9fcf39cf6fcf7c7d865 Mon Sep 17 00:00:00 2001 From: Gordon McNab Date: Wed, 30 Nov 2022 11:46:13 +0000 Subject: [PATCH] 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); }