From fdb99e2229d4210a4a5c8f0bd7321393d23936ca Mon Sep 17 00:00:00 2001 From: Petteri Aimonen Date: Mon, 2 Dec 2024 13:54:57 +0200 Subject: [PATCH 1/3] ZuluSCSIv1.1 (GD32F205): Fix USB serial port logging on Windows Previously USB serial number was disabled to save RAM, but the length was left as 12. This confused Windows and caused USB enumeration to fail. Changed serial number to fake "1234". This avoids Windows from guessing a new COM port number every time the device is changed between ports. --- .../gd32_cdc_acm_core.c | 23 ++++++++++++-- .../usbd_msc_core.c | 30 +++++++++++++++---- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/lib/ZuluSCSI_platform_GD32F205/gd32_cdc_acm_core.c b/lib/ZuluSCSI_platform_GD32F205/gd32_cdc_acm_core.c index 448d0db3..15a34870 100644 --- a/lib/ZuluSCSI_platform_GD32F205/gd32_cdc_acm_core.c +++ b/lib/ZuluSCSI_platform_GD32F205/gd32_cdc_acm_core.c @@ -232,15 +232,32 @@ static const usb_desc_str product_string = .unicode_string = {'Z', 'u', 'l', 'u', 'S', 'C', 'S', 'I'} }; -/* USBD serial string */ +#ifdef USB_ENABLE_SERIALNUMBER +/* USBD serial string + * This gets set by serial_string_get() in GD32 SPL usbd_enum.c */ +static usb_desc_str serial_string = +{ + .header = + { + .bLength = USB_STRING_LEN(12U), + .bDescriptorType = USB_DESCTYPE_STR, + } +}; +#else +/* Save some RAM by disabling the serial number. + * Note that contents must not have null bytes or Windows gets confused + * Having non-empty fake serial number avoids Windows recreating the + * device every time it moves between USB ports. */ static const usb_desc_str serial_string = { .header = { - .bLength = USB_STRING_LEN(12), + .bLength = USB_STRING_LEN(4U), .bDescriptorType = USB_DESCTYPE_STR, - } + }, + .unicode_string = {'1', '2', '3', '4'} }; +#endif /* USB string descriptor set */ void *const gd32_usbd_cdc_strings[] = diff --git a/lib/ZuluSCSI_platform_GD32F205/usbd_msc_core.c b/lib/ZuluSCSI_platform_GD32F205/usbd_msc_core.c index 2ec5d212..9b8ba90f 100644 --- a/lib/ZuluSCSI_platform_GD32F205/usbd_msc_core.c +++ b/lib/ZuluSCSI_platform_GD32F205/usbd_msc_core.c @@ -166,14 +166,32 @@ static __ALIGN_BEGIN const usb_desc_str product_string __ALIGN_END = { .unicode_string = {'G', 'D', '3', '2', '-', 'U', 'S', 'B', '_', 'M', 'S', 'C'} }; -/* USBD serial string */ -static __ALIGN_BEGIN const usb_desc_str serial_string __ALIGN_END = { +#ifdef USB_ENABLE_SERIALNUMBER +/* USBD serial string + * This gets set by serial_string_get() in GD32 SPL usbd_enum.c */ +static usb_desc_str serial_string = +{ .header = - { - .bLength = USB_STRING_LEN(12U), - .bDescriptorType = USB_DESCTYPE_STR, - } + { + .bLength = USB_STRING_LEN(12U), + .bDescriptorType = USB_DESCTYPE_STR, + } +}; +#else +/* Save some RAM by disabling the serial number. + * Note that contents must not have null bytes or Windows gets confused + * Having non-empty fake serial number avoids Windows recreating the + * device every time it moves between USB ports. */ +static const usb_desc_str serial_string = +{ + .header = + { + .bLength = USB_STRING_LEN(4U), + .bDescriptorType = USB_DESCTYPE_STR, + }, + .unicode_string = {'1', '2', '3', '4'} }; +#endif /* USB string descriptor */ void *const usbd_msc_strings[] = { From f68e827c4086c5f20b2b8777cc0df2d21528697b Mon Sep 17 00:00:00 2001 From: Petteri Aimonen Date: Mon, 2 Dec 2024 14:25:36 +0200 Subject: [PATCH 2/3] GD32F205: Avoid including USB in bootloader usb_log_poll() was bringing in unnecessary code, causing bootloader to be larger than needed and exceed 32 kB. --- lib/ZuluSCSI_platform_GD32F205/ZuluSCSI_platform.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/ZuluSCSI_platform_GD32F205/ZuluSCSI_platform.cpp b/lib/ZuluSCSI_platform_GD32F205/ZuluSCSI_platform.cpp index 12a1d87e..671ddafd 100644 --- a/lib/ZuluSCSI_platform_GD32F205/ZuluSCSI_platform.cpp +++ b/lib/ZuluSCSI_platform_GD32F205/ZuluSCSI_platform.cpp @@ -46,6 +46,10 @@ bool g_moved_select_in = false; // hw_config.cpp c functions #include "platform_hw_config.h" +// usb_log_poll() is called through function pointer to +// avoid including USB in SD card bootloader. +static void (*g_usb_log_poll_func)(void); +static void usb_log_poll(); /*************************/ @@ -394,6 +398,7 @@ void platform_late_init() { // Initialize usb for CDC serial output usb_serial_init(); + g_usb_log_poll_func = &usb_log_poll; logmsg("Platform: ", g_platform_name); logmsg("FW Version: ", g_log_firmwareversion); @@ -615,7 +620,7 @@ void show_hardfault(uint32_t *sp) while (1) { - usb_log_poll(); + if (g_usb_log_poll_func) g_usb_log_poll_func(); // Flash the crash address on the LED // Short pulse means 0, long pulse means 1 int base_delay = 1000; @@ -688,7 +693,7 @@ void __assert_func(const char *file, int line, const char *func, const char *exp while(1) { - usb_log_poll(); + if (g_usb_log_poll_func) g_usb_log_poll_func(); LED_OFF(); for (int j = 0; j < 1000; j++) delay_ns(100000); LED_ON(); From b90552152310fd66ad57e24f9eeebf7b13691844 Mon Sep 17 00:00:00 2001 From: Petteri Aimonen Date: Mon, 2 Dec 2024 14:26:47 +0200 Subject: [PATCH 3/3] GD32F205: Fix occassional problems with USB serial port Return proper error on unknown requests. Don't hang on received data. --- lib/ZuluSCSI_platform_GD32F205/gd32_cdc_acm_core.c | 2 +- lib/ZuluSCSI_platform_GD32F205/usb_serial.cpp | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/ZuluSCSI_platform_GD32F205/gd32_cdc_acm_core.c b/lib/ZuluSCSI_platform_GD32F205/gd32_cdc_acm_core.c index 15a34870..74e0a580 100644 --- a/lib/ZuluSCSI_platform_GD32F205/gd32_cdc_acm_core.c +++ b/lib/ZuluSCSI_platform_GD32F205/gd32_cdc_acm_core.c @@ -469,7 +469,7 @@ static uint8_t cdc_acm_req (usb_dev *udev, usb_req *req) break; default: - break; + return REQ_NOTSUPP; } return USBD_OK; diff --git a/lib/ZuluSCSI_platform_GD32F205/usb_serial.cpp b/lib/ZuluSCSI_platform_GD32F205/usb_serial.cpp index b27d833d..fd8b615b 100644 --- a/lib/ZuluSCSI_platform_GD32F205/usb_serial.cpp +++ b/lib/ZuluSCSI_platform_GD32F205/usb_serial.cpp @@ -52,6 +52,15 @@ bool usb_serial_ready(void) // check that (our) serial is the currently active class if ((USBD_CONFIGURED == cdc_acm.dev.cur_status) && (cdc_acm.dev.desc == &gd32_cdc_desc)) { + gd32_usb_cdc_handler *cdc = (gd32_usb_cdc_handler *)cdc_acm.dev.class_data[CDC_COM_INTERFACE]; + if (cdc->packet_receive) + { + // Discard any received data. + // Otherwise it queues up on the host side and can cause the port to hang. + cdc->packet_receive = 0; + gd32_cdc_acm_data_receive(&cdc_acm); + } + if (1U == gd32_cdc_acm_check_ready(&cdc_acm)) { return true;