update host/device_info to build with freertos for espressif board. Add hil test for host/device_info
This commit is contained in:
@@ -1,3 +1,6 @@
|
|||||||
|
mcu:ESP32S2
|
||||||
|
mcu:ESP32S3
|
||||||
|
mcu:ESP32P4
|
||||||
mcu:KINETIS_KL
|
mcu:KINETIS_KL
|
||||||
mcu:LPC175X_6X
|
mcu:LPC175X_6X
|
||||||
mcu:LPC177X_8X
|
mcu:LPC177X_8X
|
||||||
|
4
examples/host/device_info/src/CMakeLists.txt
Normal file
4
examples/host/device_info/src/CMakeLists.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# This file is for ESP-IDF only
|
||||||
|
idf_component_register(SRCS "main.c"
|
||||||
|
INCLUDE_DIRS "."
|
||||||
|
REQUIRES boards tinyusb_src)
|
@@ -24,7 +24,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Host example will get device descriptors of attached devices and print it out via uart/rtt (logger) as follows:
|
/* Host example will get device descriptors of attached devices and print it out via uart/rtt (logger) as follows:
|
||||||
* Device 1: ID 046d:c52f
|
* Device 1: ID 046d:c52f SN 11223344
|
||||||
Device Descriptor:
|
Device Descriptor:
|
||||||
bLength 18
|
bLength 18
|
||||||
bDescriptorType 1
|
bDescriptorType 1
|
||||||
@@ -56,15 +56,20 @@
|
|||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// MACRO CONSTANT TYPEDEF PROTYPES
|
// MACRO CONSTANT TYPEDEF PROTYPES
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
void led_blinking_task(void);
|
|
||||||
|
static uint32_t blink_interval_ms = 1000;
|
||||||
|
|
||||||
|
void led_blinking_task(void* param);
|
||||||
static void print_utf16(uint16_t* temp_buf, size_t buf_len);
|
static void print_utf16(uint16_t* temp_buf, size_t buf_len);
|
||||||
|
|
||||||
/*------------- MAIN -------------*/
|
#if CFG_TUSB_OS == OPT_OS_FREERTOS
|
||||||
int main(void) {
|
void init_freertos_task(void);
|
||||||
board_init();
|
#endif
|
||||||
|
|
||||||
printf("TinyUSB Device Info Example\r\n");
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// Main
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
void init_tinyusb(void) {
|
||||||
// init host stack on configured roothub port
|
// init host stack on configured roothub port
|
||||||
tusb_rhport_init_t host_init = {
|
tusb_rhport_init_t host_init = {
|
||||||
.role = TUSB_ROLE_HOST,
|
.role = TUSB_ROLE_HOST,
|
||||||
@@ -75,14 +80,22 @@ int main(void) {
|
|||||||
if (board_init_after_tusb) {
|
if (board_init_after_tusb) {
|
||||||
board_init_after_tusb();
|
board_init_after_tusb();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
board_init();
|
||||||
|
printf("TinyUSB Device Info Example\r\n");
|
||||||
|
|
||||||
|
#if CFG_TUSB_OS == OPT_OS_FREERTOS
|
||||||
|
init_freertos_task();
|
||||||
|
#else
|
||||||
|
init_tinyusb();
|
||||||
while (1) {
|
while (1) {
|
||||||
// tinyusb host task
|
tuh_task(); // tinyusb host task
|
||||||
tuh_task();
|
|
||||||
led_blinking_task();
|
led_blinking_task();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------- TinyUSB Callbacks -------------*/
|
/*------------- TinyUSB Callbacks -------------*/
|
||||||
@@ -97,9 +110,20 @@ void tuh_mount_cb(uint8_t daddr) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t serial[64];
|
||||||
uint16_t buf[256];
|
uint16_t buf[256];
|
||||||
|
|
||||||
printf("Device %u: ID %04x:%04x\r\n", daddr, desc_device.idVendor, desc_device.idProduct);
|
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));
|
||||||
|
printf("\r\n");
|
||||||
|
|
||||||
printf("Device Descriptor:\r\n");
|
printf("Device Descriptor:\r\n");
|
||||||
printf(" bLength %u\r\n", desc_device.bLength);
|
printf(" bLength %u\r\n", desc_device.bLength);
|
||||||
printf(" bDescriptorType %u\r\n", desc_device.bDescriptorType);
|
printf(" bDescriptorType %u\r\n", desc_device.bDescriptorType);
|
||||||
@@ -129,37 +153,17 @@ void tuh_mount_cb(uint8_t daddr) {
|
|||||||
printf("\r\n");
|
printf("\r\n");
|
||||||
|
|
||||||
printf(" iSerialNumber %u ", desc_device.iSerialNumber);
|
printf(" iSerialNumber %u ", desc_device.iSerialNumber);
|
||||||
xfer_result = tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, buf, sizeof(buf));
|
printf((char*)serial); // serial is already to UTF-8
|
||||||
if (XFER_RESULT_SUCCESS == xfer_result) {
|
|
||||||
print_utf16(buf, TU_ARRAY_SIZE(buf));
|
|
||||||
}
|
|
||||||
printf("\r\n");
|
printf("\r\n");
|
||||||
|
|
||||||
printf(" bNumConfigurations %u\r\n", desc_device.bNumConfigurations);
|
printf(" bNumConfigurations %u\r\n", desc_device.bNumConfigurations);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Invoked when device is unmounted (bus reset/unplugged)
|
// Invoked when device is unmounted (bus reset/unplugged)
|
||||||
void tuh_umount_cb(uint8_t daddr) {
|
void tuh_umount_cb(uint8_t daddr) {
|
||||||
printf("Device removed, address = %d\r\n", daddr);
|
printf("Device removed, address = %d\r\n", daddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
// Blinking Task
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
void led_blinking_task(void) {
|
|
||||||
const uint32_t interval_ms = 1000;
|
|
||||||
static uint32_t start_ms = 0;
|
|
||||||
|
|
||||||
static bool led_state = false;
|
|
||||||
|
|
||||||
// Blink every interval ms
|
|
||||||
if (board_millis() - start_ms < interval_ms) return; // not enough time
|
|
||||||
start_ms += interval_ms;
|
|
||||||
|
|
||||||
board_led_write(led_state);
|
|
||||||
led_state = 1 - led_state; // toggle
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// String Descriptor Helper
|
// String Descriptor Helper
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
@@ -212,3 +216,88 @@ static void print_utf16(uint16_t* temp_buf, size_t buf_len) {
|
|||||||
|
|
||||||
printf("%s", (char*) temp_buf);
|
printf("%s", (char*) temp_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Blinking Task
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
void led_blinking_task(void* param) {
|
||||||
|
(void) param;
|
||||||
|
static uint32_t start_ms = 0;
|
||||||
|
static bool led_state = false;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
#if CFG_TUSB_OS == OPT_OS_FREERTOS
|
||||||
|
if (blink_interval_ms == 0) {
|
||||||
|
vTaskSuspend(NULL);
|
||||||
|
} else {
|
||||||
|
vTaskDelay(blink_interval_ms / portTICK_PERIOD_MS);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (blink_interval_ms == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (board_millis() - start_ms < blink_interval_ms) {
|
||||||
|
return; // not enough time
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
start_ms += blink_interval_ms;
|
||||||
|
board_led_write(led_state);
|
||||||
|
led_state = 1 - led_state; // toggle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// FreeRTOS
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
#if CFG_TUSB_OS == OPT_OS_FREERTOS
|
||||||
|
|
||||||
|
#define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE
|
||||||
|
|
||||||
|
#if TUSB_MCU_VENDOR_ESPRESSIF
|
||||||
|
#define USB_STACK_SIZE 4096
|
||||||
|
#else
|
||||||
|
// Increase stack size when debug log is enabled
|
||||||
|
#define USB_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// static task
|
||||||
|
#if configSUPPORT_STATIC_ALLOCATION
|
||||||
|
StackType_t blinky_stack[BLINKY_STACK_SIZE];
|
||||||
|
StaticTask_t blinky_taskdef;
|
||||||
|
|
||||||
|
StackType_t usb_stack[USB_STACK_SIZE];
|
||||||
|
StaticTask_t usb_taskdef;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TUSB_MCU_VENDOR_ESPRESSIF
|
||||||
|
void app_main(void) {
|
||||||
|
main();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void usb_host_task(void *param) {
|
||||||
|
(void) param;
|
||||||
|
init_tinyusb();
|
||||||
|
while (1) {
|
||||||
|
tuh_task();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_freertos_task(void) {
|
||||||
|
#if configSUPPORT_STATIC_ALLOCATION
|
||||||
|
xTaskCreateStatic(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, blinky_stack, &blinky_taskdef);
|
||||||
|
xTaskCreateStatic(usb_host_task, "usbh", USB_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_stack, &usb_taskdef);
|
||||||
|
#else
|
||||||
|
xTaskCreate(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, NULL);
|
||||||
|
xTaskCreate(usb_host_task, "usbh", USB_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// skip starting scheduler (and return) for ESP32-S2 or ESP32-S3
|
||||||
|
#if !TUSB_MCU_VENDOR_ESPRESSIF
|
||||||
|
vTaskStartScheduler();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@@ -39,6 +39,11 @@
|
|||||||
#error CFG_TUSB_MCU must be defined
|
#error CFG_TUSB_MCU must be defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Espressif IDF requires "freertos/" prefix in include path
|
||||||
|
#if TUSB_MCU_VENDOR_ESPRESSIF
|
||||||
|
#define CFG_TUSB_OS_INC_PATH freertos/
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef CFG_TUSB_OS
|
#ifndef CFG_TUSB_OS
|
||||||
#define CFG_TUSB_OS OPT_OS_NONE
|
#define CFG_TUSB_OS OPT_OS_NONE
|
||||||
#endif
|
#endif
|
||||||
|
@@ -50,6 +50,7 @@ verbose = False
|
|||||||
# Path
|
# Path
|
||||||
# -------------------------------------------------------------
|
# -------------------------------------------------------------
|
||||||
OPENCOD_ADI_PATH = f'{os.getenv("HOME")}/app/openocd_adi'
|
OPENCOD_ADI_PATH = f'{os.getenv("HOME")}/app/openocd_adi'
|
||||||
|
TINYUSB_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||||
|
|
||||||
# get usb serial by id
|
# get usb serial by id
|
||||||
def get_serial_dev(id, vendor_str, product_str, ifnum):
|
def get_serial_dev(id, vendor_str, product_str, ifnum):
|
||||||
@@ -83,7 +84,7 @@ def open_serial_dev(port):
|
|||||||
# slight delay since kernel may occupy the port briefly
|
# slight delay since kernel may occupy the port briefly
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
timeout = timeout - 0.5
|
timeout = timeout - 0.5
|
||||||
ser = serial.Serial(port, timeout=5)
|
ser = serial.Serial(port, baudrate=115200, timeout=5)
|
||||||
break
|
break
|
||||||
except serial.SerialException:
|
except serial.SerialException:
|
||||||
pass
|
pass
|
||||||
@@ -212,6 +213,7 @@ def flash_esptool(board, firmware):
|
|||||||
flash_args = f.read().strip().replace('\n', ' ')
|
flash_args = f.read().strip().replace('\n', ' ')
|
||||||
command = (f'esptool.py --chip {idf_target} -p {port} {board["flasher_args"]} '
|
command = (f'esptool.py --chip {idf_target} -p {port} {board["flasher_args"]} '
|
||||||
f'--before=default_reset --after=hard_reset write_flash {flash_args}')
|
f'--before=default_reset --after=hard_reset write_flash {flash_args}')
|
||||||
|
# command = f'echo abc'
|
||||||
ret = run_cmd(command, cwd=fw_dir)
|
ret = run_cmd(command, cwd=fw_dir)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@@ -228,35 +230,6 @@ def test_dual_host_info_to_device_cdc(board):
|
|||||||
uid = board['uid']
|
uid = board['uid']
|
||||||
declared_devs = [f'{d["vid_pid"]}_{d["serial"]}' for d in board['tests']['dev_attached']]
|
declared_devs = [f'{d["vid_pid"]}_{d["serial"]}' for d in board['tests']['dev_attached']]
|
||||||
|
|
||||||
port = get_serial_dev(board["flasher_sn"], None, None, 0)
|
|
||||||
ser = open_serial_dev(port)
|
|
||||||
# read from serial, first line should contain vid/pid and serial
|
|
||||||
data = ser.read(1000)
|
|
||||||
lines = data.decode('utf-8').splitlines()
|
|
||||||
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)
|
|
||||||
if vid_pid_sn:
|
|
||||||
print(f'\r\n {l} ', end='')
|
|
||||||
enum_dev_sn.append(f'{vid_pid_sn.group(1)}_{vid_pid_sn.group(2)}_{vid_pid_sn.group(3)}')
|
|
||||||
|
|
||||||
if set(declared_devs) != set(enum_dev_sn):
|
|
||||||
# for pico/pico2 make this test optional
|
|
||||||
failed_msg = f'Enumerated devices {enum_dev_sn} not match with declared {declared_devs}'
|
|
||||||
if 'raspberry_pi_pico' in board['name']:
|
|
||||||
print(f'\r\n {failed_msg} {STATUS_FAILED} ', end='')
|
|
||||||
else:
|
|
||||||
assert False, failed_msg
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
# -------------------------------------------------------------
|
|
||||||
# Tests: host
|
|
||||||
# -------------------------------------------------------------
|
|
||||||
def test_host_cdc_msc_hid(board):
|
|
||||||
uid = board['uid']
|
|
||||||
declared_devs = [f'{d["vid_pid"]}_{d["serial"]}' for d in board['tests']['dev_attached']]
|
|
||||||
|
|
||||||
port = get_serial_dev(uid, 'TinyUSB', "TinyUSB_Device", 0)
|
port = get_serial_dev(uid, 'TinyUSB', "TinyUSB_Device", 0)
|
||||||
ser = open_serial_dev(port)
|
ser = open_serial_dev(port)
|
||||||
# read from serial, first line should contain vid/pid and serial
|
# read from serial, first line should contain vid/pid and serial
|
||||||
@@ -279,8 +252,36 @@ def test_host_cdc_msc_hid(board):
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def test_host_cdc_msc_hid_freertos(board):
|
# -------------------------------------------------------------
|
||||||
test_host_cdc_msc_hid(board)
|
# Tests: host
|
||||||
|
# -------------------------------------------------------------
|
||||||
|
def test_host_device_info(board):
|
||||||
|
uid = board['uid']
|
||||||
|
declared_devs = [f'{d["vid_pid"]}_{d["serial"]}' for d in board['tests']['dev_attached']]
|
||||||
|
|
||||||
|
port = get_serial_dev(board["flasher_sn"], None, None, 0)
|
||||||
|
ser = open_serial_dev(port)
|
||||||
|
data = ser.read(1000)
|
||||||
|
if len(data) == 0:
|
||||||
|
assert False, 'No data from device'
|
||||||
|
|
||||||
|
lines = data.decode('utf-8').splitlines()
|
||||||
|
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)
|
||||||
|
if vid_pid_sn:
|
||||||
|
print(f'\r\n {l} ', end='')
|
||||||
|
enum_dev_sn.append(f'{vid_pid_sn.group(1)}_{vid_pid_sn.group(2)}_{vid_pid_sn.group(3)}')
|
||||||
|
|
||||||
|
if set(declared_devs) != set(enum_dev_sn):
|
||||||
|
# for pico/pico2 make this test optional
|
||||||
|
failed_msg = f'Enumerated devices {enum_dev_sn} not match with declared {declared_devs}'
|
||||||
|
if 'raspberry_pi_pico' in board['name']:
|
||||||
|
print(f'\r\n {failed_msg} {STATUS_FAILED} ', end='')
|
||||||
|
else:
|
||||||
|
assert False, failed_msg
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
# -------------------------------------------------------------
|
# -------------------------------------------------------------
|
||||||
@@ -454,7 +455,7 @@ def test_board(board):
|
|||||||
print(f'{name:25} {skip:30} ... Skip')
|
print(f'{name:25} {skip:30} ... Skip')
|
||||||
|
|
||||||
# board_test is added last to disable board's usb
|
# board_test is added last to disable board's usb
|
||||||
test_list.append('device/board_test')
|
#test_list.append('device/board_test')
|
||||||
|
|
||||||
err_count = 0
|
err_count = 0
|
||||||
flags_on_list = [""]
|
flags_on_list = [""]
|
||||||
@@ -466,9 +467,9 @@ def test_board(board):
|
|||||||
if f1 != "":
|
if f1 != "":
|
||||||
f1_str = '-' + f1.replace(' ', '-')
|
f1_str = '-' + f1.replace(' ', '-')
|
||||||
for test in test_list:
|
for test in test_list:
|
||||||
fw_dir = f'cmake-build/cmake-build-{name}{f1_str}/{test}'
|
fw_dir = f'{TINYUSB_ROOT}/cmake-build/cmake-build-{name}{f1_str}/{test}'
|
||||||
if not os.path.exists(fw_dir):
|
if not os.path.exists(fw_dir):
|
||||||
fw_dir = f'examples/cmake-build-{name}{f1_str}/{test}'
|
fw_dir = f'{TINYUSB_ROOT}/examples/cmake-build-{name}{f1_str}/{test}'
|
||||||
fw_name = f'{fw_dir}/{os.path.basename(test)}'
|
fw_name = f'{fw_dir}/{os.path.basename(test)}'
|
||||||
print(f'{name+f1_str:40} {test:30} ... ', end='')
|
print(f'{name+f1_str:40} {test:30} ... ', end='')
|
||||||
|
|
||||||
|
@@ -4,7 +4,8 @@
|
|||||||
"name": "espressif_p4_function_ev",
|
"name": "espressif_p4_function_ev",
|
||||||
"uid": "6055F9F98715",
|
"uid": "6055F9F98715",
|
||||||
"tests": {
|
"tests": {
|
||||||
"only": ["device/cdc_msc_freertos", "device/hid_composite_freertos", "host/cdc_msc_hid_freertos"]
|
"only": ["device/cdc_msc_freertos", "device/hid_composite_freertos", "host/device_info"],
|
||||||
|
"dev_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2002427"}]
|
||||||
},
|
},
|
||||||
"flasher": "esptool",
|
"flasher": "esptool",
|
||||||
"flasher_sn": "4ea4f48f6bc3ee11bbb9d00f9e1b1c54",
|
"flasher_sn": "4ea4f48f6bc3ee11bbb9d00f9e1b1c54",
|
||||||
|
@@ -68,6 +68,7 @@ def get_examples(family):
|
|||||||
if family == 'espressif':
|
if family == 'espressif':
|
||||||
all_examples.append('device/board_test')
|
all_examples.append('device/board_test')
|
||||||
all_examples.append('device/video_capture')
|
all_examples.append('device/video_capture')
|
||||||
|
all_examples.append('host/device_info')
|
||||||
all_examples.sort()
|
all_examples.sort()
|
||||||
return all_examples
|
return all_examples
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user