From 875e645b324082a00072a45ae64a8fcdace7303a Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 24 Mar 2025 23:20:54 +0700 Subject: [PATCH] update hil test to include dual and host for pico/pico2 --- .../dual/host_info_to_device_cdc/src/main.c | 163 +++++++++--------- test/hil/hil_test.py | 22 ++- test/hil/tinyusb.json | 4 +- 3 files changed, 100 insertions(+), 89 deletions(-) diff --git a/examples/dual/host_info_to_device_cdc/src/main.c b/examples/dual/host_info_to_device_cdc/src/main.c index 668808db2..c1017141c 100644 --- a/examples/dual/host_info_to_device_cdc/src/main.c +++ b/examples/dual/host_info_to_device_cdc/src/main.c @@ -70,8 +70,11 @@ enum { static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; static bool is_print[CFG_TUH_DEVICE_MAX+1] = { 0 }; +static tusb_desc_device_t descriptor_device[CFG_TUH_DEVICE_MAX+1]; static void print_utf16(uint16_t *temp_buf, size_t buf_len); +static void print_device_info(uint8_t daddr, const tusb_desc_device_t* desc_device); + void led_blinking_task(void); void cdc_task(void); @@ -135,84 +138,19 @@ void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } -#if 1 -#define cdc_printf(...) \ - do { \ - char _tempbuf[256]; \ - int count = sprintf(_tempbuf, __VA_ARGS__); \ - tud_cdc_write(_tempbuf, (uint32_t) count); \ - tud_cdc_write_flush(); \ - tud_task(); \ - } while(0) -#endif - -//#define cdc_printf printf - -void print_device_info(uint8_t daddr) { - tusb_desc_device_t desc_device; - uint8_t xfer_result = tuh_descriptor_get_device_sync(daddr, &desc_device, 18); - if (XFER_RESULT_SUCCESS != xfer_result) { - tud_cdc_write_str("Failed to get device descriptor\r\n"); +void cdc_task(void) { + if (!tud_cdc_connected()) { + // delay a bit otherwise we can outpace host's terminal. Linux will set LineState (DTR) then Line Coding. + // If we send data before Linux's terminal set Line Coding, it can be ignored --> missing data with hardware test loop + board_delay(10); return; } - // Get String descriptor using Sync API - uint16_t serial[64]; - uint16_t buf[128]; - - cdc_printf("Device %u: ID %04x:%04x SN ", daddr, desc_device.idVendor, desc_device.idProduct); - xfer_result = tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, serial, sizeof(serial)); - if (XFER_RESULT_SUCCESS != xfer_result) { - serial[0] = 'n'; - serial[1] = '/'; - serial[2] = 'a'; - serial[3] = 0; - } - print_utf16(serial, TU_ARRAY_SIZE(serial)); - tud_cdc_write_str("\r\n"); - - cdc_printf("Device Descriptor:\r\n"); - cdc_printf(" bLength %u\r\n" , desc_device.bLength); - cdc_printf(" bDescriptorType %u\r\n" , desc_device.bDescriptorType); - cdc_printf(" bcdUSB %04x\r\n" , desc_device.bcdUSB); - cdc_printf(" bDeviceClass %u\r\n" , desc_device.bDeviceClass); - cdc_printf(" bDeviceSubClass %u\r\n" , desc_device.bDeviceSubClass); - cdc_printf(" bDeviceProtocol %u\r\n" , desc_device.bDeviceProtocol); - cdc_printf(" bMaxPacketSize0 %u\r\n" , desc_device.bMaxPacketSize0); - cdc_printf(" idVendor 0x%04x\r\n" , desc_device.idVendor); - cdc_printf(" idProduct 0x%04x\r\n" , desc_device.idProduct); - cdc_printf(" bcdDevice %04x\r\n" , desc_device.bcdDevice); - - cdc_printf(" iManufacturer %u " , desc_device.iManufacturer); - xfer_result = tuh_descriptor_get_manufacturer_string_sync(daddr, LANGUAGE_ID, buf, sizeof(buf)); - if (XFER_RESULT_SUCCESS == xfer_result ) { - print_utf16(buf, TU_ARRAY_SIZE(buf)); - } - tud_cdc_write_str("\r\n"); - - cdc_printf(" iProduct %u " , desc_device.iProduct); - xfer_result = tuh_descriptor_get_product_string_sync(daddr, LANGUAGE_ID, buf, sizeof(buf)); - if (XFER_RESULT_SUCCESS == xfer_result) { - print_utf16(buf, TU_ARRAY_SIZE(buf)); - } - tud_cdc_write_str("\r\n"); - - cdc_printf(" iSerialNumber %u " , desc_device.iSerialNumber); - tud_cdc_write_str((char*)serial); // serial is already to UTF-8 - tud_cdc_write_str("\r\n"); - - cdc_printf(" bNumConfigurations %u\r\n" , desc_device.bNumConfigurations); -} - -void cdc_task(void) { - if (tud_cdc_connected()) { - for (uint8_t daddr = 1; daddr <= CFG_TUH_DEVICE_MAX; daddr++) { - if (tuh_mounted(daddr)) { - if (is_print[daddr]) { - is_print[daddr] = false; - print_device_info(daddr); - tud_cdc_write_flush(); - } + for (uint8_t daddr = 1; daddr <= CFG_TUH_DEVICE_MAX; daddr++) { + if (tuh_mounted(daddr)) { + if (is_print[daddr]) { + is_print[daddr] = false; + print_device_info(daddr, &descriptor_device[daddr]); } } } @@ -221,6 +159,77 @@ void cdc_task(void) { //--------------------------------------------------------------------+ // Host Get device information //--------------------------------------------------------------------+ +#define cdc_printf(...) \ + do { \ + char _tempbuf[256]; \ + char* _bufptr = _tempbuf; \ + uint32_t count = (uint32_t) sprintf(_tempbuf, __VA_ARGS__); \ + while (count > 0) { \ + uint32_t wr_count = tud_cdc_write(_bufptr, count); \ + count -= wr_count; \ + _bufptr += wr_count; \ + if (count > 0){ \ + tud_task();\ + tud_cdc_write_flush(); \ + } \ + } \ + } while(0) + +static void print_device_info(uint8_t daddr, const tusb_desc_device_t* desc_device) { + // Get String descriptor using Sync API + uint16_t serial[64]; + uint16_t buf[128]; + (void) buf; + + cdc_printf("Device %u: ID %04x:%04x SN ", daddr, desc_device->idVendor, desc_device->idProduct); + uint8_t xfer_result = tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, serial, sizeof(serial)); + if (XFER_RESULT_SUCCESS != xfer_result) { + serial[0] = 'n'; + serial[1] = '/'; + serial[2] = 'a'; + serial[3] = 0; + } + print_utf16(serial, TU_ARRAY_SIZE(serial)); + cdc_printf("\r\n"); + + cdc_printf("Device Descriptor:\r\n"); + cdc_printf(" bLength %u\r\n" , desc_device->bLength); + cdc_printf(" bDescriptorType %u\r\n" , desc_device->bDescriptorType); + cdc_printf(" bcdUSB %04x\r\n" , desc_device->bcdUSB); + cdc_printf(" bDeviceClass %u\r\n" , desc_device->bDeviceClass); + cdc_printf(" bDeviceSubClass %u\r\n" , desc_device->bDeviceSubClass); + cdc_printf(" bDeviceProtocol %u\r\n" , desc_device->bDeviceProtocol); + cdc_printf(" bMaxPacketSize0 %u\r\n" , desc_device->bMaxPacketSize0); + cdc_printf(" idVendor 0x%04x\r\n" , desc_device->idVendor); + cdc_printf(" idProduct 0x%04x\r\n" , desc_device->idProduct); + cdc_printf(" bcdDevice %04x\r\n" , desc_device->bcdDevice); + + cdc_printf(" iManufacturer %u " , desc_device->iManufacturer); + xfer_result = tuh_descriptor_get_manufacturer_string_sync(daddr, LANGUAGE_ID, buf, sizeof(buf)); + if (XFER_RESULT_SUCCESS == xfer_result) { + print_utf16(buf, TU_ARRAY_SIZE(buf)); + } + cdc_printf("\r\n"); + + cdc_printf(" iProduct %u " , desc_device->iProduct); + xfer_result = tuh_descriptor_get_product_string_sync(daddr, LANGUAGE_ID, buf, sizeof(buf)); + if (XFER_RESULT_SUCCESS == xfer_result) { + print_utf16(buf, TU_ARRAY_SIZE(buf)); + } + cdc_printf("\r\n"); + + cdc_printf(" iSerialNumber %u " , desc_device->iSerialNumber); + cdc_printf((char*)serial); // serial is already to UTF-8 + cdc_printf("\r\n"); + + cdc_printf(" bNumConfigurations %u\r\n" , desc_device->bNumConfigurations); +} + +void tuh_enum_descriptor_device_cb(uint8_t daddr, tusb_desc_device_t const* desc_device) { + (void) daddr; + descriptor_device[daddr] = *desc_device; // save device descriptor +} + void tuh_mount_cb(uint8_t daddr) { printf("mounted device %u\r\n", daddr); is_print[daddr] = true; @@ -296,7 +305,5 @@ static void print_utf16(uint16_t *temp_buf, size_t buf_len) { _convert_utf16le_to_utf8(temp_buf + 1, utf16_len, (uint8_t *) temp_buf, sizeof(uint16_t) * buf_len); ((uint8_t*) temp_buf)[utf8_len] = '\0'; - tud_cdc_write(temp_buf, utf8_len); - tud_cdc_write_flush(); - tud_task(); + cdc_printf((char*) temp_buf); } diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index a9f5dc1e1..11b67082c 100755 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -81,7 +81,7 @@ def get_serial_dev(id, vendor_str, product_str, ifnum): return f'/dev/serial/by-id/usb-{vendor_str}_{product_str}_{id}-if{ifnum:02d}' else: # just use id: mostly for cp210x/ftdi flasher - pattern = f'/dev/serial/by-id/usb-*_{id}-if{ifnum:02d}*' + pattern = f'/dev/serial/by-id/usb-*_{id}-if*' port_list = glob.glob(pattern) return port_list[0] @@ -98,18 +98,19 @@ def get_hid_dev(id, vendor_str, product_str, event): def open_serial_dev(port): timeout = ENUM_TIMEOUT ser = None + t_step = 0.1 while timeout: if os.path.exists(port): try: # slight delay since kernel may occupy the port briefly - time.sleep(0.5) - timeout = timeout - 0.5 + time.sleep(t_step) + timeout = timeout - t_step ser = serial.Serial(port, baudrate=115200, timeout=5) break except serial.SerialException: pass - time.sleep(0.5) - timeout = timeout - 0.5 + time.sleep(t_step) + timeout = timeout - t_step assert timeout, f'Cannot open port f{port}' if os.path.exists(port) else f'Port {port} not existed' return ser @@ -202,14 +203,14 @@ def reset_stflash(board): def flash_openocd(board, firmware): flasher = board['flasher'] ret = run_cmd(f'openocd -c "tcl_port disabled" -c "gdb_port disabled" -c "adapter serial {flasher["uid"]}" ' - f'{flasher["args"]} -c init -c halt -c "program {firmware}.elf verify" -c reset -c exit') + f'{flasher["args"]} -c "init; halt; program {firmware}.elf verify; reset; exit"') return ret def reset_openocd(board): flasher = board['flasher'] ret = run_cmd(f'openocd -c "tcl_port disabled" -c "gdb_port disabled" -c "adapter serial {flasher["uid"]}" ' - f'{flasher["args"]} -c "reset exit"') + f'{flasher["args"]} -c "init; reset run; exit"') return ret @@ -310,6 +311,9 @@ def test_dual_host_info_to_device_cdc(board): assert False, 'No data from device' lines = data.decode('utf-8').splitlines() + if verbose: + print('\n'.join(lines)) + enum_dev_sn = [] for l in lines: vid_pid_sn = re.search(r'ID ([0-9a-fA-F]+):([0-9a-fA-F]+) SN (\w+)', l) @@ -577,10 +581,10 @@ def test_board(board): print(f' {e}') else: print() - print(f' Test failed: {e}, retry {i+1}') + print(f' Test failed: {e}, retry {i+2}/{max_rety}') time.sleep(1) else: - print(f'Flashing failed, retry {i+1}') + print(f'Flashing failed, retry {i+2}/{max_rety}') time.sleep(1) if ret.returncode != 0: diff --git a/test/hil/tinyusb.json b/test/hil/tinyusb.json index c2bbdf5a3..e702ffe9f 100644 --- a/test/hil/tinyusb.json +++ b/test/hil/tinyusb.json @@ -99,7 +99,7 @@ "name": "raspberry_pi_pico", "uid": "E6614C311B764A37", "tests": { - "device": true, "host": false, "dual": false, + "device": true, "host": true, "dual": true, "dev_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2002470"}] }, "flasher": { @@ -112,7 +112,7 @@ "name": "raspberry_pi_pico2", "uid": "560AE75E1C7152C9", "tests": { - "device": true, "host": false, "dual": false, + "device": true, "host": true, "dual": true, "dev_attached": [{"vid_pid": "1a86_55d4", "serial": "533D004242"}] }, "flasher": {