Merge branch 'feature/usb_host/ci-tests' into 'master'

Run USB Host tests in pipeline

Closes IDF-4425

See merge request espressif/esp-idf!16376
pull/11508/head
Tomas Rezucha 2022-03-22 14:12:12 +08:00
commit 7db3d28187
28 zmienionych plików z 570 dodań i 361 usunięć

Wyświetl plik

@ -196,6 +196,16 @@ test_app_test_pytest_esp32c3_generic:
TARGET: ESP32C3
ENV_MARKER: generic
test_app_test_pytest_esp32s2_usb_host:
extends:
- .pytest_test_apps_dir_template
- .rules:test:custom_test-esp32s2
needs:
- build_pytest_test_apps_esp32s2
variables:
TARGET: ESP32S2
ENV_MARKER: usb_host
# for parallel jobs, CI_JOB_NAME will be "job_name index/total" (for example, "IT_001 1/2")
# we need to convert to pattern "job_name_index.yml"
.define_config_file_name: &define_config_file_name |

Wyświetl plik

@ -116,7 +116,6 @@ menu "TinyUSB Stack"
menu "Massive Storage Class (MSC)"
config TINYUSB_MSC_ENABLED
depends on TINYUSB_CDC_COUNT < 2
bool "Enable TinyUSB MSC feature"
default n
help

Wyświetl plik

@ -64,9 +64,13 @@ extern "C" {
* @brief Configuration structure of the tinyUSB core
*/
typedef struct {
tusb_desc_device_t *descriptor; /*!< Pointer to a device descriptor */
const char **string_descriptor; /*!< Pointer to an array of string descriptors */
bool external_phy; /*!< Should USB use an external PHY */
union {
const tusb_desc_device_t *device_descriptor; /*!< Pointer to a device descriptor. If set to NULL, the TinyUSB device will use a default device descriptor whose values are set in Kconfig */
const tusb_desc_device_t *descriptor __attribute__((deprecated)); /*!< Alias to `device_descriptor` for backward compatibility */
};
const char **string_descriptor; /*!< Pointer to an array of string descriptors */
bool external_phy; /*!< Should USB use an external PHY */
const uint8_t *configuration_descriptor; /*!< Pointer to a configuration descriptor. If set to NULL, TinyUSB device will use a default configuration descriptor whose values are set in Kconfig */
} tinyusb_config_t;
/**

Wyświetl plik

@ -12,7 +12,6 @@ extern "C" {
#include <stdint.h>
#include "freertos/FreeRTOS.h"
#include "freertos/ringbuf.h"
#include "freertos/semphr.h"
#include "freertos/timers.h"
#include "tusb.h"

Wyświetl plik

@ -12,7 +12,6 @@ extern "C" {
#include <stdint.h>
#include "freertos/FreeRTOS.h"
#include "freertos/ringbuf.h"
#include "freertos/semphr.h"
#include "freertos/timers.h"
#include "tusb.h"

Wyświetl plik

@ -6,49 +6,14 @@
#pragma once
#include <string.h>
#include "usb_descriptors.h"
#include "tusb.h"
#include "tinyusb_types.h"
#ifdef __cplusplus
extern "C" {
#endif
//------------- HID Report Descriptor -------------//
#if CFG_TUD_HID
enum {
REPORT_ID_KEYBOARD = 1,
REPORT_ID_MOUSE
};
#endif
//------------- Configuration Descriptor -------------//
enum {
# if CFG_TUD_CDC
ITF_NUM_CDC = 0,
ITF_NUM_CDC_DATA,
# endif
# if CFG_TUD_CDC > 1
ITF_NUM_CDC1,
ITF_NUM_CDC1_DATA,
# endif
# if CFG_TUD_MSC
ITF_NUM_MSC,
# endif
# if CFG_TUD_HID
ITF_NUM_HID,
# endif
ITF_NUM_TOTAL
};
enum {
TUSB_DESC_TOTAL_LEN = TUD_CONFIG_DESC_LEN + CFG_TUD_CDC * TUD_CDC_DESC_LEN + CFG_TUD_MSC * TUD_MSC_DESC_LEN +
CFG_TUD_HID * TUD_HID_DESC_LEN
};
void tusb_set_descriptor(tusb_desc_device_t *desc, const char **str_desc);
void tusb_set_descriptor(const tusb_desc_device_t *dev_desc, const char **str_desc, const uint8_t *cfg_desc);
tusb_desc_device_t *tusb_get_active_desc(void);
char **tusb_get_active_str_desc(void);
void tusb_clear_descriptor(void);

Wyświetl plik

@ -18,8 +18,9 @@ extern "C" {
extern tusb_desc_device_t descriptor_tinyusb;
extern tusb_desc_strarray_device_t descriptor_str_tinyusb;
extern tusb_desc_device_t descriptor_kconfig;
extern const tusb_desc_device_t descriptor_dev_kconfig;
extern tusb_desc_strarray_device_t descriptor_str_kconfig;
extern const uint8_t descriptor_cfg_kconfig[];
#ifdef __cplusplus
}

Wyświetl plik

@ -4,49 +4,16 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include "esp_log.h"
#include "descriptors_control.h"
static const char *TAG = "tusb_desc";
static tusb_desc_device_t s_descriptor;
static tusb_desc_device_t s_device_descriptor;
static const uint8_t *s_configuration_descriptor;
static char *s_str_descriptor[USB_STRING_DESCRIPTOR_ARRAY_SIZE];
#define MAX_DESC_BUF_SIZE 32
#define EPNUM_MSC ((CFG_TUD_CDC * 2) + 1)
#define EPNUM_HID (EPNUM_MSC + 1)
#if CFG_TUD_HID //HID Report Descriptor
uint8_t const desc_hid_report[] = {
TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(REPORT_ID_KEYBOARD), ),
TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(REPORT_ID_MOUSE), )
};
#endif
uint8_t const desc_configuration[] = {
// interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, TUSB_DESC_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
# if CFG_TUD_CDC
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, 0x81, 8, 0x02, 0x82, 64),
# endif
# if CFG_TUD_CDC > 1
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC1, 4, 0x83, 8, 0x04, 0x84, 64),
# endif
# if CFG_TUD_MSC
// Interface number, string index, EP Out & EP In address, EP size
TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC, 0x80 | EPNUM_MSC, 64), // highspeed 512
# endif
# if CFG_TUD_HID
// Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval
TUD_HID_DESCRIPTOR(ITF_NUM_HID, 6, HID_PROTOCOL_NONE, sizeof(desc_hid_report), 0x80 | EPNUM_HID, 16, 10)
# endif
};
// =============================================================================
// CALLBACKS
// =============================================================================
@ -59,7 +26,7 @@ uint8_t const desc_configuration[] = {
*/
uint8_t const *tud_descriptor_device_cb(void)
{
return (uint8_t const *)&s_descriptor;
return (uint8_t const *)&s_device_descriptor;
}
/**
@ -72,7 +39,7 @@ uint8_t const *tud_descriptor_device_cb(void)
uint8_t const *tud_descriptor_configuration_cb(uint8_t index)
{
(void)index; // for multiple configurations
return desc_configuration;
return s_configuration_descriptor;
}
static uint16_t _desc_str[MAX_DESC_BUF_SIZE];
@ -114,25 +81,11 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid)
return _desc_str;
}
/**
* @brief Invoked when received GET HID REPORT DESCRIPTOR
* Application returns pointer to descriptor. Descriptor contents must exist
* long enough for transfer to complete
*
* @return uint8_t const*
*/
#if CFG_TUD_HID
uint8_t const *tud_hid_descriptor_report_cb(void)
{
return desc_hid_report;
}
#endif
// =============================================================================
// Driver functions
// =============================================================================
void tusb_set_descriptor(tusb_desc_device_t *dev_desc, const char **str_desc)
void tusb_set_descriptor(const tusb_desc_device_t *dev_desc, const char **str_desc, const uint8_t *cfg_desc)
{
ESP_LOGI(TAG, "\n"
"┌─────────────────────────────────┐\n"
@ -165,7 +118,8 @@ void tusb_set_descriptor(tusb_desc_device_t *dev_desc, const char **str_desc)
dev_desc->idVendor, dev_desc->idProduct, dev_desc->bcdDevice,
dev_desc->iManufacturer, dev_desc->iProduct, dev_desc->iSerialNumber,
dev_desc->bNumConfigurations);
s_descriptor = *dev_desc;
s_device_descriptor = *dev_desc;
s_configuration_descriptor = cfg_desc;
if (str_desc != NULL) {
memcpy(s_str_descriptor, str_desc,
@ -175,7 +129,7 @@ void tusb_set_descriptor(tusb_desc_device_t *dev_desc, const char **str_desc)
tusb_desc_device_t *tusb_get_active_desc(void)
{
return &s_descriptor;
return &s_device_descriptor;
}
char **tusb_get_active_str_desc(void)
@ -185,6 +139,6 @@ char **tusb_get_active_str_desc(void)
void tusb_clear_descriptor(void)
{
memset(&s_descriptor, 0, sizeof(s_descriptor));
memset(&s_device_descriptor, 0, sizeof(s_device_descriptor));
memset(&s_str_descriptor, 0, sizeof(s_str_descriptor));
}

Wyświetl plik

@ -13,6 +13,7 @@
#include "soc/usb_pins.h"
#include "tinyusb.h"
#include "descriptors_control.h"
#include "usb_descriptors.h"
#include "tusb.h"
#include "tusb_tasks.h"
@ -21,8 +22,9 @@ static usb_phy_handle_t phy_hdl;
esp_err_t tinyusb_driver_install(const tinyusb_config_t *config)
{
tusb_desc_device_t *dev_descriptor;
const tusb_desc_device_t *dev_descriptor;
const char **string_descriptor;
const uint8_t *cfg_descriptor;
ESP_RETURN_ON_FALSE(config, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
// Configure USB PHY
@ -46,10 +48,11 @@ esp_err_t tinyusb_driver_install(const tinyusb_config_t *config)
}
ESP_RETURN_ON_ERROR(usb_new_phy(&phy_conf, &phy_hdl), TAG, "Install USB PHY failed");
dev_descriptor = config->descriptor ? config->descriptor : &descriptor_kconfig;
dev_descriptor = config->device_descriptor ? config->device_descriptor : &descriptor_dev_kconfig;
string_descriptor = config->string_descriptor ? config->string_descriptor : descriptor_str_kconfig;
cfg_descriptor = config->configuration_descriptor ? config->configuration_descriptor : descriptor_cfg_kconfig;
tusb_set_descriptor(dev_descriptor, string_descriptor);
tusb_set_descriptor(dev_descriptor, string_descriptor, cfg_descriptor);
ESP_RETURN_ON_FALSE(tusb_init(), ESP_FAIL, TAG, "Init TinyUSB stack failed");
#if !CONFIG_TINYUSB_NO_DEFAULT_TASK

Wyświetl plik

@ -10,6 +10,7 @@
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/ringbuf.h"
#include "tusb.h"
#include "tusb_cdc_acm.h"
#include "cdc.h"

Wyświetl plik

@ -60,8 +60,8 @@ tusb_desc_strarray_device_t descriptor_str_tinyusb = {
/* End of TinyUSB default */
/**** Kconfig driven Descriptor ****/
tusb_desc_device_t descriptor_kconfig = {
.bLength = sizeof(descriptor_kconfig),
const tusb_desc_device_t descriptor_dev_kconfig = {
.bLength = sizeof(descriptor_dev_kconfig),
.bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = 0x0200,
@ -126,4 +126,76 @@ tusb_desc_strarray_device_t descriptor_str_kconfig = {
#endif
};
//------------- HID Report Descriptor -------------//
#if CFG_TUD_HID
enum {
REPORT_ID_KEYBOARD = 1,
REPORT_ID_MOUSE
};
#endif
//------------- Configuration Descriptor -------------//
enum {
# if CFG_TUD_CDC
ITF_NUM_CDC = 0,
ITF_NUM_CDC_DATA,
# endif
# if CFG_TUD_CDC > 1
ITF_NUM_CDC1,
ITF_NUM_CDC1_DATA,
# endif
# if CFG_TUD_MSC
ITF_NUM_MSC,
# endif
# if CFG_TUD_HID
ITF_NUM_HID,
# endif
ITF_NUM_TOTAL
};
enum {
TUSB_DESC_TOTAL_LEN = TUD_CONFIG_DESC_LEN + CFG_TUD_CDC * TUD_CDC_DESC_LEN + CFG_TUD_MSC * TUD_MSC_DESC_LEN +
CFG_TUD_HID * TUD_HID_DESC_LEN
};
#define EPNUM_MSC ((CFG_TUD_CDC * 2) + 1)
#define EPNUM_HID (EPNUM_MSC + 1)
#if CFG_TUD_HID //HID Report Descriptor
uint8_t const desc_hid_report[] = {
TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(REPORT_ID_KEYBOARD), ),
TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(REPORT_ID_MOUSE), )
};
#endif
uint8_t const descriptor_cfg_kconfig[] = {
// interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, TUSB_DESC_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
# if CFG_TUD_CDC
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, 0x81, 8, 0x02, 0x82, 64),
# endif
# if CFG_TUD_CDC > 1
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC1, 4, 0x83, 8, 0x04, 0x84, 64),
# endif
# if CFG_TUD_MSC
// Interface number, string index, EP Out & EP In address, EP size
TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC, 0x80 | EPNUM_MSC, 64), // highspeed 512
# endif
# if CFG_TUD_HID
// Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval
TUD_HID_DESCRIPTOR(ITF_NUM_HID, 6, HID_PROTOCOL_NONE, sizeof(desc_hid_report), 0x80 | EPNUM_HID, 16, 10)
# endif
};
/* End of Kconfig driven Descriptor */

Wyświetl plik

@ -230,6 +230,19 @@ static void usbh_print_cfg_desc(const usb_config_desc_t *cfg_desc)
printf("bMaxPower %dmA\n", cfg_desc->bMaxPower * 2);
}
static void print_iad_desc(const usb_iad_desc_t *iad_desc)
{
printf("*** Interface Association Descriptor ***\n");
printf("bLength %d\n", iad_desc->bLength);
printf("bDescriptorType %d\n", iad_desc->bDescriptorType);
printf("bFirstInterface %d\n", iad_desc->bFirstInterface);
printf("bInterfaceCount %d\n", iad_desc->bInterfaceCount);
printf("bFunctionClass 0x%x\n", iad_desc->bFunctionClass);
printf("bFunctionSubClass 0x%x\n", iad_desc->bFunctionSubClass);
printf("bFunctionProtocol 0x%x\n", iad_desc->bFunctionProtocol);
printf("iFunction %d\n", iad_desc->iFunction);
}
void usb_print_device_descriptor(const usb_device_desc_t *devc_desc)
{
if (devc_desc == NULL) {
@ -265,15 +278,18 @@ void usb_print_config_descriptor(const usb_config_desc_t *cfg_desc, print_class_
do {
switch (next_desc->bDescriptorType) {
case USB_W_VALUE_DT_CONFIG:
case USB_B_DESCRIPTOR_TYPE_CONFIGURATION:
usbh_print_cfg_desc((const usb_config_desc_t *)next_desc);
break;
case USB_W_VALUE_DT_INTERFACE:
case USB_B_DESCRIPTOR_TYPE_INTERFACE:
usbh_print_intf_desc((const usb_intf_desc_t *)next_desc);
break;
case USB_W_VALUE_DT_ENDPOINT:
case USB_B_DESCRIPTOR_TYPE_ENDPOINT:
print_ep_desc((const usb_ep_desc_t *)next_desc);
break;
case USB_B_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION:
print_iad_desc((const usb_iad_desc_t*)next_desc);
break;
default:
if(class_specific_cb) {
class_specific_cb(next_desc);

Wyświetl plik

@ -29,7 +29,7 @@ from _pytest.python import Function
from _pytest.reports import TestReport
from _pytest.runner import CallInfo
from _pytest.terminal import TerminalReporter
from pytest_embedded.plugin import parse_configuration
from pytest_embedded.plugin import apply_count, parse_configuration
from pytest_embedded.utils import find_by_suffix
SUPPORTED_TARGETS = ['esp32', 'esp32s2', 'esp32c3', 'esp32s3']
@ -62,6 +62,7 @@ def item_marker_names(item: Item) -> List[str]:
# Fixtures #
############
@pytest.fixture
@parse_configuration
def config(request: FixtureRequest) -> str:
return getattr(request, 'param', None) or DEFAULT_SDKCONFIG
@ -77,9 +78,9 @@ def test_case_name(request: FixtureRequest, target: str, config: str) -> str:
@pytest.fixture
@parse_configuration
@apply_count
def build_dir(
request: FixtureRequest, app_path: str, target: Optional[str], config: Optional[str]
app_path: str, target: Optional[str], config: Optional[str]
) -> str:
"""
Check local build dir with the following priority:
@ -90,7 +91,6 @@ def build_dir(
4. build
Args:
request: pytest fixture
app_path: app path
target: target
config: config
@ -98,11 +98,6 @@ def build_dir(
Returns:
valid build directory
"""
param_or_cli: str = getattr(request, 'param', None) or request.config.getoption(
'build_dir'
)
if param_or_cli is not None: # respect the param and the cli
return param_or_cli
check_dirs = []
if target is not None and config is not None:
@ -131,6 +126,7 @@ def build_dir(
@pytest.fixture(autouse=True)
@apply_count
def junit_properties(
test_case_name: str, record_xml_attribute: Callable[[str, object], None]
) -> None:

Wyświetl plik

@ -33,23 +33,26 @@ idf.py -p PORT flash monitor
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
### Running with dual USB CDC device
USB CDC device example [tusb_serial_device example](../../../device/tusb_serial_device)
can be configured to act as dual CDC device.
In the device example project, enter command `idf.py menuconfig` and set Component config->TinyUSB Stack->Communication Device Class (CDC)->CDC channel Count to `2`.
This settings also changes device's PID, so `EXAMPLE_USB_DEVICE_PID` in [usb-cdc.c](./main/usb-cdc.c) must be changed to `0x4002`.
## Example Output
After the flashing you should see the output at idf monitor:
```
...
I (256) USB-CDC: USB Host installed
I (256) USB-CDC: Opening CDC ACM device 0x303A:0x4001
CDC Header Descriptor:
bcdCDC: 1.20
CDC Call Descriptor:
bmCapabilities: 0x00
bDataInterface: 1
CDC ACM Descriptor:
bmCapabilities: 0x02
CDC Union Descriptor:
bControlInterface: 0
bSubordinateInterface[0]: 1
...
Device descriptor is printed here
...
I (1666) USB-CDC: Data received
I (1666) USB-CDC: 0x3ffc4c20 41 54 0d |AT.|
I (2666) USB-CDC: Data received

Wyświetl plik

@ -16,7 +16,7 @@
#define EXAMPLE_USB_HOST_PRIORITY 20
#define EXAMPLE_USB_DEVICE_VID 0x303A // 0x303A:0x4001 (TinyUSB CDC device)
#define EXAMPLE_USB_DEVICE_PID 0x4001
#define EXAMPLE_USB_DEVICE_PID 0x4001 // Change this to 0x4002 for dual CDC device
static const char *TAG = "USB-CDC";

Wyświetl plik

@ -648,7 +648,7 @@ static esp_err_t cdc_acm_find_intf_and_ep_desc(cdc_dev_t *cdc_dev, uint8_t intf_
// IAD with correct interface number was found: Check Class/Subclass codes, save Interface indexes
assert(iad_desc->bInterfaceCount == 2);
assert(iad_desc->bFunctionClass == USB_CLASS_COMM);
assert(iad_desc->bFunctionSubClass == CDC_SUBCLASS_ACM);
assert(iad_desc->bFunctionSubClass == USB_CDC_SUBCLASS_ACM);
notif_intf_idx = iad_desc->bFirstInterface;
data_intf_idx = iad_desc->bFirstInterface + 1;
interface_found = true;
@ -673,7 +673,7 @@ static esp_err_t cdc_acm_find_intf_and_ep_desc(cdc_dev_t *cdc_dev, uint8_t intf_
const usb_standard_desc_t *cdc_desc = (usb_standard_desc_t *)cdc_dev->notif.intf_desc;
do {
cdc_desc = usb_parse_next_descriptor(cdc_desc, config_desc->wTotalLength, &desc_offset);
if ((cdc_desc == NULL) || (cdc_desc->bDescriptorType != ((USB_CLASS_COMM << 4) | USB_W_VALUE_DT_INTERFACE)))
if ((cdc_desc == NULL) || (cdc_desc->bDescriptorType != ((USB_CLASS_COMM << 4) | USB_B_DESCRIPTOR_TYPE_INTERFACE )))
break; // We found all CDC specific descriptors
cdc_dev->num_cdc_intf_desc++;
cdc_dev->cdc_intf_desc =
@ -727,7 +727,7 @@ esp_err_t cdc_acm_host_open(uint16_t vid, uint16_t pid, uint8_t interface_idx, c
// Check whether found Interfaces are really CDC-ACM
assert(cdc_dev->notif.intf_desc->bInterfaceClass == USB_CLASS_COMM);
assert(cdc_dev->notif.intf_desc->bInterfaceSubClass == CDC_SUBCLASS_ACM);
assert(cdc_dev->notif.intf_desc->bInterfaceSubClass == USB_CDC_SUBCLASS_ACM);
assert(cdc_dev->notif.intf_desc->bNumEndpoints == 1);
assert(cdc_dev->data.intf_desc->bInterfaceClass == USB_CLASS_CDC_DATA);
assert(cdc_dev->data.intf_desc->bNumEndpoints == 2);
@ -844,46 +844,66 @@ esp_err_t cdc_acm_host_close(cdc_acm_dev_hdl_t cdc_hdl)
return ESP_OK;
}
/**
* @brief Print CDC specific descriptor in human readable form
*
* This is a callback function that is called from USB Host library,
* when it wants to print full configuration descriptor to stdout.
*
* @param[in] _desc CDC specific descriptor
*/
static void cdc_acm_print_desc(const usb_standard_desc_t *_desc)
{
if (_desc->bDescriptorType != ((USB_CLASS_COMM << 4) | USB_B_DESCRIPTOR_TYPE_INTERFACE ))
{
// Quietly return in case that this descriptor is not CDC interface descriptor
return;
}
switch (((cdc_header_desc_t *)_desc)->bDescriptorSubtype) {
case USB_CDC_DESC_SUBTYPE_HEADER: {
cdc_header_desc_t *desc = (cdc_header_desc_t *)_desc;
printf("\t*** CDC Header Descriptor ***\n");
printf("\tbcdCDC: %d.%d0\n", ((desc->bcdCDC >> 8) & 0xF), ((desc->bcdCDC >> 4) & 0xF));
break;
}
case USB_CDC_DESC_SUBTYPE_CALL: {
cdc_acm_call_desc_t *desc = (cdc_acm_call_desc_t *)_desc;
printf("\t*** CDC Call Descriptor ***\n");
printf("\tbmCapabilities: 0x%02X\n", desc->bmCapabilities.val);
printf("\tbDataInterface: %d\n", desc->bDataInterface);
break;
}
case USB_CDC_DESC_SUBTYPE_ACM: {
cdc_acm_acm_desc_t *desc = (cdc_acm_acm_desc_t *)_desc;
printf("\t*** CDC ACM Descriptor ***\n");
printf("\tbmCapabilities: 0x%02X\n", desc->bmCapabilities.val);
break;
}
case USB_CDC_DESC_SUBTYPE_UNION: {
cdc_union_desc_t *desc = (cdc_union_desc_t *)_desc;
printf("\t*** CDC Union Descriptor ***\n");
printf("\tbControlInterface: %d\n", desc->bControlInterface);
printf("\tbSubordinateInterface[0]: %d\n", desc->bSubordinateInterface[0]);
break;
}
default:
ESP_LOGW(TAG, "Unsupported CDC specific descriptor");
break;
}
}
void cdc_acm_host_desc_print(cdc_acm_dev_hdl_t cdc_hdl)
{
assert(cdc_hdl);
cdc_dev_t *cdc_dev = (cdc_dev_t *)cdc_hdl;
ESP_RETURN_ON_FALSE(cdc_dev->num_cdc_intf_desc > 0,, TAG, "No CDC-ACM specific descriptors found");
for (int i = 0; i < cdc_dev->num_cdc_intf_desc; i++) {
switch (((cdc_header_desc_t *)cdc_dev->cdc_intf_desc[i])->bDescriptorSubtype) {
case CDC_DESC_SUBTYPE_HEADER: {
cdc_header_desc_t *desc = (cdc_header_desc_t *)cdc_dev->cdc_intf_desc[i];
printf("CDC Header Descriptor:\n");
printf("\tbcdCDC: %d.%d0\n", ((desc->bcdCDC >> 8) & 0xF), ((desc->bcdCDC >> 4) & 0xF));
break;
}
case CDC_DESC_SUBTYPE_CALL: {
cdc_acm_call_desc_t *desc = (cdc_acm_call_desc_t *)cdc_dev->cdc_intf_desc[i];
printf("CDC Call Descriptor:\n");
printf("\tbmCapabilities: 0x%02X\n", desc->bmCapabilities.val);
printf("\tbDataInterface: %d\n", desc->bDataInterface);
break;
}
case CDC_DESC_SUBTYPE_ACM: {
cdc_acm_acm_desc_t *desc = (cdc_acm_acm_desc_t *)cdc_dev->cdc_intf_desc[i];
printf("CDC ACM Descriptor:\n");
printf("\tbmCapabilities: 0x%02X\n", desc->bmCapabilities.val);
break;
}
case CDC_DESC_SUBTYPE_UNION: {
cdc_union_desc_t *desc = (cdc_union_desc_t *)cdc_dev->cdc_intf_desc[i];
printf("CDC Union Descriptor:\n");
printf("\tbControlInterface: %d\n", desc->bControlInterface);
printf("\tbSubordinateInterface[0]: %d\n", desc->bSubordinateInterface[0]);
break;
}
default:
ESP_LOGW(TAG, "Unsupported CDC specific descriptor");
break;
}
}
const usb_device_desc_t *device_desc;
const usb_config_desc_t *config_desc;
ESP_ERROR_CHECK_WITHOUT_ABORT(usb_host_get_device_descriptor(cdc_dev->dev_hdl, &device_desc));
ESP_ERROR_CHECK_WITHOUT_ABORT(usb_host_get_active_config_descriptor(cdc_dev->dev_hdl, &config_desc));
usb_print_device_descriptor(device_desc);
usb_print_config_descriptor(config_desc, cdc_acm_print_desc);
}
/**
@ -949,7 +969,7 @@ static void notif_xfer_cb(usb_transfer_t *transfer)
if (cdc_acm_is_transfer_completed(transfer)) {
cdc_notification_t *notif = (cdc_notification_t *)transfer->data_buffer;
switch (notif->bNotificationCode) {
case CDC_NOTIF_NETWORK_CONNECTION: {
case USB_CDC_NOTIF_NETWORK_CONNECTION: {
if (cdc_dev->notif.cb) {
const cdc_acm_host_dev_event_data_t net_conn_event = {
.type = CDC_ACM_HOST_NETWORK_CONNECTION,
@ -959,7 +979,7 @@ static void notif_xfer_cb(usb_transfer_t *transfer)
}
break;
}
case CDC_NOTIF_SERIAL_STATE: {
case USB_CDC_NOTIF_SERIAL_STATE: {
cdc_dev->serial_state.val = *((uint16_t *)notif->Data);
if (cdc_dev->notif.cb) {
const cdc_acm_host_dev_event_data_t serial_state_event = {
@ -970,7 +990,7 @@ static void notif_xfer_cb(usb_transfer_t *transfer)
}
break;
}
case CDC_NOTIF_RESPONSE_AVAILABLE: // Encapsulated commands not implemented - fallthrough
case USB_CDC_NOTIF_RESPONSE_AVAILABLE: // Encapsulated commands not implemented - fallthrough
default:
ESP_LOGW("CDC_ACM", "Unsupported notification type 0x%02X", notif->bNotificationCode);
ESP_LOG_BUFFER_HEX("CDC_ACM", transfer->data_buffer, transfer->actual_num_bytes);
@ -1063,7 +1083,7 @@ esp_err_t cdc_acm_host_line_coding_get(cdc_acm_dev_hdl_t cdc_hdl, cdc_acm_line_c
CDC_ACM_CHECK(cdc_hdl && line_coding, ESP_ERR_INVALID_ARG);
ESP_RETURN_ON_ERROR(
send_cdc_request((cdc_dev_t *)cdc_hdl, true, CDC_REQ_GET_LINE_CODING, (uint8_t *)line_coding, sizeof(cdc_acm_line_coding_t), 0),
send_cdc_request((cdc_dev_t *)cdc_hdl, true, USB_CDC_REQ_GET_LINE_CODING, (uint8_t *)line_coding, sizeof(cdc_acm_line_coding_t), 0),
TAG,);
ESP_LOGD(TAG, "Line Get: Rate: %d, Stop bits: %d, Parity: %d, Databits: %d", line_coding->dwDTERate,
line_coding->bCharFormat, line_coding->bParityType, line_coding->bDataBits);
@ -1075,7 +1095,7 @@ esp_err_t cdc_acm_host_line_coding_set(cdc_acm_dev_hdl_t cdc_hdl, const cdc_acm_
CDC_ACM_CHECK(cdc_hdl && line_coding, ESP_ERR_INVALID_ARG);
ESP_RETURN_ON_ERROR(
send_cdc_request((cdc_dev_t *)cdc_hdl, false, CDC_REQ_SET_LINE_CODING, (uint8_t *)line_coding, sizeof(cdc_acm_line_coding_t), 0),
send_cdc_request((cdc_dev_t *)cdc_hdl, false, USB_CDC_REQ_SET_LINE_CODING, (uint8_t *)line_coding, sizeof(cdc_acm_line_coding_t), 0),
TAG,);
ESP_LOGD(TAG, "Line Set: Rate: %d, Stop bits: %d, Parity: %d, Databits: %d", line_coding->dwDTERate,
line_coding->bCharFormat, line_coding->bParityType, line_coding->bDataBits);
@ -1089,7 +1109,7 @@ esp_err_t cdc_acm_host_set_control_line_state(cdc_acm_dev_hdl_t cdc_hdl, bool dt
const uint16_t ctrl_bitmap = (uint16_t)dtr | ((uint16_t)rts << 1);
ESP_RETURN_ON_ERROR(
send_cdc_request((cdc_dev_t *)cdc_hdl, false, CDC_REQ_SET_CONTROL_LINE_STATE, NULL, 0, ctrl_bitmap),
send_cdc_request((cdc_dev_t *)cdc_hdl, false, USB_CDC_REQ_SET_CONTROL_LINE_STATE, NULL, 0, ctrl_bitmap),
TAG,);
ESP_LOGD(TAG, "Control Line Set: DTR: %d, RTS: %d", dtr, rts);
return ESP_OK;
@ -1100,7 +1120,7 @@ esp_err_t cdc_acm_host_send_break(cdc_acm_dev_hdl_t cdc_hdl, uint16_t duration_m
CDC_ACM_CHECK(cdc_hdl, ESP_ERR_INVALID_ARG);
ESP_RETURN_ON_ERROR(
send_cdc_request((cdc_dev_t *)cdc_hdl, false, CDC_REQ_SEND_BREAK, NULL, 0, duration_ms),
send_cdc_request((cdc_dev_t *)cdc_hdl, false, USB_CDC_REQ_SEND_BREAK, NULL, 0, duration_ms),
TAG,);
// Block until break is deasserted

Wyświetl plik

@ -220,10 +220,9 @@ esp_err_t cdc_acm_host_set_control_line_state(cdc_acm_dev_hdl_t cdc_hdl, bool dt
esp_err_t cdc_acm_host_send_break(cdc_acm_dev_hdl_t cdc_hdl, uint16_t duration_ms);
/**
* @brief Print CDC-ACM specific descriptors
* @brief Print device's descriptors
*
* Descriptors are printed in human readable format to stdout.
* Intended for debugging and for CDC-ACM compliant devices only.
* Device and full Configuration descriptors are printed in human readable format to stdout.
*
* @param cdc_hdl CDC handle obtained from cdc_acm_host_open()
*/

Wyświetl plik

@ -13,33 +13,33 @@
* @see Table 13, USB CDC specification rev. 1.2
*/
typedef enum {
CDC_DESC_SUBTYPE_HEADER = 0x00, // Header Functional Descriptor
CDC_DESC_SUBTYPE_CALL = 0x01, // Call Management Functional Descriptor
CDC_DESC_SUBTYPE_ACM = 0x02, // Abstract Control Management Functional Descriptor
CDC_DESC_SUBTYPE_DLM = 0x03, // Direct Line Management Functional Descriptor
CDC_DESC_SUBTYPE_TEL_RINGER = 0x04, // Telephone Ringer Functional Descriptor
CDC_DESC_SUBTYPE_TEL_CLSR = 0x05, // Telephone Call and Line State Reporting Capabilities Functional Descriptor
CDC_DESC_SUBTYPE_UNION = 0x06, // Union Functional Descriptor
CDC_DESC_SUBTYPE_COUNTRY = 0x07, // Country Selection Functional Descriptor
CDC_DESC_SUBTYPE_TEL_MODE = 0x08, // Telephone Operational Modes Functional Descriptor
CDC_DESC_SUBTYPE_TERMINAL = 0x09, // USB Terminal
CDC_DESC_SUBTYPE_NCHT = 0x0A, // Network Channel Terminal
CDC_DESC_SUBTYPE_PROTOCOL = 0x08, // Protocol Unit
CDC_DESC_SUBTYPE_EXTENSION = 0x0C, // Extension Unit
CDC_DESC_SUBTYPE_MULTI_CHAN = 0x0D, // Multi-Channel Management Functional Descriptor
CDC_DESC_SUBTYPE_CAPI = 0x0E, // CAPI Control
CDC_DESC_SUBTYPE_ETH = 0x0F, // Ethernet Networking
CDC_DESC_SUBTYPE_ATM = 0x10, // ATM Networking
CDC_DESC_SUBTYPE_WHANDSET = 0x11, // Wireless Handset Control Model Functional Descriptor
CDC_DESC_SUBTYPE_MDLM = 0x12, // Mobile Direct Line Model
CDC_DESC_SUBTYPE_MDLM_DETAIL = 0x13, // MDLM Detail
CDC_DESC_SUBTYPE_DMM = 0x14, // Device Management Model
CDC_DESC_SUBTYPE_OBEX = 0x15, // OBEX Functional
CDC_DESC_SUBTYPE_COMMAND_SET = 0x16, // Command Set
CDC_DESC_SUBTYPE_COMMAND_SET_DETAIL = 0x17, // Command Set Detail Functional Descriptor
CDC_DESC_SUBTYPE_TEL_CM = 0x18, // Telephone Control Model Functional Descriptor
CDC_DESC_SUBTYPE_OBEX_SERVICE = 0x19, // OBEX Service Identifier Functional Descriptor
CDC_DESC_SUBTYPE_NCM = 0x1A // NCM Functional Descriptor
USB_CDC_DESC_SUBTYPE_HEADER = 0x00, // Header Functional Descriptor
USB_CDC_DESC_SUBTYPE_CALL = 0x01, // Call Management Functional Descriptor
USB_CDC_DESC_SUBTYPE_ACM = 0x02, // Abstract Control Management Functional Descriptor
USB_CDC_DESC_SUBTYPE_DLM = 0x03, // Direct Line Management Functional Descriptor
USB_CDC_DESC_SUBTYPE_TEL_RINGER = 0x04, // Telephone Ringer Functional Descriptor
USB_CDC_DESC_SUBTYPE_TEL_CLSR = 0x05, // Telephone Call and Line State Reporting Capabilities Functional Descriptor
USB_CDC_DESC_SUBTYPE_UNION = 0x06, // Union Functional Descriptor
USB_CDC_DESC_SUBTYPE_COUNTRY = 0x07, // Country Selection Functional Descriptor
USB_CDC_DESC_SUBTYPE_TEL_MODE = 0x08, // Telephone Operational Modes Functional Descriptor
USB_CDC_DESC_SUBTYPE_TERMINAL = 0x09, // USB Terminal
USB_CDC_DESC_SUBTYPE_NCHT = 0x0A, // Network Channel Terminal
USB_CDC_DESC_SUBTYPE_PROTOCOL = 0x08, // Protocol Unit
USB_CDC_DESC_SUBTYPE_EXTENSION = 0x0C, // Extension Unit
USB_CDC_DESC_SUBTYPE_MULTI_CHAN = 0x0D, // Multi-Channel Management Functional Descriptor
USB_CDC_DESC_SUBTYPE_CAPI = 0x0E, // CAPI Control
USB_CDC_DESC_SUBTYPE_ETH = 0x0F, // Ethernet Networking
USB_CDC_DESC_SUBTYPE_ATM = 0x10, // ATM Networking
USB_CDC_DESC_SUBTYPE_WHANDSET = 0x11, // Wireless Handset Control Model Functional Descriptor
USB_CDC_DESC_SUBTYPE_MDLM = 0x12, // Mobile Direct Line Model
USB_CDC_DESC_SUBTYPE_MDLM_DETAIL = 0x13, // MDLM Detail
USB_CDC_DESC_SUBTYPE_DMM = 0x14, // Device Management Model
USB_CDC_DESC_SUBTYPE_OBEX = 0x15, // OBEX Functional
USB_CDC_DESC_SUBTYPE_COMMAND_SET = 0x16, // Command Set
USB_CDC_DESC_SUBTYPE_COMMAND_SET_DETAIL = 0x17, // Command Set Detail Functional Descriptor
USB_CDC_DESC_SUBTYPE_TEL_CM = 0x18, // Telephone Control Model Functional Descriptor
USB_CDC_DESC_SUBTYPE_OBEX_SERVICE = 0x19, // OBEX Service Identifier Functional Descriptor
USB_CDC_DESC_SUBTYPE_NCM = 0x1A // NCM Functional Descriptor
} __attribute__((packed)) cdc_desc_subtype_t;
/**
@ -48,19 +48,19 @@ typedef enum {
* @see Table 4, USB CDC specification rev. 1.2
*/
typedef enum {
CDC_SUBCLASS_DLCM = 0x01, // Direct Line Control Model
CDC_SUBCLASS_ACM = 0x02, // Abstract Control Model
CDC_SUBCLASS_TCM = 0x03, // Telephone Control Model
CDC_SUBCLASS_MCHCM = 0x04, // Multi-Channel Control Model
CDC_SUBCLASS_CAPI = 0x05, // CAPI Control Model
CDC_SUBCLASS_ECM = 0x06, // Ethernet Networking Control Model
CDC_SUBCLASS_ATM = 0x07, // ATM Networking Model
CDC_SUBCLASS_HANDSET = 0x08, // Wireless Handset Control Model
CDC_SUBCLASS_DEV_MAN = 0x09, // Device Management
CDC_SUBCLASS_MOBILE = 0x0A, // Mobile Direct Line Model
CDC_SUBCLASS_OBEX = 0x0B, // OBEX
CDC_SUBCLASS_EEM = 0x0C, // Ethernet Emulation Model
CDC_SUBCLASS_NCM = 0x0D // Network Control Model
USB_CDC_SUBCLASS_DLCM = 0x01, // Direct Line Control Model
USB_CDC_SUBCLASS_ACM = 0x02, // Abstract Control Model
USB_CDC_SUBCLASS_TCM = 0x03, // Telephone Control Model
USB_CDC_SUBCLASS_MCHCM = 0x04, // Multi-Channel Control Model
USB_CDC_SUBCLASS_CAPI = 0x05, // CAPI Control Model
USB_CDC_SUBCLASS_ECM = 0x06, // Ethernet Networking Control Model
USB_CDC_SUBCLASS_ATM = 0x07, // ATM Networking Model
USB_CDC_SUBCLASS_HANDSET = 0x08, // Wireless Handset Control Model
USB_CDC_SUBCLASS_DEV_MAN = 0x09, // Device Management
USB_CDC_SUBCLASS_MOBILE = 0x0A, // Mobile Direct Line Model
USB_CDC_SUBCLASS_OBEX = 0x0B, // OBEX
USB_CDC_SUBCLASS_EEM = 0x0C, // Ethernet Emulation Model
USB_CDC_SUBCLASS_NCM = 0x0D // Network Control Model
} __attribute__((packed)) cdc_subclass_t;
/**
@ -69,16 +69,16 @@ typedef enum {
* @see Table 5, USB CDC specification rev. 1.2
*/
typedef enum {
CDC_COMM_PROTOCOL_NONE = 0x00, // No class specific protocol required
CDC_COMM_PROTOCOL_V250 = 0x01, // AT Commands: V.250 etc
CDC_COMM_PROTOCOL_PCAA = 0x02, // AT Commands defined by PCCA-101
CDC_COMM_PROTOCOL_PCAA_A = 0x03, // AT Commands defined by PCAA-101 & Annex O
CDC_COMM_PROTOCOL_GSM = 0x04, // AT Commands defined by GSM 07.07
CDC_COMM_PROTOCOL_3GPP = 0x05, // AT Commands defined by 3GPP 27.007
CDC_COMM_PROTOCOL_TIA = 0x06, // AT Commands defined by TIA for CDMA
CDC_COMM_PROTOCOL_EEM = 0x07, // Ethernet Emulation Model
CDC_COMM_PROTOCOL_EXT = 0xFE, // External Protocol: Commands defined by Command Set Functional Descriptor
CDC_COMM_PROTOCOL_VENDOR = 0xFF // Vendor-specific
USB_CDC_COMM_PROTOCOL_NONE = 0x00, // No class specific protocol required
USB_CDC_COMM_PROTOCOL_V250 = 0x01, // AT Commands: V.250 etc
USB_CDC_COMM_PROTOCOL_PCAA = 0x02, // AT Commands defined by PCCA-101
USB_CDC_COMM_PROTOCOL_PCAA_A = 0x03, // AT Commands defined by PCAA-101 & Annex O
USB_CDC_COMM_PROTOCOL_GSM = 0x04, // AT Commands defined by GSM 07.07
USB_CDC_COMM_PROTOCOL_3GPP = 0x05, // AT Commands defined by 3GPP 27.007
USB_CDC_COMM_PROTOCOL_TIA = 0x06, // AT Commands defined by TIA for CDMA
USB_CDC_COMM_PROTOCOL_EEM = 0x07, // Ethernet Emulation Model
USB_CDC_COMM_PROTOCOL_EXT = 0xFE, // External Protocol: Commands defined by Command Set Functional Descriptor
USB_CDC_COMM_PROTOCOL_VENDOR = 0xFF // Vendor-specific
} __attribute__((packed)) cdc_comm_protocol_t;
/**
@ -87,18 +87,18 @@ typedef enum {
* @see Table 7, USB CDC specification rev. 1.2
*/
typedef enum {
CDC_DATA_PROTOCOL_NONE = 0x00, // No class specific protocol required
CDC_DATA_PROTOCOL_NCM = 0x01, // Network Transfer Block
CDC_DATA_PROTOCOL_I430 = 0x30, // Physical interface protocol for ISDN BRI
CDC_DATA_PROTOCOL_HDLC = 0x31, // HDLC
CDC_DATA_PROTOCOL_Q921M = 0x50, // Management protocol for Q.921 data link protocol
CDC_DATA_PROTOCOL_Q921 = 0x51, // Data link protocol for Q.931
CDC_DATA_PROTOCOL_Q921TM = 0x52, // TEI-multiplexor for Q.921 data link protocol
CDC_DATA_PROTOCOL_V42BIS = 0x90, // Data compression procedures
CDC_DATA_PROTOCOL_Q931 = 0x91, // Euro-ISDN protocol control
CDC_DATA_PROTOCOL_V120 = 0x92, // V.24 rate adaptation to ISDN
CDC_DATA_PROTOCOL_CAPI = 0x93, // CAPI Commands
CDC_DATA_PROTOCOL_VENDOR = 0xFF // Vendor-specific
USB_CDC_DATA_PROTOCOL_NONE = 0x00, // No class specific protocol required
USB_CDC_DATA_PROTOCOL_NCM = 0x01, // Network Transfer Block
USB_CDC_DATA_PROTOCOL_I430 = 0x30, // Physical interface protocol for ISDN BRI
USB_CDC_DATA_PROTOCOL_HDLC = 0x31, // HDLC
USB_CDC_DATA_PROTOCOL_Q921M = 0x50, // Management protocol for Q.921 data link protocol
USB_CDC_DATA_PROTOCOL_Q921 = 0x51, // Data link protocol for Q.931
USB_CDC_DATA_PROTOCOL_Q921TM = 0x52, // TEI-multiplexor for Q.921 data link protocol
USB_CDC_DATA_PROTOCOL_V42BIS = 0x90, // Data compression procedures
USB_CDC_DATA_PROTOCOL_Q931 = 0x91, // Euro-ISDN protocol control
USB_CDC_DATA_PROTOCOL_V120 = 0x92, // V.24 rate adaptation to ISDN
USB_CDC_DATA_PROTOCOL_CAPI = 0x93, // CAPI Commands
USB_CDC_DATA_PROTOCOL_VENDOR = 0xFF // Vendor-specific
} __attribute__((packed)) cdc_data_protocol_t;
/**
@ -107,52 +107,52 @@ typedef enum {
* @see Table 19, USB CDC specification rev. 1.2
*/
typedef enum {
CDC_REQ_SEND_ENCAPSULATED_COMMAND = 0x00,
CDC_REQ_GET_ENCAPSULATED_RESPONSE = 0x01,
CDC_REQ_SET_COMM_FEATURE = 0x02,
CDC_REQ_GET_COMM_FEATURE = 0x03,
CDC_REQ_CLEAR_COMM_FEATURE = 0x04,
CDC_REQ_SET_AUX_LINE_STATE = 0x10,
CDC_REQ_SET_HOOK_STATE = 0x11,
CDC_REQ_PULSE_SETUP = 0x12,
CDC_REQ_SEND_PULSE = 0x13,
CDC_REQ_SET_PULSE_TIME = 0x14,
CDC_REQ_RING_AUX_JACK = 0x15,
CDC_REQ_SET_LINE_CODING = 0x20,
CDC_REQ_GET_LINE_CODING = 0x21,
CDC_REQ_SET_CONTROL_LINE_STATE = 0x22,
CDC_REQ_SEND_BREAK = 0x23,
CDC_REQ_SET_RINGER_PARMS = 0x30,
CDC_REQ_GET_RINGER_PARMS = 0x31,
CDC_REQ_SET_OPERATION_PARMS = 0x32,
CDC_REQ_GET_OPERATION_PARMS = 0x33,
CDC_REQ_SET_LINE_PARMS = 0x34,
CDC_REQ_GET_LINE_PARMS = 0x35,
CDC_REQ_DIAL_DIGITS = 0x36,
CDC_REQ_SET_UNIT_PARAMETER = 0x37,
CDC_REQ_GET_UNIT_PARAMETER = 0x38,
CDC_REQ_CLEAR_UNIT_PARAMETER = 0x39,
CDC_REQ_GET_PROFILE = 0x3A,
CDC_REQ_SET_ETHERNET_MULTICAST_FILTERS = 0x40,
CDC_REQ_SET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER = 0x41,
CDC_REQ_GET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER = 0x42,
CDC_REQ_SET_ETHERNET_PACKET_FILTER = 0x43,
CDC_REQ_GET_ETHERNET_STATISTIC = 0x44,
CDC_REQ_SET_ATM_DATA_FORMAT = 0x50,
CDC_REQ_GET_ATM_DEVICE_STATISTICS = 0x51,
CDC_REQ_SET_ATM_DEFAULT_VC = 0x52,
CDC_REQ_GET_ATM_VC_STATISTICS = 0x53,
CDC_REQ_GET_NTB_PARAMETERS = 0x80,
CDC_REQ_GET_NET_ADDRESS = 0x81,
CDC_REQ_SET_NET_ADDRESS = 0x82,
CDC_REQ_GET_NTB_FORMAT = 0x83,
CDC_REQ_SET_NTB_FORMAT = 0x84,
CDC_REQ_GET_NTB_INPUT_SIZE = 0x85,
CDC_REQ_SET_NTB_INPUT_SIZE = 0x86,
CDC_REQ_GET_MAX_DATAGRAM_SIZE = 0x87,
CDC_REQ_SET_MAX_DATAGRAM_SIZE = 0x88,
CDC_REQ_GET_CRC_MODE = 0x89,
CDC_REQ_SET_CRC_MODE = 0x8A
USB_CDC_REQ_SEND_ENCAPSULATED_COMMAND = 0x00,
USB_CDC_REQ_GET_ENCAPSULATED_RESPONSE = 0x01,
USB_CDC_REQ_SET_COMM_FEATURE = 0x02,
USB_CDC_REQ_GET_COMM_FEATURE = 0x03,
USB_CDC_REQ_CLEAR_COMM_FEATURE = 0x04,
USB_CDC_REQ_SET_AUX_LINE_STATE = 0x10,
USB_CDC_REQ_SET_HOOK_STATE = 0x11,
USB_CDC_REQ_PULSE_SETUP = 0x12,
USB_CDC_REQ_SEND_PULSE = 0x13,
USB_CDC_REQ_SET_PULSE_TIME = 0x14,
USB_CDC_REQ_RING_AUX_JACK = 0x15,
USB_CDC_REQ_SET_LINE_CODING = 0x20,
USB_CDC_REQ_GET_LINE_CODING = 0x21,
USB_CDC_REQ_SET_CONTROL_LINE_STATE = 0x22,
USB_CDC_REQ_SEND_BREAK = 0x23,
USB_CDC_REQ_SET_RINGER_PARMS = 0x30,
USB_CDC_REQ_GET_RINGER_PARMS = 0x31,
USB_CDC_REQ_SET_OPERATION_PARMS = 0x32,
USB_CDC_REQ_GET_OPERATION_PARMS = 0x33,
USB_CDC_REQ_SET_LINE_PARMS = 0x34,
USB_CDC_REQ_GET_LINE_PARMS = 0x35,
USB_CDC_REQ_DIAL_DIGITS = 0x36,
USB_CDC_REQ_SET_UNIT_PARAMETER = 0x37,
USB_CDC_REQ_GET_UNIT_PARAMETER = 0x38,
USB_CDC_REQ_CLEAR_UNIT_PARAMETER = 0x39,
USB_CDC_REQ_GET_PROFILE = 0x3A,
USB_CDC_REQ_SET_ETHERNET_MULTICAST_FILTERS = 0x40,
USB_CDC_REQ_SET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER = 0x41,
USB_CDC_REQ_GET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER = 0x42,
USB_CDC_REQ_SET_ETHERNET_PACKET_FILTER = 0x43,
USB_CDC_REQ_GET_ETHERNET_STATISTIC = 0x44,
USB_CDC_REQ_SET_ATM_DATA_FORMAT = 0x50,
USB_CDC_REQ_GET_ATM_DEVICE_STATISTICS = 0x51,
USB_CDC_REQ_SET_ATM_DEFAULT_VC = 0x52,
USB_CDC_REQ_GET_ATM_VC_STATISTICS = 0x53,
USB_CDC_REQ_GET_NTB_PARAMETERS = 0x80,
USB_CDC_REQ_GET_NET_ADDRESS = 0x81,
USB_CDC_REQ_SET_NET_ADDRESS = 0x82,
USB_CDC_REQ_GET_NTB_FORMAT = 0x83,
USB_CDC_REQ_SET_NTB_FORMAT = 0x84,
USB_CDC_REQ_GET_NTB_INPUT_SIZE = 0x85,
USB_CDC_REQ_SET_NTB_INPUT_SIZE = 0x86,
USB_CDC_REQ_GET_MAX_DATAGRAM_SIZE = 0x87,
USB_CDC_REQ_SET_MAX_DATAGRAM_SIZE = 0x88,
USB_CDC_REQ_GET_CRC_MODE = 0x89,
USB_CDC_REQ_SET_CRC_MODE = 0x8A
} __attribute__((packed)) cdc_request_code_t;
/**
@ -161,14 +161,14 @@ typedef enum {
* @see Table 20, USB CDC specification rev. 1.2
*/
typedef enum {
CDC_NOTIF_NETWORK_CONNECTION = 0x00,
CDC_NOTIF_RESPONSE_AVAILABLE = 0x01,
CDC_NOTIF_AUX_JACK_HOOK_STATE = 0x08,
CDC_NOTIF_RING_DETECT = 0x09,
CDC_NOTIF_SERIAL_STATE = 0x20,
CDC_NOTIF_CALL_STATE_CHANGE = 0x28,
CDC_NOTIF_LINE_STATE_CHANGE = 0x29,
CDC_NOTIF_CONNECTION_SPEED_CHANGE = 0x2A
USB_CDC_NOTIF_NETWORK_CONNECTION = 0x00,
USB_CDC_NOTIF_RESPONSE_AVAILABLE = 0x01,
USB_CDC_NOTIF_AUX_JACK_HOOK_STATE = 0x08,
USB_CDC_NOTIF_RING_DETECT = 0x09,
USB_CDC_NOTIF_SERIAL_STATE = 0x20,
USB_CDC_NOTIF_CALL_STATE_CHANGE = 0x28,
USB_CDC_NOTIF_LINE_STATE_CHANGE = 0x29,
USB_CDC_NOTIF_CONNECTION_SPEED_CHANGE = 0x2A
} __attribute__((packed)) cdc_notification_code_t;
typedef struct {

Wyświetl plik

@ -1,3 +1,3 @@
idf_component_register(SRCS "test_cdc_acm_host.c"
idf_component_register(SRCS "test_cdc_acm_host.c" "usb_device.c"
INCLUDE_DIRS "."
REQUIRES cdc_acm_host unity)
REQUIRES cdc_acm_host tinyusb unity)

Wyświetl plik

@ -1,7 +1,7 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
* SPDX-License-Identifier: CC0-1.0
*/
#include "soc/soc_caps.h"
@ -42,7 +42,7 @@ static void force_conn_state(bool connected, TickType_t delay_ticks)
void usb_lib_task(void *arg)
{
//Initialize the internal USB PHY to connect to the USB OTG peripheral. We manually install the USB PHY for testing
// Initialize the internal USB PHY to connect to the USB OTG peripheral. We manually install the USB PHY for testing
usb_phy_config_t phy_config = {
.controller = USB_PHY_CTRL_OTG,
.target = USB_PHY_TARGET_INT,
@ -60,27 +60,27 @@ void usb_lib_task(void *arg)
printf("USB Host installed\n");
xTaskNotifyGive(arg);
while (1) {
bool all_clients_gone = false;
bool all_dev_free = false;
while (!all_clients_gone || !all_dev_free) {
// Start handling system events
uint32_t event_flags;
usb_host_lib_handle_events(portMAX_DELAY, &event_flags);
if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) {
printf("No more clients: clean up\n");
// The device should not have been freed yet, so we expect an ESP_ERR_NOT_FINISHED
TEST_ASSERT_EQUAL(ESP_ERR_NOT_FINISHED, usb_host_device_free_all());
printf("No more clients\n");
usb_host_device_free_all();
all_clients_gone = true;
}
if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) {
printf("All free: uninstall USB lib\n");
break;
printf("All devices freed\n");
all_dev_free = true;
}
}
// Clean up USB Host
vTaskDelay(10); // Short delay to allow clients clean-up
usb_host_lib_handle_events(0, NULL); // Make sure there are now pending events
TEST_ASSERT_EQUAL(ESP_OK, usb_host_uninstall());
//Tear down USB PHY
TEST_ASSERT_EQUAL(ESP_OK, usb_del_phy(phy_hdl));
TEST_ASSERT_EQUAL(ESP_OK, usb_del_phy(phy_hdl)); //Tear down USB PHY
phy_hdl = NULL;
vTaskDelete(NULL);
}
@ -88,7 +88,7 @@ void usb_lib_task(void *arg)
void test_install_cdc_driver(void)
{
// Create a task that will handle USB library events
TEST_ASSERT_EQUAL(pdTRUE, xTaskCreate(usb_lib_task, "usb_lib", 4*4096, xTaskGetCurrentTaskHandle(), 10, NULL));
TEST_ASSERT_EQUAL(pdTRUE, xTaskCreatePinnedToCore(usb_lib_task, "usb_lib", 4*4096, xTaskGetCurrentTaskHandle(), 10, NULL, 0));
ulTaskNotifyTake(false, 1000);
printf("Installing CDC-ACM driver\n");
@ -133,7 +133,7 @@ static void notif_cb(cdc_acm_dev_hdl_t cdc_hdl, const cdc_acm_host_dev_event_dat
/* Basic test to check CDC communication:
* open/read/write/close device
* CDC-ACM specific commands: set/get_line_coding, set_control_line_state */
TEST_CASE("USB Host CDC-ACM driver: Basic test", "[cdc_acm][ignore]")
TEST_CASE("read_write", "[cdc_acm]")
{
nb_of_responses = 0;
cdc_acm_dev_hdl_t cdc_dev = NULL;
@ -180,7 +180,7 @@ TEST_CASE("USB Host CDC-ACM driver: Basic test", "[cdc_acm][ignore]")
}
/* Test communication with multiple CDC-ACM devices from one thread */
TEST_CASE("USB Host CDC-ACM driver: Multiple devices test", "[cdc_acm][ignore]")
TEST_CASE("multiple_devices", "[cdc_acm]")
{
nb_of_responses = 0;
nb_of_responses2 = 0;
@ -244,7 +244,7 @@ void tx_task(void *arg)
* In this test, one CDC device is accessed from multiple threads.
* It has to be opened/closed just once, though.
*/
TEST_CASE("USB Host CDC-ACM driver: Multiple threads test", "[cdc_acm][ignore]")
TEST_CASE("multiple_threads", "[cdc_acm]")
{
nb_of_responses = 0;
cdc_acm_dev_hdl_t cdc_dev;
@ -278,7 +278,7 @@ TEST_CASE("USB Host CDC-ACM driver: Multiple threads test", "[cdc_acm][ignore]")
}
/* Test CDC driver reaction to USB device sudden disconnection */
TEST_CASE("USB Host CDC-ACM driver: Sudden disconnection test", "[cdc_acm][ignore]")
TEST_CASE("sudden_disconnection", "[cdc_acm]")
{
test_install_cdc_driver();
@ -293,11 +293,9 @@ TEST_CASE("USB Host CDC-ACM driver: Sudden disconnection test", "[cdc_acm][ignor
TEST_ASSERT_EQUAL(ESP_OK, cdc_acm_host_open(0x303A, 0x4002, 0, &dev_config, &cdc_dev));
TEST_ASSERT_NOT_NULL(cdc_dev);
force_conn_state(false, pdMS_TO_TICKS(10));
// Notify will succeed only if CDC_ACM_HOST_DEVICE_DISCONNECTED notification was generated
TEST_ASSERT_EQUAL(1, ulTaskNotifyTake(false, pdMS_TO_TICKS(100)));
force_conn_state(false, pdMS_TO_TICKS(10)); // Simulate device disconnection
TEST_ASSERT_EQUAL(1, ulTaskNotifyTake(false, pdMS_TO_TICKS(100))); // Notify will succeed only if CDC_ACM_HOST_DEVICE_DISCONNECTED notification was generated
force_conn_state(true, 0); // Switch back to real PHY
TEST_ASSERT_EQUAL(ESP_OK, cdc_acm_host_uninstall());
vTaskDelay(20); //Short delay to allow task to be cleaned up
}
@ -317,7 +315,7 @@ TEST_CASE("USB Host CDC-ACM driver: Sudden disconnection test", "[cdc_acm][ignor
* -# Send unsupported CDC request
* -# Write to read-only device
*/
TEST_CASE("USB Host CDC-ACM driver: Error handling", "[cdc_acm][ignore]")
TEST_CASE("error_handling", "[cdc_acm]")
{
cdc_acm_dev_hdl_t cdc_dev;
cdc_acm_host_device_config_t dev_config = {
@ -347,10 +345,10 @@ TEST_CASE("USB Host CDC-ACM driver: Error handling", "[cdc_acm][ignore]")
TEST_ASSERT_EQUAL(ESP_OK, cdc_acm_host_open(0x303A, 0x4002, 0, &dev_config, &cdc_dev));
TEST_ASSERT_NOT_NULL(cdc_dev);
// Open one CDC-ACM device twice //@todo this test is commented out due to bug in usb_host
//cdc_acm_dev_hdl_t cdc_dev_test;
//TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, cdc_acm_host_open(0x303A, 0x4002, 0, &dev_config, &cdc_dev_test));
//TEST_ASSERT_NULL(cdc_dev_test);
// Open one CDC-ACM device twice
cdc_acm_dev_hdl_t cdc_dev_test;
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, cdc_acm_host_open(0x303A, 0x4002, 0, &dev_config, &cdc_dev_test));
TEST_ASSERT_NULL(cdc_dev_test);
// Uninstall driver with open devices
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, cdc_acm_host_uninstall());
@ -375,4 +373,11 @@ TEST_CASE("USB Host CDC-ACM driver: Error handling", "[cdc_acm][ignore]")
vTaskDelay(20);
}
/* Following test case implements dual CDC-ACM USB device that can be used as mock device for CDC-ACM Host tests */
void run_usb_dual_cdc_device(void);
TEST_CASE("mock_device_app", "[cdc_acm_device][ignore]")
{
run_usb_dual_cdc_device();
}
#endif

Wyświetl plik

@ -0,0 +1,71 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
#include <stdint.h>
#include "sdkconfig.h"
#include "tinyusb.h"
#include "tusb_cdc_acm.h"
static uint8_t buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE + 1];
void tinyusb_cdc_rx_callback(int itf, cdcacm_event_t *event)
{
size_t rx_size = 0;
/* read and write back */
ESP_ERROR_CHECK(tinyusb_cdcacm_read(itf, buf, CONFIG_TINYUSB_CDC_RX_BUFSIZE, &rx_size));
tinyusb_cdcacm_write_queue(itf, buf, rx_size);
tinyusb_cdcacm_write_flush(itf, 0);
}
static const tusb_desc_device_t cdc_device_descriptor = {
.bLength = sizeof(cdc_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 = USB_ESPRESSIF_VID,
.idProduct = 0x4002,
.bcdDevice = 0x0100,
.iManufacturer = 0x01,
.iProduct = 0x02,
.iSerialNumber = 0x03,
.bNumConfigurations = 0x01
};
const uint16_t cdc_desc_config_len = TUD_CONFIG_DESC_LEN + 2 * TUD_CDC_DESC_LEN;
static const uint8_t cdc_desc_configuration[] = {
TUD_CONFIG_DESCRIPTOR(1, 4, 0, cdc_desc_config_len, 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),
};
void run_usb_dual_cdc_device(void)
{
const tinyusb_config_t tusb_cfg = {
.device_descriptor = &cdc_device_descriptor,
.configuration_descriptor = cdc_desc_configuration
};
ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
tinyusb_config_cdcacm_t amc_cfg = {
.usb_dev = TINYUSB_USBDEV_0,
.cdc_port = TINYUSB_CDC_ACM_0,
.rx_unread_buf_sz = 64,
.callback_rx = &tinyusb_cdc_rx_callback,
.callback_rx_wanted_char = NULL,
.callback_line_state_changed = NULL,
.callback_line_coding_changed = NULL
};
ESP_ERROR_CHECK(tusb_cdc_acm_init(&amc_cfg));
#if (CONFIG_TINYUSB_CDC_COUNT > 1)
amc_cfg.cdc_port = TINYUSB_CDC_ACM_1;
ESP_ERROR_CHECK(tusb_cdc_acm_init(&amc_cfg));
#endif
printf("USB initialization DONE\n");
}

Wyświetl plik

@ -50,7 +50,7 @@ static const char *TAG = "msc_example";
/**** Kconfig driven Descriptor ****/
tusb_desc_device_t device_descriptor = {
static const tusb_desc_device_t device_descriptor = {
.bLength = sizeof(device_descriptor),
.bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = 0x0200,
@ -67,12 +67,20 @@ tusb_desc_device_t device_descriptor = {
.bNumConfigurations = 0x01
};
const uint16_t msc_desc_config_len = TUD_CONFIG_DESC_LEN + CFG_TUD_MSC * TUD_MSC_DESC_LEN;
static const uint8_t msc_desc_configuration[] = {
TUD_CONFIG_DESCRIPTOR(1, 4, 0, msc_desc_config_len, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
TUD_MSC_DESCRIPTOR(0, 5, 1, 0x80 | 1, 64),
};
void device_app(void)
{
ESP_LOGI(TAG, "USB initialization");
tinyusb_config_t tusb_cfg = {
.descriptor = &device_descriptor
.device_descriptor = &device_descriptor,
.configuration_descriptor = msc_desc_configuration
};
ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
@ -83,7 +91,6 @@ void device_app(void)
}
}
// whether host does safe-eject
static bool ejected = false;
@ -108,7 +115,7 @@ uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] = {
// Zero up to 2 last bytes of FAT magic code
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 'F', 'A', 'T', '3', '2', ' ', ' ', ' ', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -292,4 +299,4 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void *buffer,
return resplen;
}
#endif
#endif /* SOC_USB_OTG_SUPPORTED */

Wyświetl plik

@ -1,7 +1,7 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
* SPDX-License-Identifier: CC0-1.0
*/
#pragma once

Wyświetl plik

@ -2,7 +2,7 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
* SPDX-License-Identifier: CC0-1.0
*/
#include "unity.h"
@ -50,7 +50,7 @@ static usb_phy_handle_t phy_hdl = NULL;
static void force_conn_state(bool connected, TickType_t delay_ticks)
{
TEST_ASSERT_NOT_EQUAL(NULL, phy_hdl);
TEST_ASSERT(phy_hdl);
if (delay_ticks > 0) {
//Delay of 0 ticks causes a yield. So skip if delay_ticks is 0.
vTaskDelay(delay_ticks);
@ -62,7 +62,7 @@ static void msc_event_cb(const msc_host_event_t *event, void *arg)
{
if (waiting_for_sudden_disconnect) {
waiting_for_sudden_disconnect = false;
TEST_ASSERT(event->event == MSC_DEVICE_DISCONNECTED);
TEST_ASSERT_EQUAL(MSC_DEVICE_DISCONNECTED, event->event);
}
if (event->event == MSC_DEVICE_CONNECTED) {
@ -83,12 +83,12 @@ static void write_read_file(const char *file_path)
ESP_LOGI(TAG, "Writing file");
FILE *f = fopen(file_path, "w");
TEST_ASSERT( f != NULL);
TEST_ASSERT(f);
fprintf(f, TEST_STRING);
fclose(f);
ESP_LOGI(TAG, "Reading file");
TEST_ASSERT( fopen(file_path, "r") != NULL);
TEST_ASSERT(fopen(file_path, "r"));
fgets(line, sizeof(line), f);
fclose(f);
// strip newline
@ -138,7 +138,7 @@ static void check_file_content(const char *file_path, const char *expected)
{
ESP_LOGI(TAG, "Reading %s:", file_path);
FILE *file = fopen(file_path, "r");
TEST_ASSERT(file != NULL)
TEST_ASSERT(file)
char content[200];
fread(content, 1, sizeof(content), file);
@ -153,12 +153,12 @@ static void check_sudden_disconnect(void)
ESP_LOGI(TAG, "Creating test.tx");
FILE *file = fopen("/usb/test.txt", "w");
TEST_ASSERT( file != NULL);
TEST_ASSERT(file);
ESP_LOGI(TAG, "Write data");
TEST_ASSERT( fwrite(data, 1, DATA_SIZE, file) == DATA_SIZE );
TEST_ASSERT( fwrite(data, 1, DATA_SIZE, file) == DATA_SIZE );
TEST_ASSERT( fflush(file) == 0 );
TEST_ASSERT_EQUAL(DATA_SIZE, fwrite(data, 1, DATA_SIZE, file));
TEST_ASSERT_EQUAL(DATA_SIZE, fwrite(data, 1, DATA_SIZE, file));
TEST_ASSERT_EQUAL(0, fflush(file));
ESP_LOGI(TAG, "Trigger a disconnect");
//Trigger a disconnect
@ -167,10 +167,10 @@ static void check_sudden_disconnect(void)
// Make sure flag was leared in callback
vTaskDelay( pdMS_TO_TICKS(100) );
TEST_ASSERT( waiting_for_sudden_disconnect == false );
TEST_ASSERT_FALSE(waiting_for_sudden_disconnect);
ESP_LOGI(TAG, "Write data after disconnect");
TEST_ASSERT( fwrite(data, 1, DATA_SIZE, file) != DATA_SIZE );
TEST_ASSERT_NOT_EQUAL( DATA_SIZE, fwrite(data, 1, DATA_SIZE, file));
fclose(file);
}
@ -191,14 +191,14 @@ static void msc_setup(void)
.otg_speed = USB_PHY_SPEED_UNDEFINED, //In Host mode, the speed is determined by the connected device
.gpio_conf = NULL,
};
TEST_ASSERT_EQUAL(ESP_OK, usb_new_phy(&phy_config, &phy_hdl));
ESP_OK_ASSERT(usb_new_phy(&phy_config, &phy_hdl));
const usb_host_config_t host_config = {
.skip_phy_setup = true,
.intr_flags = ESP_INTR_FLAG_LEVEL1,
};
ESP_OK_ASSERT( usb_host_install(&host_config) );
task_created = xTaskCreate(handle_usb_events, "usb_events", 2048, NULL, 2, NULL);
task_created = xTaskCreatePinnedToCore(handle_usb_events, "usb_events", 2048, NULL, 2, NULL, 0);
TEST_ASSERT(task_created);
const msc_host_driver_config_t msc_config = {
@ -212,7 +212,7 @@ static void msc_setup(void)
ESP_LOGI(TAG, "Waiting for USB stick to be connected");
msc_host_event_t app_event;
xQueueReceive(app_queue, &app_event, portMAX_DELAY);
TEST_ASSERT( app_event.event == MSC_DEVICE_CONNECTED );
TEST_ASSERT_EQUAL(MSC_DEVICE_CONNECTED, app_event.event);
uint8_t device_addr = app_event.device.address;
ESP_OK_ASSERT( msc_host_install_device(device_addr, &device) );
@ -232,7 +232,7 @@ static void msc_teardown(void)
vSemaphoreDelete(ready_to_deinit_usb);
ESP_OK_ASSERT( usb_host_uninstall() );
//Tear down USB PHY
TEST_ASSERT_EQUAL(ESP_OK, usb_del_phy(phy_hdl));
ESP_OK_ASSERT(usb_del_phy(phy_hdl));
phy_hdl = NULL;
vQueueDelete(app_queue);
@ -262,35 +262,40 @@ static void erase_storage(void)
}
}
static void check_readme_content(void)
{
msc_setup();
check_file_content("/usb/README.TXT", README_CONTENTS);
msc_teardown();
}
TEST_CASE("Write and read file", "[usb_msc][ignore]")
TEST_CASE("write_and_read_file", "[usb_msc]")
{
msc_setup();
write_read_file(FILE_NAME);
msc_teardown();
}
TEST_CASE("Sudden disconnect", "[usb_msc][ignore]")
TEST_CASE("sudden_disconnect", "[usb_msc]")
{
msc_setup();
check_sudden_disconnect();
msc_teardown();
}
void read_write_sectors(void)
TEST_CASE("sectors_can_be_written_and_read", "[usb_msc]")
{
msc_setup();
write_read_sectors();
msc_teardown();
}
void check_formatting(void)
TEST_CASE("check_README_content", "[usb_msc]")
{
msc_setup();
check_file_content("/usb/README.TXT", README_CONTENTS);
msc_teardown();
}
/**
* @brief USB MSC format testcase
* @attention This testcase deletes all content on the USB MSC device.
* The device must be reset in order to contain the FILE_NAME again.
*/
TEST_CASE("can_be_formated", "[usb_msc]")
{
printf("Create file\n");
msc_setup();
@ -299,7 +304,7 @@ void check_formatting(void)
printf("File exists after mounting again\n");
msc_setup();
TEST_ASSERT( file_exists(FILE_NAME) );
TEST_ASSERT(file_exists(FILE_NAME));
printf("Erase storage device\n");
erase_storage();
msc_teardown();
@ -307,15 +312,14 @@ void check_formatting(void)
printf("Check file does not exist after formatting\n");
mount_config.format_if_mount_failed = true;
msc_setup();
TEST_ASSERT( !file_exists(FILE_NAME) );
TEST_ASSERT_FALSE(file_exists(FILE_NAME));
msc_teardown();
mount_config.format_if_mount_failed = false;
}
TEST_CASE_MULTIPLE_DEVICES("Sectors can be written and read", "[usb_msc][ignore]", read_write_sectors, device_app);
TEST_CASE_MULTIPLE_DEVICES("Can be Formated", "[usb_msc][ignore]", check_formatting, device_app);
TEST_CASE_MULTIPLE_DEVICES("Check README content", "[usb_msc][ignore]", check_readme_content, device_app);
TEST_CASE("mock_device_app", "[usb_msc_device][ignore]")
{
device_app();
}
#endif

Wyświetl plik

@ -25,6 +25,7 @@ markers =
ip101: connected via wired 10/100M ethernet
lan8720: connected via LAN8720 ethernet transceiver
octal_psram: runners with octal psram
usb_host: usb host runners
# log related
log_cli = True

Wyświetl plik

@ -7,6 +7,18 @@
#include <stdio.h>
#include <string.h>
#include "unity.h"
#include "esp_heap_caps.h"
static size_t before_free_8bit;
static size_t before_free_32bit;
#define TEST_MEMORY_LEAK_THRESHOLD (-10000) // @todo MSC test are leaking memory
static void check_leak(size_t before_free, size_t after_free, const char *type)
{
ssize_t delta = after_free - before_free;
printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta);
TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak");
}
void app_main(void)
{
@ -14,3 +26,19 @@ void app_main(void)
unity_run_menu();
UNITY_END();
}
/* setUp runs before every test */
void setUp(void)
{
before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
}
/* tearDown runs after every test */
void tearDown(void)
{
size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
check_leak(before_free_8bit, after_free_8bit, "8BIT");
check_leak(before_free_32bit, after_free_32bit, "32BIT");
}

Wyświetl plik

@ -0,0 +1,40 @@
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
from typing import Tuple
import pytest
from pytest_embedded_idf.dut import IdfDut
@pytest.mark.esp32s2
@pytest.mark.esp32s3
@pytest.mark.usb_host
@pytest.mark.parametrize('count', [
2,
], indirect=True)
def test_usb_host(dut: Tuple[IdfDut, IdfDut]) -> None:
device = dut[0]
host = dut[1]
# 1.1 Prepare USB device for CDC test
device.expect_exact('Press ENTER to see the list of tests.')
device.write('[cdc_acm_device]')
device.expect_exact('USB initialization DONE')
# 1.2 Run CDC test
host.expect_exact('Press ENTER to see the list of tests.')
host.write('[cdc_acm]')
host.expect_unity_test_output()
host.expect_exact("Enter next test, or 'enter' to see menu")
# 2.1 Prepare USB device for MSC test
device.serial.hard_reset()
device.expect_exact('Press ENTER to see the list of tests.')
device.write('[usb_msc_device]')
device.expect_exact('USB initialization DONE')
# 2.2 Run MSC test
host.write('[usb_msc]')
host.expect_unity_test_output()
host.expect_exact("Enter next test, or 'enter' to see menu")

Wyświetl plik

@ -1,4 +1,16 @@
# Configure TinyUSB, it will be used to mock USB devices
CONFIG_TINYUSB=y
CONFIG_TINYUSB_MSC_ENABLED=y
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