From 8f8990aa58c35d5101f880fb59b7fb3d0d80710a Mon Sep 17 00:00:00 2001 From: TravisRo Date: Thu, 16 Jun 2022 12:20:09 -0600 Subject: [PATCH] Fix compile errors for high speed devices Added high speed descriptors though I'm not sure if the CH341 driver will work as a high speed device. Changed "buffer size" define names in tusb_config to clarify whether we are specifying fifo buffer sizes or endpoint max packet sizes --- .../device/ch341_serial/src/tusb_config.h | 34 +++------- .../device/ch341_serial/src/usb_descriptors.c | 66 +++++++++++++++++-- src/class/ch341/ch341_device.c | 28 ++++---- src/class/ch341/ch341_device.h | 17 +++-- 4 files changed, 92 insertions(+), 53 deletions(-) diff --git a/examples/device/ch341_serial/src/tusb_config.h b/examples/device/ch341_serial/src/tusb_config.h index ad8fcf2c7..ad5a3ce04 100644 --- a/examples/device/ch341_serial/src/tusb_config.h +++ b/examples/device/ch341_serial/src/tusb_config.h @@ -65,28 +65,13 @@ // Enable Device stack #define CFG_TUD_ENABLED 1 -// CH340G is a full speed USB device. -#define CFG_TUD_MAX_SPEED TUSB_SPEED_FULL +// Default is max speed that hardware controller could support with on-chip PHY +#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED #ifndef CFG_TUSB_RHPORT0_MODE #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE | OPT_MODE_FULL_SPEED #endif -/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. - * Tinyusb use follows macros to declare transferring memory so that they can be put - * into those specific section. - * e.g - * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) - * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) - */ -#ifndef CFG_TUSB_MEM_SECTION -#define CFG_TUSB_MEM_SECTION -#endif - -#ifndef CFG_TUSB_MEM_ALIGN -#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) -#endif - //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- @@ -102,14 +87,15 @@ #define CFG_TUD_MIDI 0 #define CFG_TUD_VENDOR 0 #define CFG_TUD_CH341 1 - -// CDC FIFO size of TX and RX -#define CFG_TUD_CH341_TX_BUFSIZE (64) -#define CFG_TUD_CH341_RX_BUFSIZE (64) -#define CFG_TUD_CH341_TXNOTIFY_BUFSIZE (8) -// CDC Endpoint transfer buffer size, more is faster -#define CFG_TUD_CH341_EP_BUFSIZE (64) +// CH341 Endpoint max packet sizes (should not change) +#define CFG_TUD_CH341_EP_RX_MAX_PACKET (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CH341_EP_TX_MAX_PACKET CFG_TUD_CH341_EP_RX_MAX_PACKET +#define CFG_TUD_CH341_EP_TXNOTIFY_MAX_PACKET (8) + +// CH341 buffer size for TX and RX data (must be an interval of max packet size) +// more is faster +#define CFG_TUD_CH341_FIFO_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #ifdef __cplusplus } diff --git a/examples/device/ch341_serial/src/usb_descriptors.c b/examples/device/ch341_serial/src/usb_descriptors.c index 777d294c3..ea44e9412 100644 --- a/examples/device/ch341_serial/src/usb_descriptors.c +++ b/examples/device/ch341_serial/src/usb_descriptors.c @@ -30,7 +30,6 @@ #define USB_VID 0x1A86 // CH341 serial converter #define USB_PID 0x7523 -#define USB_BCD 0x0110 //--------------------------------------------------------------------+ // Generic Descriptor Templates @@ -52,8 +51,13 @@ tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, - .bcdUSB = USB_BCD, - +#if TUD_OPT_HIGH_SPEED + // atleast 0x0200 required for HS + .bcdUSB = 0x0200, +#else + // this is what's in a genuine CH340G's descriptor + .bcdUSB = 0x0110, +#endif .bDeviceClass = 0xFF, .bDeviceSubClass = 0x00, .bDeviceProtocol = 0x00, @@ -115,14 +119,62 @@ uint8_t const desc_fs_configuration[] = // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x80, 100), TUD_GEN_INTERFACE_DESCRIPTOR(0, 0, 3, 0xFF, 1, 2 , 0), - TUD_GEN_BULK_EP_DESCRIPTOR(EPNUM_CH341_0_IN, CFG_TUD_CH341_EP_BUFSIZE), - TUD_GEN_BULK_EP_DESCRIPTOR(EPNUM_CH341_0_OUT, CFG_TUD_CH341_EP_BUFSIZE), + TUD_GEN_BULK_EP_DESCRIPTOR(EPNUM_CH341_0_IN, CFG_TUD_CH341_EP_TX_MAX_PACKET), + TUD_GEN_BULK_EP_DESCRIPTOR(EPNUM_CH341_0_OUT, CFG_TUD_CH341_EP_RX_MAX_PACKET), TUD_GEN_INTERRUPT_EP_DESCRIPTOR(EPNUM_CH341_0_NOTIF, 8, 1) }; #if TUD_OPT_HIGH_SPEED -#error "High speed not supported" -// TODO: Im not sure if the ch341 windows driver would allow high speed descriptors. Its certainly possible but unlikely + +// TEST: Im not sure if the ch341 windows driver will allow high speed descriptors. +// Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration + +uint8_t const desc_hs_configuration[] = +{ + // Config number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x80, 100), + TUD_GEN_INTERFACE_DESCRIPTOR(0, 0, 3, 0xFF, 1, 2 , 0), + TUD_GEN_BULK_EP_DESCRIPTOR(EPNUM_CH341_0_IN, CFG_TUD_CH341_EP_TX_MAX_PACKET), + TUD_GEN_BULK_EP_DESCRIPTOR(EPNUM_CH341_0_OUT, CFG_TUD_CH341_EP_RX_MAX_PACKET), + TUD_GEN_INTERRUPT_EP_DESCRIPTOR(EPNUM_CH341_0_NOTIF, 8, 1) +}; + +// device qualifier is mostly similar to device descriptor since we don't change configuration based on speed +tusb_desc_device_qualifier_t const desc_device_qualifier = +{ + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = 0x0200, + + .bDeviceClass = 0xFF, + .bDeviceSubClass = 0x00, + .bDeviceProtocol = 0x00, + + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + .bNumConfigurations = 0x01, + .bReserved = 0x00 +}; + +// Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. +// device_qualifier descriptor describes information about a high-speed capable device that would +// change if the device were operating at the other speed. If not highspeed capable stall this request. +uint8_t const* tud_descriptor_device_qualifier_cb(void) +{ + return (uint8_t const*) &desc_device_qualifier; +} + +// Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete +// Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa +uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index) +{ + (void) index; // for multiple configurations + + // if link speed is high return fullspeed config, and vice versa + return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration; +} + #endif // highspeed // Invoked when received GET CONFIGURATION DESCRIPTOR diff --git a/src/class/ch341/ch341_device.c b/src/class/ch341/ch341_device.c index c56cb7e4c..fd93abd0c 100644 --- a/src/class/ch341/ch341_device.c +++ b/src/class/ch341/ch341_device.c @@ -151,9 +151,9 @@ typedef struct tu_fifo_t tx_ff; tu_fifo_t txnotify_ff; - uint8_t rx_ff_buf[CFG_TUD_CH341_RX_BUFSIZE]; - uint8_t tx_ff_buf[CFG_TUD_CH341_TX_BUFSIZE]; - uint8_t txnotify_ff_buf[CFG_TUD_CH341_TXNOTIFY_BUFSIZE]; + uint8_t rx_ff_buf[CFG_TUD_CH341_FIFO_SIZE]; + uint8_t tx_ff_buf[CFG_TUD_CH341_FIFO_SIZE]; + uint8_t txnotify_ff_buf[CFG_TUD_CH341_EP_TXNOTIFY_MAX_PACKET]; #if CFG_FIFO_MUTEX osal_mutex_def_t rx_ff_mutex; @@ -168,8 +168,8 @@ typedef struct CFG_TUSB_MEM_ALIGN uint8_t ep0_in_buf[4]; // Endpoint Transfer buffer - CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_CH341_EP_BUFSIZE]; - CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_CH341_EP_BUFSIZE]; + CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_CH341_EP_RX_MAX_PACKET]; + CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_CH341_EP_TX_MAX_PACKET]; uint8_t register_data[REG_DIDX_MAX]; @@ -514,7 +514,7 @@ uint32_t tud_ch341_n_write(uint8_t itf, void const* buffer, uint32_t bufsize) uint16_t ret = tu_fifo_write_n(&p_ch341->tx_ff, buffer, bufsize); // flush if queue more than packet size - if (tu_fifo_count(&p_ch341->tx_ff) >= CFG_TUD_CH341_EP_BUFSIZE ) + if (tu_fifo_count(&p_ch341->tx_ff) >= sizeof(p_ch341->epin_buf)) { tud_ch341_n_write_flush(itf); } @@ -632,16 +632,10 @@ void ch341d_init(void) // Config RX fifo tu_fifo_config(&p_ch341->rx_ff, p_ch341->rx_ff_buf, TU_ARRAY_SIZE(p_ch341->rx_ff_buf), 1, false); - - // Config TX fifo as overwritable at initialization and will be changed to non-overwritable - // if terminal supports DTR bit. Without DTR we do not know if data is actually polled by terminal. - // In this way, the most current data is prioritized. - tu_fifo_config(&p_ch341->tx_ff, p_ch341->tx_ff_buf, TU_ARRAY_SIZE(p_ch341->tx_ff_buf), 1, true); - - // Config TX notify fifo as overwritable at initialization and will be changed to non-overwritable - // if terminal supports DTR bit. Without DTR we do not know if data is actually polled by terminal. - // In this way, the most current data is prioritized. - tu_fifo_config(&p_ch341->txnotify_ff, p_ch341->txnotify_ff_buf, TU_ARRAY_SIZE(p_ch341->txnotify_ff_buf), 1, true); + // Config TX fifo + tu_fifo_config(&p_ch341->tx_ff, p_ch341->tx_ff_buf, TU_ARRAY_SIZE(p_ch341->tx_ff_buf), 1, false); + // Config TX NOTIFY fifo + tu_fifo_config(&p_ch341->txnotify_ff, p_ch341->txnotify_ff_buf, TU_ARRAY_SIZE(p_ch341->txnotify_ff_buf), 1, false); #if CFG_FIFO_MUTEX tu_fifo_config_mutex(&p_ch341->rx_ff, NULL, osal_mutex_create(&p_ch341->rx_ff_mutex)); @@ -896,7 +890,7 @@ bool ch341d_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 { // If there is no data left, a ZLP should be sent if // xferred_bytes is multiple of EP Packet size and not zero - if (!tu_fifo_count(&p_ch341->tx_ff) && xferred_bytes && (0 == (xferred_bytes & (CFG_TUD_CH341_EP_BUFSIZE-1))) ) + if (!tu_fifo_count(&p_ch341->tx_ff) && xferred_bytes && (0 == (xferred_bytes & (CFG_TUD_CH341_EP_TX_MAX_PACKET-1))) ) { if ( usbd_edpt_claim(rhport, p_ch341->ep_in) ) { diff --git a/src/class/ch341/ch341_device.h b/src/class/ch341/ch341_device.h index c5fd6b0a6..1bda60746 100644 --- a/src/class/ch341/ch341_device.h +++ b/src/class/ch341/ch341_device.h @@ -41,13 +41,20 @@ //--------------------------------------------------------------------+ // Class Driver Configuration //--------------------------------------------------------------------+ -#if !defined(CFG_TUD_CH341_EP_BUFSIZE) && defined(CFG_TUD_CH341_EPSIZE) - #warning CFG_TUD_CH341_EPSIZE is renamed to CFG_TUD_CH341_EP_BUFSIZE, please update to use the new name - #define CFG_TUD_CH341_EP_BUFSIZE CFG_TUD_CH341_EPSIZE +#ifndef CFG_TUD_CH341_EP_RX_MAX_PACKET + #define CFG_TUD_CH341_EP_RX_MAX_PACKET (TUD_OPT_HIGH_SPEED ? 512 : 64) #endif -#ifndef CFG_TUD_CH341_EP_BUFSIZE - #define CFG_TUD_CH341_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#ifndef CFG_TUD_CH341_EP_TX_MAX_PACKET + #define CFG_TUD_CH341_EP_TX_MAX_PACKET CFG_TUD_CH341_EP_RX_MAX_PACKET +#endif + +#ifndef CFG_TUD_CH341_EP_TXNOTIFY_MAX_PACKET + #define CFG_TUD_CH341_EP_TXNOTIFY_MAX_PACKET (8) +#endif + +#ifndef CFG_TUD_CH341_FIFO_SIZE + #define CFG_TUD_CH341_FIFO_SIZE CFG_TUD_CH341_EP_RX_MAX_PACKET #endif #ifdef __cplusplus