summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhathach <[email protected]>2026-03-17 14:58:45 +0700
committerhathach <[email protected]>2026-03-17 14:58:45 +0700
commita3b2b4217630eea3f514ee042ee399e9ee397b8a (patch)
tree1d54c86d222a34aca5edc9e58b858577f04319e8
parent151a5ad1984a9706aedbe9d26411c33202760007 (diff)
add hil host cdc test
-rw-r--r--AGENTS.md1
-rw-r--r--hw/bsp/stm32h7/boards/stm32h743eval/board.h20
-rw-r--r--hw/bsp/stm32h7/family.c20
-rwxr-xr-xtest/hil/hil_test.py75
-rw-r--r--test/hil/tinyusb.json16
5 files changed, 117 insertions, 15 deletions
diff --git a/AGENTS.md b/AGENTS.md
index 4e510b01e..d491f94f1 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -27,7 +27,6 @@ information that does not match the info here.
## Build Examples
Choose ONE of these approaches:
-
**Option 1: Individual Example with CMake and Ninja (RECOMMENDED)**
```bash
diff --git a/hw/bsp/stm32h7/boards/stm32h743eval/board.h b/hw/bsp/stm32h7/boards/stm32h743eval/board.h
index d2f61a5ce..3914d7aac 100644
--- a/hw/bsp/stm32h7/boards/stm32h743eval/board.h
+++ b/hw/bsp/stm32h7/boards/stm32h743eval/board.h
@@ -205,13 +205,25 @@ static int32_t board_i2c_deinit(void) {
}
static int32_t i2c_readreg(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length) {
- TU_ASSERT (HAL_OK == HAL_I2C_Mem_Read(&i2c_handle, DevAddr, Reg, I2C_MEMADD_SIZE_8BIT, pData, Length, 10000));
- return 0;
+ for (int retry = 0; retry < 3; retry++) {
+ if (HAL_OK == HAL_I2C_Mem_Read(&i2c_handle, DevAddr, Reg, I2C_MEMADD_SIZE_8BIT, pData, Length, 10000)) {
+ return 0;
+ }
+ HAL_Delay(10);
+ }
+ TU_ASSERT(0);
+ return -1;
}
static int32_t i2c_writereg(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length) {
- TU_ASSERT(HAL_OK == HAL_I2C_Mem_Write(&i2c_handle, DevAddr, Reg, I2C_MEMADD_SIZE_8BIT, pData, Length, 10000));
- return 0;
+ for (int retry = 0; retry < 3; retry++) {
+ if (HAL_OK == HAL_I2C_Mem_Write(&i2c_handle, DevAddr, Reg, I2C_MEMADD_SIZE_8BIT, pData, Length, 10000)) {
+ return 0;
+ }
+ HAL_Delay(10);
+ }
+ TU_ASSERT(0);
+ return -1;
}
static int32_t i2c_get_tick(void) {
diff --git a/hw/bsp/stm32h7/family.c b/hw/bsp/stm32h7/family.c
index c94c2e755..a95674217 100644
--- a/hw/bsp/stm32h7/family.c
+++ b/hw/bsp/stm32h7/family.c
@@ -275,9 +275,25 @@ size_t board_get_unique_id(uint8_t id[], size_t max_len) {
}
int board_uart_read(uint8_t *buf, int len) {
- (void) buf;
- (void) len;
+#ifdef UART_DEV
+ int count = 0;
+ // clear overrun error if any
+ if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_ORE)) {
+ __HAL_UART_CLEAR_FLAG(&UartHandle, UART_CLEAR_OREF);
+ }
+ for (int i = 0; i < len; i++) {
+ if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE)) {
+ buf[i] = (uint8_t) UartHandle.Instance->RDR;
+ count++;
+ } else {
+ break;
+ }
+ }
+ return count;
+#else
+ (void) buf; (void) len;
return 0;
+#endif
}
int board_uart_write(void const *buf, int len) {
diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py
index 7cffd2da8..65585d929 100755
--- a/test/hil/hil_test.py
+++ b/test/hil/hil_test.py
@@ -416,6 +416,80 @@ def test_host_device_info(board):
return 0
+def test_host_cdc_msc_hid(board):
+ flasher = board['flasher']
+ cdc_devs = [d for d in board['tests'].get('dev_attached', []) if d.get('is_cdc')]
+ if not cdc_devs:
+ return
+
+ port = get_serial_dev(flasher["uid"], None, None, 0)
+ ser = open_serial_dev(port)
+ ser.timeout = 0.1
+
+ # reset device to catch mount messages
+ ret = globals()[f'reset_{flasher["name"].lower()}'](board)
+ assert ret.returncode == 0, 'Failed to reset device'
+
+ # Wait for CDC mounted message
+ data = b''
+ timeout = ENUM_TIMEOUT
+ while timeout > 0:
+ new_data = ser.read(ser.in_waiting or 1)
+ if new_data:
+ data += new_data
+ if b'CDC Interface is mounted' in data:
+ break
+ time.sleep(0.1)
+ timeout -= 0.1
+ assert b'CDC Interface is mounted' in data, 'CDC device not mounted on host'
+
+ # Lookup serial chip name from vid_pid
+ vid_pid_name = {
+ '0403_6001': 'FTDI', '0403_6010': 'FTDI', '0403_6011': 'FTDI', '0403_6014': 'FTDI',
+ '10c4_ea60': 'CP210x', '10c4_ea70': 'CP210x',
+ '067b_2303': 'PL2303', '067b_23a3': 'PL2303',
+ '1a86_7523': 'CH340', '1a86_7522': 'CH340',
+ '1a86_55d3': 'CH9102', '1a86_55d4': 'CH9102',
+ }
+ dev = cdc_devs[0]
+ chip_name = vid_pid_name.get(dev['vid_pid'], dev['vid_pid'])
+ for l in data.decode('utf-8', errors='ignore').splitlines():
+ if 'CDC Interface is mounted' in l:
+ print(f'\r\n {chip_name}: {l} ', end='')
+
+ # CDC echo test via flasher serial
+ time.sleep(2)
+ ser.reset_input_buffer()
+
+ def rand_ascii(length):
+ return "".join(random.choices(string.ascii_letters + string.digits, k=length)).encode("ascii")
+
+ sizes = [8, 32, 64, 128]
+ for size in sizes:
+ test_data = rand_ascii(size)
+ ser.reset_input_buffer()
+
+ # Write byte-by-byte with delay to avoid UART overrun
+ for b in test_data:
+ ser.write(bytes([b]))
+ ser.flush()
+ time.sleep(0.001)
+
+ # Read echo back with timeout
+ echo = b''
+ t = 5.0
+ while t > 0 and len(echo) < size:
+ rd = ser.read(max(1, ser.in_waiting))
+ if rd:
+ echo += rd
+ time.sleep(0.05)
+ t -= 0.05
+ assert echo == test_data, (f'CDC echo wrong data ({size} bytes):\n'
+ f' expected: {test_data}\n received: {echo}')
+
+ ser.close()
+
+
# -------------------------------------------------------------
# Tests: device
# -------------------------------------------------------------
@@ -763,6 +837,7 @@ dual_tests = [
]
host_test = [
+ 'host/cdc_msc_hid',
'host/device_info',
]
diff --git a/test/hil/tinyusb.json b/test/hil/tinyusb.json
index e8449ba74..eaf60c6ce 100644
--- a/test/hil/tinyusb.json
+++ b/test/hil/tinyusb.json
@@ -8,7 +8,7 @@
},
"tests": {
"only": ["device/cdc_msc_freertos", "device/hid_composite_freertos", "host/device_info"],
- "dev_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2002427"}]
+ "dev_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2002427", "is_cdc": true}]
},
"flasher": {
"name": "esptool",
@@ -26,7 +26,7 @@
},
"tests": {
"only": ["device/cdc_msc_freertos", "device/hid_composite_freertos", "host/device_info"],
- "dev_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2005402"}]
+ "dev_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2005402", "is_cdc": true}]
},
"flasher": {
"name": "esptool",
@@ -67,7 +67,7 @@
},
"tests": {
"device": true, "host": false, "dual": true,
- "dev_attached": [{"vid_pid": "067b_2303", "serial": "0"}],
+ "dev_attached": [{"vid_pid": "067b_2303", "serial": "0", "is_cdc": true}],
"comment": "pl23x"
},
"flasher": {
@@ -93,7 +93,7 @@
"uid": "BAE96FB95AFA6DBB8F00005002001200",
"tests": {
"device": true, "host": true, "dual": true,
- "dev_attached": [{"vid_pid": "10c4_ea60", "serial": "0001"}],
+ "dev_attached": [{"vid_pid": "10c4_ea60", "serial": "0001", "is_cdc": true}],
"comment": "cp2102"
},
"flasher": {
@@ -136,7 +136,7 @@
},
"tests": {
"device": true, "host": true, "dual": true,
- "dev_attached": [{"vid_pid": "1a86_7523", "serial": "0"}],
+ "dev_attached": [{"vid_pid": "1a86_7523", "serial": "0", "is_cdc": true}],
"comment": "ch34x"
},
"flasher": {
@@ -150,7 +150,7 @@
"uid": "E6614C311B764A37",
"tests": {
"device": false, "host": true, "dual": false,
- "dev_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2023934"}]
+ "dev_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2023934", "is_cdc": true}]
},
"flasher": {
"name": "openocd",
@@ -167,7 +167,7 @@
},
"tests": {
"device": true, "host": true, "dual": true,
- "dev_attached": [{"vid_pid": "1a86_55d4", "serial": "533D004242"}]
+ "dev_attached": [{"vid_pid": "1a86_55d4", "serial": "533D004242", "is_cdc": true}]
},
"flasher": {
"name": "openocd",
@@ -193,7 +193,7 @@
},
"tests": {
"device": true, "host": true, "dual": false,
- "dev_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2003414"}]
+ "dev_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2003414", "is_cdc": true}]
},
"flasher": {
"name": "jlink",