Skip to content

Commit

Permalink
refactor(config_test): Added test for different tinyusb configurations
Browse files Browse the repository at this point in the history
  • Loading branch information
roma-jam committed Jan 6, 2025
1 parent 8488ae7 commit 9d5e31b
Show file tree
Hide file tree
Showing 7 changed files with 336 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# The following lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)

# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
set(COMPONENTS main)

project(test_app_configuration_descriptor)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
idf_component_register(SRC_DIRS .
INCLUDE_DIRS .
REQUIRES unity
WHOLE_ARCHIVE)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## IDF Component Manager Manifest File
dependencies:
espressif/esp_tinyusb:
version: "*"
override_path: "../../../"
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <stdio.h>
#include <string.h>
#include "unity.h"
#include "unity_test_runner.h"
#include "unity_test_utils_memory.h"

void app_main(void)
{
/*
_ _ _
| | (_) | |
___ ___ _ __ | |_ _ _ __ _ _ _ _ ___| |__
/ _ \/ __| '_ \| __| | '_ \| | | | | | / __| '_ \
| __/\__ \ |_) | |_| | | | | |_| | |_| \__ \ |_) |
\___||___/ .__/ \__|_|_| |_|\__, |\__,_|___/_.__/
| |______ __/ |
|_|______| |___/
_____ _____ _____ _____
|_ _| ___/ ___|_ _|
| | | |__ \ `--. | |
| | | __| `--. \ | |
| | | |___/\__/ / | |
\_/ \____/\____/ \_/
*/

printf(" _ _ _ \n");
printf(" | | (_) | | \n");
printf(" ___ ___ _ __ | |_ _ _ __ _ _ _ _ ___| |__ \n");
printf(" / _ \\/ __| '_ \\| __| | '_ \\| | | | | | / __| '_ \\ \n");
printf("| __/\\__ \\ |_) | |_| | | | | |_| | |_| \\__ \\ |_) |\n");
printf(" \\___||___/ .__/ \\__|_|_| |_|\\__, |\\__,_|___/_.__/ \n");
printf(" | |______ __/ | \n");
printf(" |_|______| |___/ \n");
printf(" _____ _____ _____ _____ \n");
printf("|_ _| ___/ ___|_ _| \n");
printf(" | | | |__ \\ `--. | | \n");
printf(" | | | __| `--. \\ | | \n");
printf(" | | | |___/\\__/ / | | \n");
printf(" \\_/ \\____/\\____/ \\_/ \n");

unity_utils_setup_heap_record(80);
unity_utils_set_leak_level(128);
unity_run_menu();
}

/* setUp runs before every test */
void setUp(void)
{
unity_utils_record_free_mem();
}

/* tearDown runs after every test */
void tearDown(void)
{
unity_utils_evaluate_leaks();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
/*
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

#include "soc/soc_caps.h"

#if SOC_USB_OTG_SUPPORTED

#include <stdio.h>
#include <string.h>
#include "esp_system.h"
#include "esp_err.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "esp_log.h"
#include "esp_err.h"
#include "unity.h"
#include "tinyusb.h"
#include "tusb_tasks.h"

static const char *TAG = "teardown";

#define TEARDOWN_DEVICE_ATTACH_TIMEOUT_MS 1000
#define TEARDOWN_DEVICE_DETACH_DELAY_MS 1000

// ========================= TinyUSB descriptors ===============================

// Here we need to create dual CDC device, to match the CONFIG_TINYUSB_CDC_COUNT from sdkconfig.defaults
static const uint16_t cdc_desc_config_len = TUD_CONFIG_DESC_LEN + CFG_TUD_CDC * TUD_CDC_DESC_LEN;
static const uint8_t test_fs_configuration_descriptor[] = {
// Config number, interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, 0, 0, cdc_desc_config_len, TUSB_DESC_CONFIG_ATT_SELF_POWERED | TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
TUD_CDC_DESCRIPTOR(0, 4, 0x81, 8, 0x02, 0x82, 64),
TUD_CDC_DESCRIPTOR(2, 4, 0x83, 8, 0x04, 0x84, 64),
};

#if (TUD_OPT_HIGH_SPEED)
static const uint8_t test_hs_configuration_descriptor[] = {
// Config number, interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, 4, 0, cdc_desc_config_len, TUSB_DESC_CONFIG_ATT_SELF_POWERED | TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
TUD_CDC_DESCRIPTOR(0, 4, 0x81, 8, 0x02, 0x82, 512),
TUD_CDC_DESCRIPTOR(2, 4, 0x83, 8, 0x04, 0x84, 512),
};

static const tusb_desc_device_qualifier_t device_qualifier = {
.bLength = sizeof(tusb_desc_device_qualifier_t),
.bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER,
.bcdUSB = 0x0200,
.bDeviceClass = TUSB_CLASS_MISC,
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
.bDeviceProtocol = MISC_PROTOCOL_IAD,
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
.bNumConfigurations = 0x01,
.bReserved = 0
};
#endif // TUD_OPT_HIGH_SPEED

static const tusb_desc_device_t test_device_descriptor = {
.bLength = sizeof(test_device_descriptor),
.bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = 0x0200,
.bDeviceClass = TUSB_CLASS_MISC,
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
.bDeviceProtocol = MISC_PROTOCOL_IAD,
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
.idVendor = 0x303A, // This is Espressif VID. This needs to be changed according to Users / Customers
.idProduct = 0x4002,
.bcdDevice = 0x100,
.iManufacturer = 0x01,
.iProduct = 0x02,
.iSerialNumber = 0x03,
.bNumConfigurations = 0x01
};

// ========================== Private logic ====================================
SemaphoreHandle_t wait_mount = NULL;

static bool __test_init(void)
{
wait_mount = xSemaphoreCreateBinary();
return (wait_mount != NULL);
}

static void __test_conn(void)
{
if (wait_mount) {
xSemaphoreGive(wait_mount);
}
}

static esp_err_t __test_wait_conn(void)
{
if (!wait_mount) {
return ESP_ERR_INVALID_STATE;
}

return ( xSemaphoreTake(wait_mount, pdMS_TO_TICKS(TEARDOWN_DEVICE_ATTACH_TIMEOUT_MS))
? ESP_OK
: ESP_ERR_TIMEOUT );
}

static void __test_release(void)
{
if (wait_mount) {
vSemaphoreDelete(wait_mount);
}
}

static void __test_tinyusb_set_config(const tinyusb_config_t *tusb_cfg)
{
// Install
TEST_ASSERT_EQUAL(ESP_OK, tinyusb_driver_install(tusb_cfg));
// Wait for mounted callback
TEST_ASSERT_EQUAL(ESP_OK, __test_wait_conn());
// Give Host some timer to init the device
vTaskDelay(pdMS_TO_TICKS(TEARDOWN_DEVICE_DETACH_DELAY_MS));
// Cleanup
TEST_ASSERT_EQUAL(ESP_OK, tinyusb_driver_uninstall());
// Release resources
__test_release();
}

// ========================== Callbacks ========================================
// Invoked when device is mounted
void tud_mount_cb(void)
{
ESP_LOGD(TAG, "%s", __FUNCTION__);
__test_conn();
}

// ============================= Tests =========================================

TEST_CASE("descriptors_config_all_default", "[esp_tinyusb][usb_device][config]")
{
TEST_ASSERT_EQUAL(true, __test_init());
// Install TinyUSB driver
const tinyusb_config_t tusb_cfg = {
.external_phy = false,
.device_descriptor = NULL,
.configuration_descriptor = NULL,
#if (TUD_OPT_HIGH_SPEED)
.hs_configuration_descriptor = NULL,
#endif // TUD_OPT_HIGH_SPEED
};
__test_tinyusb_set_config(&tusb_cfg);
}

TEST_CASE("descriptors_config_device", "[esp_tinyusb][usb_device][config]")
{
TEST_ASSERT_EQUAL(true, __test_init());
// Install TinyUSB driver
const tinyusb_config_t tusb_cfg = {
.external_phy = false,
.device_descriptor = &test_device_descriptor,
.configuration_descriptor = NULL,
#if (TUD_OPT_HIGH_SPEED)
.hs_configuration_descriptor = NULL,
.qualifier_descriptor = &device_qualifier,
#endif // TUD_OPT_HIGH_SPEED
};
__test_tinyusb_set_config(&tusb_cfg);
}

TEST_CASE("descriptors_config_device_and_config", "[esp_tinyusb][usb_device][config]")
{
TEST_ASSERT_EQUAL(true, __test_init());
// Install TinyUSB driver
const tinyusb_config_t tusb_cfg = {
.external_phy = false,
.device_descriptor = &test_device_descriptor,
.configuration_descriptor = test_fs_configuration_descriptor,
#if (TUD_OPT_HIGH_SPEED)
.hs_configuration_descriptor = NULL,
.qualifier_descriptor = &device_qualifier,
#endif // TUD_OPT_HIGH_SPEED
};
__test_tinyusb_set_config(&tusb_cfg);
}

#if (TUD_OPT_HIGH_SPEED)
TEST_CASE("descriptors_config_device_and_fs_config_only", "[esp_tinyusb][usb_device][config]")
{
TEST_ASSERT_EQUAL(true, __test_init());
// Install TinyUSB driver
const tinyusb_config_t tusb_cfg = {
.external_phy = false,
.device_descriptor = &test_device_descriptor,
.configuration_descriptor = test_fs_configuration_descriptor,
.hs_configuration_descriptor = NULL,
.qualifier_descriptor = &device_qualifier,
};
__test_tinyusb_set_config(&tusb_cfg);
}

TEST_CASE("descriptors_config_device_and_hs_config_only", "[esp_tinyusb][usb_device][config]")
{
TEST_ASSERT_EQUAL(true, __test_init());
// Install TinyUSB driver
const tinyusb_config_t tusb_cfg = {
.external_phy = false,
.device_descriptor = &test_device_descriptor,
.configuration_descriptor = NULL,
.hs_configuration_descriptor = test_hs_configuration_descriptor,
.qualifier_descriptor = &device_qualifier,
};
__test_tinyusb_set_config(&tusb_cfg);
}

TEST_CASE("descriptors_config_all_configured", "[esp_tinyusb][usb_device][config]")
{
TEST_ASSERT_EQUAL(true, __test_init());
// Install TinyUSB driver
const tinyusb_config_t tusb_cfg = {
.external_phy = false,
.device_descriptor = &test_device_descriptor,
.fs_configuration_descriptor = test_fs_configuration_descriptor,
.hs_configuration_descriptor = test_hs_configuration_descriptor,
.qualifier_descriptor = &device_qualifier,
};
__test_tinyusb_set_config(&tusb_cfg);
}
#endif // TUD_OPT_HIGH_SPEED

#endif // SOC_USB_OTG_SUPPORTED
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0

import pytest
from pytest_embedded_idf.dut import IdfDut


@pytest.mark.esp32s2
@pytest.mark.esp32s3
@pytest.mark.esp32p4
@pytest.mark.usb_device
def test_usb_device_configuration(dut: IdfDut) -> None:
dut.run_all_single_board_cases(group='config')
16 changes: 16 additions & 0 deletions device/esp_tinyusb/test_apps/configuration_desc/sdkconfig.defaults
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Configure TinyUSB, it will be used to mock USB devices
CONFIG_TINYUSB_CDC_ENABLED=y
CONFIG_TINYUSB_CDC_COUNT=2

# Disable watchdogs, they'd get triggered during unity interactive menu
CONFIG_ESP_INT_WDT=n
CONFIG_ESP_TASK_WDT=n

# Run-time checks of Heap and Stack
CONFIG_HEAP_POISONING_COMPREHENSIVE=y
CONFIG_COMPILER_STACK_CHECK_MODE_STRONG=y
CONFIG_COMPILER_STACK_CHECK=y

CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL=y

CONFIG_COMPILER_CXX_EXCEPTIONS=y

0 comments on commit 9d5e31b

Please sign in to comment.