mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-05 05:34:32 +02:00
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
This commit is contained in:
@@ -196,6 +196,16 @@ test_app_test_pytest_esp32c3_generic:
|
|||||||
TARGET: ESP32C3
|
TARGET: ESP32C3
|
||||||
ENV_MARKER: generic
|
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")
|
# 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"
|
# we need to convert to pattern "job_name_index.yml"
|
||||||
.define_config_file_name: &define_config_file_name |
|
.define_config_file_name: &define_config_file_name |
|
||||||
|
@@ -116,7 +116,6 @@ menu "TinyUSB Stack"
|
|||||||
|
|
||||||
menu "Massive Storage Class (MSC)"
|
menu "Massive Storage Class (MSC)"
|
||||||
config TINYUSB_MSC_ENABLED
|
config TINYUSB_MSC_ENABLED
|
||||||
depends on TINYUSB_CDC_COUNT < 2
|
|
||||||
bool "Enable TinyUSB MSC feature"
|
bool "Enable TinyUSB MSC feature"
|
||||||
default n
|
default n
|
||||||
help
|
help
|
||||||
|
@@ -64,9 +64,13 @@ extern "C" {
|
|||||||
* @brief Configuration structure of the tinyUSB core
|
* @brief Configuration structure of the tinyUSB core
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
tusb_desc_device_t *descriptor; /*!< Pointer to a device descriptor */
|
union {
|
||||||
const char **string_descriptor; /*!< Pointer to an array of string descriptors */
|
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 */
|
||||||
bool external_phy; /*!< Should USB use an external PHY */
|
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;
|
} tinyusb_config_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -12,7 +12,6 @@ extern "C" {
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/ringbuf.h"
|
|
||||||
#include "freertos/semphr.h"
|
#include "freertos/semphr.h"
|
||||||
#include "freertos/timers.h"
|
#include "freertos/timers.h"
|
||||||
#include "tusb.h"
|
#include "tusb.h"
|
||||||
|
@@ -12,7 +12,6 @@ extern "C" {
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/ringbuf.h"
|
|
||||||
#include "freertos/semphr.h"
|
#include "freertos/semphr.h"
|
||||||
#include "freertos/timers.h"
|
#include "freertos/timers.h"
|
||||||
#include "tusb.h"
|
#include "tusb.h"
|
||||||
|
@@ -6,49 +6,14 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string.h>
|
#include "tusb.h"
|
||||||
#include "usb_descriptors.h"
|
#include "tinyusb_types.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
//------------- HID Report Descriptor -------------//
|
|
||||||
#if CFG_TUD_HID
|
|
||||||
enum {
|
|
||||||
REPORT_ID_KEYBOARD = 1,
|
|
||||||
REPORT_ID_MOUSE
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//------------- Configuration Descriptor -------------//
|
void tusb_set_descriptor(const tusb_desc_device_t *dev_desc, const char **str_desc, const uint8_t *cfg_desc);
|
||||||
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);
|
|
||||||
tusb_desc_device_t *tusb_get_active_desc(void);
|
tusb_desc_device_t *tusb_get_active_desc(void);
|
||||||
char **tusb_get_active_str_desc(void);
|
char **tusb_get_active_str_desc(void);
|
||||||
void tusb_clear_descriptor(void);
|
void tusb_clear_descriptor(void);
|
||||||
|
@@ -18,8 +18,9 @@ extern "C" {
|
|||||||
extern tusb_desc_device_t descriptor_tinyusb;
|
extern tusb_desc_device_t descriptor_tinyusb;
|
||||||
extern tusb_desc_strarray_device_t descriptor_str_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 tusb_desc_strarray_device_t descriptor_str_kconfig;
|
||||||
|
extern const uint8_t descriptor_cfg_kconfig[];
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@@ -4,49 +4,16 @@
|
|||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "descriptors_control.h"
|
#include "descriptors_control.h"
|
||||||
|
|
||||||
static const char *TAG = "tusb_desc";
|
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];
|
static char *s_str_descriptor[USB_STRING_DESCRIPTOR_ARRAY_SIZE];
|
||||||
#define MAX_DESC_BUF_SIZE 32
|
#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
|
// CALLBACKS
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
@@ -59,7 +26,7 @@ uint8_t const desc_configuration[] = {
|
|||||||
*/
|
*/
|
||||||
uint8_t const *tud_descriptor_device_cb(void)
|
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)
|
uint8_t const *tud_descriptor_configuration_cb(uint8_t index)
|
||||||
{
|
{
|
||||||
(void)index; // for multiple configurations
|
(void)index; // for multiple configurations
|
||||||
return desc_configuration;
|
return s_configuration_descriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t _desc_str[MAX_DESC_BUF_SIZE];
|
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;
|
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
|
// 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"
|
ESP_LOGI(TAG, "\n"
|
||||||
"┌─────────────────────────────────┐\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->idVendor, dev_desc->idProduct, dev_desc->bcdDevice,
|
||||||
dev_desc->iManufacturer, dev_desc->iProduct, dev_desc->iSerialNumber,
|
dev_desc->iManufacturer, dev_desc->iProduct, dev_desc->iSerialNumber,
|
||||||
dev_desc->bNumConfigurations);
|
dev_desc->bNumConfigurations);
|
||||||
s_descriptor = *dev_desc;
|
s_device_descriptor = *dev_desc;
|
||||||
|
s_configuration_descriptor = cfg_desc;
|
||||||
|
|
||||||
if (str_desc != NULL) {
|
if (str_desc != NULL) {
|
||||||
memcpy(s_str_descriptor, str_desc,
|
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)
|
tusb_desc_device_t *tusb_get_active_desc(void)
|
||||||
{
|
{
|
||||||
return &s_descriptor;
|
return &s_device_descriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
char **tusb_get_active_str_desc(void)
|
char **tusb_get_active_str_desc(void)
|
||||||
@@ -185,6 +139,6 @@ char **tusb_get_active_str_desc(void)
|
|||||||
|
|
||||||
void tusb_clear_descriptor(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));
|
memset(&s_str_descriptor, 0, sizeof(s_str_descriptor));
|
||||||
}
|
}
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
#include "soc/usb_pins.h"
|
#include "soc/usb_pins.h"
|
||||||
#include "tinyusb.h"
|
#include "tinyusb.h"
|
||||||
#include "descriptors_control.h"
|
#include "descriptors_control.h"
|
||||||
|
#include "usb_descriptors.h"
|
||||||
#include "tusb.h"
|
#include "tusb.h"
|
||||||
#include "tusb_tasks.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)
|
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 char **string_descriptor;
|
||||||
|
const uint8_t *cfg_descriptor;
|
||||||
ESP_RETURN_ON_FALSE(config, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
ESP_RETURN_ON_FALSE(config, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||||
|
|
||||||
// Configure USB PHY
|
// 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");
|
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;
|
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");
|
ESP_RETURN_ON_FALSE(tusb_init(), ESP_FAIL, TAG, "Init TinyUSB stack failed");
|
||||||
#if !CONFIG_TINYUSB_NO_DEFAULT_TASK
|
#if !CONFIG_TINYUSB_NO_DEFAULT_TASK
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
|
#include "freertos/ringbuf.h"
|
||||||
#include "tusb.h"
|
#include "tusb.h"
|
||||||
#include "tusb_cdc_acm.h"
|
#include "tusb_cdc_acm.h"
|
||||||
#include "cdc.h"
|
#include "cdc.h"
|
||||||
|
@@ -60,8 +60,8 @@ tusb_desc_strarray_device_t descriptor_str_tinyusb = {
|
|||||||
/* End of TinyUSB default */
|
/* End of TinyUSB default */
|
||||||
|
|
||||||
/**** Kconfig driven Descriptor ****/
|
/**** Kconfig driven Descriptor ****/
|
||||||
tusb_desc_device_t descriptor_kconfig = {
|
const tusb_desc_device_t descriptor_dev_kconfig = {
|
||||||
.bLength = sizeof(descriptor_kconfig),
|
.bLength = sizeof(descriptor_dev_kconfig),
|
||||||
.bDescriptorType = TUSB_DESC_DEVICE,
|
.bDescriptorType = TUSB_DESC_DEVICE,
|
||||||
.bcdUSB = 0x0200,
|
.bcdUSB = 0x0200,
|
||||||
|
|
||||||
@@ -126,4 +126,76 @@ tusb_desc_strarray_device_t descriptor_str_kconfig = {
|
|||||||
#endif
|
#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 */
|
/* End of Kconfig driven Descriptor */
|
||||||
|
@@ -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);
|
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)
|
void usb_print_device_descriptor(const usb_device_desc_t *devc_desc)
|
||||||
{
|
{
|
||||||
if (devc_desc == NULL) {
|
if (devc_desc == NULL) {
|
||||||
@@ -265,15 +278,18 @@ void usb_print_config_descriptor(const usb_config_desc_t *cfg_desc, print_class_
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
switch (next_desc->bDescriptorType) {
|
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);
|
usbh_print_cfg_desc((const usb_config_desc_t *)next_desc);
|
||||||
break;
|
break;
|
||||||
case USB_W_VALUE_DT_INTERFACE:
|
case USB_B_DESCRIPTOR_TYPE_INTERFACE:
|
||||||
usbh_print_intf_desc((const usb_intf_desc_t *)next_desc);
|
usbh_print_intf_desc((const usb_intf_desc_t *)next_desc);
|
||||||
break;
|
break;
|
||||||
case USB_W_VALUE_DT_ENDPOINT:
|
case USB_B_DESCRIPTOR_TYPE_ENDPOINT:
|
||||||
print_ep_desc((const usb_ep_desc_t *)next_desc);
|
print_ep_desc((const usb_ep_desc_t *)next_desc);
|
||||||
break;
|
break;
|
||||||
|
case USB_B_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION:
|
||||||
|
print_iad_desc((const usb_iad_desc_t*)next_desc);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if(class_specific_cb) {
|
if(class_specific_cb) {
|
||||||
class_specific_cb(next_desc);
|
class_specific_cb(next_desc);
|
||||||
|
14
conftest.py
14
conftest.py
@@ -29,7 +29,7 @@ from _pytest.python import Function
|
|||||||
from _pytest.reports import TestReport
|
from _pytest.reports import TestReport
|
||||||
from _pytest.runner import CallInfo
|
from _pytest.runner import CallInfo
|
||||||
from _pytest.terminal import TerminalReporter
|
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
|
from pytest_embedded.utils import find_by_suffix
|
||||||
|
|
||||||
SUPPORTED_TARGETS = ['esp32', 'esp32s2', 'esp32c3', 'esp32s3']
|
SUPPORTED_TARGETS = ['esp32', 'esp32s2', 'esp32c3', 'esp32s3']
|
||||||
@@ -62,6 +62,7 @@ def item_marker_names(item: Item) -> List[str]:
|
|||||||
# Fixtures #
|
# Fixtures #
|
||||||
############
|
############
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
@parse_configuration
|
||||||
def config(request: FixtureRequest) -> str:
|
def config(request: FixtureRequest) -> str:
|
||||||
return getattr(request, 'param', None) or DEFAULT_SDKCONFIG
|
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
|
@pytest.fixture
|
||||||
@parse_configuration
|
@apply_count
|
||||||
def build_dir(
|
def build_dir(
|
||||||
request: FixtureRequest, app_path: str, target: Optional[str], config: Optional[str]
|
app_path: str, target: Optional[str], config: Optional[str]
|
||||||
) -> str:
|
) -> str:
|
||||||
"""
|
"""
|
||||||
Check local build dir with the following priority:
|
Check local build dir with the following priority:
|
||||||
@@ -90,7 +91,6 @@ def build_dir(
|
|||||||
4. build
|
4. build
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
request: pytest fixture
|
|
||||||
app_path: app path
|
app_path: app path
|
||||||
target: target
|
target: target
|
||||||
config: config
|
config: config
|
||||||
@@ -98,11 +98,6 @@ def build_dir(
|
|||||||
Returns:
|
Returns:
|
||||||
valid build directory
|
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 = []
|
check_dirs = []
|
||||||
if target is not None and config is not None:
|
if target is not None and config is not None:
|
||||||
@@ -131,6 +126,7 @@ def build_dir(
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
|
@apply_count
|
||||||
def junit_properties(
|
def junit_properties(
|
||||||
test_case_name: str, record_xml_attribute: Callable[[str, object], None]
|
test_case_name: str, record_xml_attribute: Callable[[str, object], None]
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@@ -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.
|
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
|
## Example Output
|
||||||
|
|
||||||
After the flashing you should see the output at idf monitor:
|
After the flashing you should see the output at idf monitor:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
...
|
||||||
I (256) USB-CDC: USB Host installed
|
I (256) USB-CDC: USB Host installed
|
||||||
I (256) USB-CDC: Opening CDC ACM device 0x303A:0x4001
|
I (256) USB-CDC: Opening CDC ACM device 0x303A:0x4001
|
||||||
CDC Header Descriptor:
|
...
|
||||||
bcdCDC: 1.20
|
Device descriptor is printed here
|
||||||
CDC Call Descriptor:
|
...
|
||||||
bmCapabilities: 0x00
|
|
||||||
bDataInterface: 1
|
|
||||||
CDC ACM Descriptor:
|
|
||||||
bmCapabilities: 0x02
|
|
||||||
CDC Union Descriptor:
|
|
||||||
bControlInterface: 0
|
|
||||||
bSubordinateInterface[0]: 1
|
|
||||||
I (1666) USB-CDC: Data received
|
I (1666) USB-CDC: Data received
|
||||||
I (1666) USB-CDC: 0x3ffc4c20 41 54 0d |AT.|
|
I (1666) USB-CDC: 0x3ffc4c20 41 54 0d |AT.|
|
||||||
I (2666) USB-CDC: Data received
|
I (2666) USB-CDC: Data received
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
#define EXAMPLE_USB_HOST_PRIORITY 20
|
#define EXAMPLE_USB_HOST_PRIORITY 20
|
||||||
#define EXAMPLE_USB_DEVICE_VID 0x303A // 0x303A:0x4001 (TinyUSB CDC device)
|
#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";
|
static const char *TAG = "USB-CDC";
|
||||||
|
|
||||||
|
@@ -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
|
// IAD with correct interface number was found: Check Class/Subclass codes, save Interface indexes
|
||||||
assert(iad_desc->bInterfaceCount == 2);
|
assert(iad_desc->bInterfaceCount == 2);
|
||||||
assert(iad_desc->bFunctionClass == USB_CLASS_COMM);
|
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;
|
notif_intf_idx = iad_desc->bFirstInterface;
|
||||||
data_intf_idx = iad_desc->bFirstInterface + 1;
|
data_intf_idx = iad_desc->bFirstInterface + 1;
|
||||||
interface_found = true;
|
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;
|
const usb_standard_desc_t *cdc_desc = (usb_standard_desc_t *)cdc_dev->notif.intf_desc;
|
||||||
do {
|
do {
|
||||||
cdc_desc = usb_parse_next_descriptor(cdc_desc, config_desc->wTotalLength, &desc_offset);
|
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
|
break; // We found all CDC specific descriptors
|
||||||
cdc_dev->num_cdc_intf_desc++;
|
cdc_dev->num_cdc_intf_desc++;
|
||||||
cdc_dev->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
|
// Check whether found Interfaces are really CDC-ACM
|
||||||
assert(cdc_dev->notif.intf_desc->bInterfaceClass == USB_CLASS_COMM);
|
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->notif.intf_desc->bNumEndpoints == 1);
|
||||||
assert(cdc_dev->data.intf_desc->bInterfaceClass == USB_CLASS_CDC_DATA);
|
assert(cdc_dev->data.intf_desc->bInterfaceClass == USB_CLASS_CDC_DATA);
|
||||||
assert(cdc_dev->data.intf_desc->bNumEndpoints == 2);
|
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;
|
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)
|
void cdc_acm_host_desc_print(cdc_acm_dev_hdl_t cdc_hdl)
|
||||||
{
|
{
|
||||||
assert(cdc_hdl);
|
assert(cdc_hdl);
|
||||||
cdc_dev_t *cdc_dev = (cdc_dev_t *)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");
|
const usb_device_desc_t *device_desc;
|
||||||
|
const usb_config_desc_t *config_desc;
|
||||||
for (int i = 0; i < cdc_dev->num_cdc_intf_desc; i++) {
|
ESP_ERROR_CHECK_WITHOUT_ABORT(usb_host_get_device_descriptor(cdc_dev->dev_hdl, &device_desc));
|
||||||
switch (((cdc_header_desc_t *)cdc_dev->cdc_intf_desc[i])->bDescriptorSubtype) {
|
ESP_ERROR_CHECK_WITHOUT_ABORT(usb_host_get_active_config_descriptor(cdc_dev->dev_hdl, &config_desc));
|
||||||
case CDC_DESC_SUBTYPE_HEADER: {
|
usb_print_device_descriptor(device_desc);
|
||||||
cdc_header_desc_t *desc = (cdc_header_desc_t *)cdc_dev->cdc_intf_desc[i];
|
usb_print_config_descriptor(config_desc, cdc_acm_print_desc);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -949,7 +969,7 @@ static void notif_xfer_cb(usb_transfer_t *transfer)
|
|||||||
if (cdc_acm_is_transfer_completed(transfer)) {
|
if (cdc_acm_is_transfer_completed(transfer)) {
|
||||||
cdc_notification_t *notif = (cdc_notification_t *)transfer->data_buffer;
|
cdc_notification_t *notif = (cdc_notification_t *)transfer->data_buffer;
|
||||||
switch (notif->bNotificationCode) {
|
switch (notif->bNotificationCode) {
|
||||||
case CDC_NOTIF_NETWORK_CONNECTION: {
|
case USB_CDC_NOTIF_NETWORK_CONNECTION: {
|
||||||
if (cdc_dev->notif.cb) {
|
if (cdc_dev->notif.cb) {
|
||||||
const cdc_acm_host_dev_event_data_t net_conn_event = {
|
const cdc_acm_host_dev_event_data_t net_conn_event = {
|
||||||
.type = CDC_ACM_HOST_NETWORK_CONNECTION,
|
.type = CDC_ACM_HOST_NETWORK_CONNECTION,
|
||||||
@@ -959,7 +979,7 @@ static void notif_xfer_cb(usb_transfer_t *transfer)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CDC_NOTIF_SERIAL_STATE: {
|
case USB_CDC_NOTIF_SERIAL_STATE: {
|
||||||
cdc_dev->serial_state.val = *((uint16_t *)notif->Data);
|
cdc_dev->serial_state.val = *((uint16_t *)notif->Data);
|
||||||
if (cdc_dev->notif.cb) {
|
if (cdc_dev->notif.cb) {
|
||||||
const cdc_acm_host_dev_event_data_t serial_state_event = {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case CDC_NOTIF_RESPONSE_AVAILABLE: // Encapsulated commands not implemented - fallthrough
|
case USB_CDC_NOTIF_RESPONSE_AVAILABLE: // Encapsulated commands not implemented - fallthrough
|
||||||
default:
|
default:
|
||||||
ESP_LOGW("CDC_ACM", "Unsupported notification type 0x%02X", notif->bNotificationCode);
|
ESP_LOGW("CDC_ACM", "Unsupported notification type 0x%02X", notif->bNotificationCode);
|
||||||
ESP_LOG_BUFFER_HEX("CDC_ACM", transfer->data_buffer, transfer->actual_num_bytes);
|
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);
|
CDC_ACM_CHECK(cdc_hdl && line_coding, ESP_ERR_INVALID_ARG);
|
||||||
|
|
||||||
ESP_RETURN_ON_ERROR(
|
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,);
|
TAG,);
|
||||||
ESP_LOGD(TAG, "Line Get: Rate: %d, Stop bits: %d, Parity: %d, Databits: %d", line_coding->dwDTERate,
|
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);
|
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);
|
CDC_ACM_CHECK(cdc_hdl && line_coding, ESP_ERR_INVALID_ARG);
|
||||||
|
|
||||||
ESP_RETURN_ON_ERROR(
|
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,);
|
TAG,);
|
||||||
ESP_LOGD(TAG, "Line Set: Rate: %d, Stop bits: %d, Parity: %d, Databits: %d", line_coding->dwDTERate,
|
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);
|
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);
|
const uint16_t ctrl_bitmap = (uint16_t)dtr | ((uint16_t)rts << 1);
|
||||||
|
|
||||||
ESP_RETURN_ON_ERROR(
|
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,);
|
TAG,);
|
||||||
ESP_LOGD(TAG, "Control Line Set: DTR: %d, RTS: %d", dtr, rts);
|
ESP_LOGD(TAG, "Control Line Set: DTR: %d, RTS: %d", dtr, rts);
|
||||||
return ESP_OK;
|
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);
|
CDC_ACM_CHECK(cdc_hdl, ESP_ERR_INVALID_ARG);
|
||||||
|
|
||||||
ESP_RETURN_ON_ERROR(
|
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,);
|
TAG,);
|
||||||
|
|
||||||
// Block until break is deasserted
|
// Block until break is deasserted
|
||||||
|
@@ -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);
|
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.
|
* Device and full Configuration descriptors are printed in human readable format to stdout.
|
||||||
* Intended for debugging and for CDC-ACM compliant devices only.
|
|
||||||
*
|
*
|
||||||
* @param cdc_hdl CDC handle obtained from cdc_acm_host_open()
|
* @param cdc_hdl CDC handle obtained from cdc_acm_host_open()
|
||||||
*/
|
*/
|
||||||
|
@@ -13,33 +13,33 @@
|
|||||||
* @see Table 13, USB CDC specification rev. 1.2
|
* @see Table 13, USB CDC specification rev. 1.2
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CDC_DESC_SUBTYPE_HEADER = 0x00, // Header Functional Descriptor
|
USB_CDC_DESC_SUBTYPE_HEADER = 0x00, // Header Functional Descriptor
|
||||||
CDC_DESC_SUBTYPE_CALL = 0x01, // Call Management Functional Descriptor
|
USB_CDC_DESC_SUBTYPE_CALL = 0x01, // Call Management Functional Descriptor
|
||||||
CDC_DESC_SUBTYPE_ACM = 0x02, // Abstract Control Management Functional Descriptor
|
USB_CDC_DESC_SUBTYPE_ACM = 0x02, // Abstract Control Management Functional Descriptor
|
||||||
CDC_DESC_SUBTYPE_DLM = 0x03, // Direct Line Management Functional Descriptor
|
USB_CDC_DESC_SUBTYPE_DLM = 0x03, // Direct Line Management Functional Descriptor
|
||||||
CDC_DESC_SUBTYPE_TEL_RINGER = 0x04, // Telephone Ringer Functional Descriptor
|
USB_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
|
USB_CDC_DESC_SUBTYPE_TEL_CLSR = 0x05, // Telephone Call and Line State Reporting Capabilities Functional Descriptor
|
||||||
CDC_DESC_SUBTYPE_UNION = 0x06, // Union Functional Descriptor
|
USB_CDC_DESC_SUBTYPE_UNION = 0x06, // Union Functional Descriptor
|
||||||
CDC_DESC_SUBTYPE_COUNTRY = 0x07, // Country Selection Functional Descriptor
|
USB_CDC_DESC_SUBTYPE_COUNTRY = 0x07, // Country Selection Functional Descriptor
|
||||||
CDC_DESC_SUBTYPE_TEL_MODE = 0x08, // Telephone Operational Modes Functional Descriptor
|
USB_CDC_DESC_SUBTYPE_TEL_MODE = 0x08, // Telephone Operational Modes Functional Descriptor
|
||||||
CDC_DESC_SUBTYPE_TERMINAL = 0x09, // USB Terminal
|
USB_CDC_DESC_SUBTYPE_TERMINAL = 0x09, // USB Terminal
|
||||||
CDC_DESC_SUBTYPE_NCHT = 0x0A, // Network Channel Terminal
|
USB_CDC_DESC_SUBTYPE_NCHT = 0x0A, // Network Channel Terminal
|
||||||
CDC_DESC_SUBTYPE_PROTOCOL = 0x08, // Protocol Unit
|
USB_CDC_DESC_SUBTYPE_PROTOCOL = 0x08, // Protocol Unit
|
||||||
CDC_DESC_SUBTYPE_EXTENSION = 0x0C, // Extension Unit
|
USB_CDC_DESC_SUBTYPE_EXTENSION = 0x0C, // Extension Unit
|
||||||
CDC_DESC_SUBTYPE_MULTI_CHAN = 0x0D, // Multi-Channel Management Functional Descriptor
|
USB_CDC_DESC_SUBTYPE_MULTI_CHAN = 0x0D, // Multi-Channel Management Functional Descriptor
|
||||||
CDC_DESC_SUBTYPE_CAPI = 0x0E, // CAPI Control
|
USB_CDC_DESC_SUBTYPE_CAPI = 0x0E, // CAPI Control
|
||||||
CDC_DESC_SUBTYPE_ETH = 0x0F, // Ethernet Networking
|
USB_CDC_DESC_SUBTYPE_ETH = 0x0F, // Ethernet Networking
|
||||||
CDC_DESC_SUBTYPE_ATM = 0x10, // ATM Networking
|
USB_CDC_DESC_SUBTYPE_ATM = 0x10, // ATM Networking
|
||||||
CDC_DESC_SUBTYPE_WHANDSET = 0x11, // Wireless Handset Control Model Functional Descriptor
|
USB_CDC_DESC_SUBTYPE_WHANDSET = 0x11, // Wireless Handset Control Model Functional Descriptor
|
||||||
CDC_DESC_SUBTYPE_MDLM = 0x12, // Mobile Direct Line Model
|
USB_CDC_DESC_SUBTYPE_MDLM = 0x12, // Mobile Direct Line Model
|
||||||
CDC_DESC_SUBTYPE_MDLM_DETAIL = 0x13, // MDLM Detail
|
USB_CDC_DESC_SUBTYPE_MDLM_DETAIL = 0x13, // MDLM Detail
|
||||||
CDC_DESC_SUBTYPE_DMM = 0x14, // Device Management Model
|
USB_CDC_DESC_SUBTYPE_DMM = 0x14, // Device Management Model
|
||||||
CDC_DESC_SUBTYPE_OBEX = 0x15, // OBEX Functional
|
USB_CDC_DESC_SUBTYPE_OBEX = 0x15, // OBEX Functional
|
||||||
CDC_DESC_SUBTYPE_COMMAND_SET = 0x16, // Command Set
|
USB_CDC_DESC_SUBTYPE_COMMAND_SET = 0x16, // Command Set
|
||||||
CDC_DESC_SUBTYPE_COMMAND_SET_DETAIL = 0x17, // Command Set Detail Functional Descriptor
|
USB_CDC_DESC_SUBTYPE_COMMAND_SET_DETAIL = 0x17, // Command Set Detail Functional Descriptor
|
||||||
CDC_DESC_SUBTYPE_TEL_CM = 0x18, // Telephone Control Model Functional Descriptor
|
USB_CDC_DESC_SUBTYPE_TEL_CM = 0x18, // Telephone Control Model Functional Descriptor
|
||||||
CDC_DESC_SUBTYPE_OBEX_SERVICE = 0x19, // OBEX Service Identifier Functional Descriptor
|
USB_CDC_DESC_SUBTYPE_OBEX_SERVICE = 0x19, // OBEX Service Identifier Functional Descriptor
|
||||||
CDC_DESC_SUBTYPE_NCM = 0x1A // NCM Functional Descriptor
|
USB_CDC_DESC_SUBTYPE_NCM = 0x1A // NCM Functional Descriptor
|
||||||
} __attribute__((packed)) cdc_desc_subtype_t;
|
} __attribute__((packed)) cdc_desc_subtype_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -48,19 +48,19 @@ typedef enum {
|
|||||||
* @see Table 4, USB CDC specification rev. 1.2
|
* @see Table 4, USB CDC specification rev. 1.2
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CDC_SUBCLASS_DLCM = 0x01, // Direct Line Control Model
|
USB_CDC_SUBCLASS_DLCM = 0x01, // Direct Line Control Model
|
||||||
CDC_SUBCLASS_ACM = 0x02, // Abstract Control Model
|
USB_CDC_SUBCLASS_ACM = 0x02, // Abstract Control Model
|
||||||
CDC_SUBCLASS_TCM = 0x03, // Telephone Control Model
|
USB_CDC_SUBCLASS_TCM = 0x03, // Telephone Control Model
|
||||||
CDC_SUBCLASS_MCHCM = 0x04, // Multi-Channel Control Model
|
USB_CDC_SUBCLASS_MCHCM = 0x04, // Multi-Channel Control Model
|
||||||
CDC_SUBCLASS_CAPI = 0x05, // CAPI Control Model
|
USB_CDC_SUBCLASS_CAPI = 0x05, // CAPI Control Model
|
||||||
CDC_SUBCLASS_ECM = 0x06, // Ethernet Networking Control Model
|
USB_CDC_SUBCLASS_ECM = 0x06, // Ethernet Networking Control Model
|
||||||
CDC_SUBCLASS_ATM = 0x07, // ATM Networking Model
|
USB_CDC_SUBCLASS_ATM = 0x07, // ATM Networking Model
|
||||||
CDC_SUBCLASS_HANDSET = 0x08, // Wireless Handset Control Model
|
USB_CDC_SUBCLASS_HANDSET = 0x08, // Wireless Handset Control Model
|
||||||
CDC_SUBCLASS_DEV_MAN = 0x09, // Device Management
|
USB_CDC_SUBCLASS_DEV_MAN = 0x09, // Device Management
|
||||||
CDC_SUBCLASS_MOBILE = 0x0A, // Mobile Direct Line Model
|
USB_CDC_SUBCLASS_MOBILE = 0x0A, // Mobile Direct Line Model
|
||||||
CDC_SUBCLASS_OBEX = 0x0B, // OBEX
|
USB_CDC_SUBCLASS_OBEX = 0x0B, // OBEX
|
||||||
CDC_SUBCLASS_EEM = 0x0C, // Ethernet Emulation Model
|
USB_CDC_SUBCLASS_EEM = 0x0C, // Ethernet Emulation Model
|
||||||
CDC_SUBCLASS_NCM = 0x0D // Network Control Model
|
USB_CDC_SUBCLASS_NCM = 0x0D // Network Control Model
|
||||||
} __attribute__((packed)) cdc_subclass_t;
|
} __attribute__((packed)) cdc_subclass_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -69,16 +69,16 @@ typedef enum {
|
|||||||
* @see Table 5, USB CDC specification rev. 1.2
|
* @see Table 5, USB CDC specification rev. 1.2
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CDC_COMM_PROTOCOL_NONE = 0x00, // No class specific protocol required
|
USB_CDC_COMM_PROTOCOL_NONE = 0x00, // No class specific protocol required
|
||||||
CDC_COMM_PROTOCOL_V250 = 0x01, // AT Commands: V.250 etc
|
USB_CDC_COMM_PROTOCOL_V250 = 0x01, // AT Commands: V.250 etc
|
||||||
CDC_COMM_PROTOCOL_PCAA = 0x02, // AT Commands defined by PCCA-101
|
USB_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
|
USB_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
|
USB_CDC_COMM_PROTOCOL_GSM = 0x04, // AT Commands defined by GSM 07.07
|
||||||
CDC_COMM_PROTOCOL_3GPP = 0x05, // AT Commands defined by 3GPP 27.007
|
USB_CDC_COMM_PROTOCOL_3GPP = 0x05, // AT Commands defined by 3GPP 27.007
|
||||||
CDC_COMM_PROTOCOL_TIA = 0x06, // AT Commands defined by TIA for CDMA
|
USB_CDC_COMM_PROTOCOL_TIA = 0x06, // AT Commands defined by TIA for CDMA
|
||||||
CDC_COMM_PROTOCOL_EEM = 0x07, // Ethernet Emulation Model
|
USB_CDC_COMM_PROTOCOL_EEM = 0x07, // Ethernet Emulation Model
|
||||||
CDC_COMM_PROTOCOL_EXT = 0xFE, // External Protocol: Commands defined by Command Set Functional Descriptor
|
USB_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_VENDOR = 0xFF // Vendor-specific
|
||||||
} __attribute__((packed)) cdc_comm_protocol_t;
|
} __attribute__((packed)) cdc_comm_protocol_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -87,18 +87,18 @@ typedef enum {
|
|||||||
* @see Table 7, USB CDC specification rev. 1.2
|
* @see Table 7, USB CDC specification rev. 1.2
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CDC_DATA_PROTOCOL_NONE = 0x00, // No class specific protocol required
|
USB_CDC_DATA_PROTOCOL_NONE = 0x00, // No class specific protocol required
|
||||||
CDC_DATA_PROTOCOL_NCM = 0x01, // Network Transfer Block
|
USB_CDC_DATA_PROTOCOL_NCM = 0x01, // Network Transfer Block
|
||||||
CDC_DATA_PROTOCOL_I430 = 0x30, // Physical interface protocol for ISDN BRI
|
USB_CDC_DATA_PROTOCOL_I430 = 0x30, // Physical interface protocol for ISDN BRI
|
||||||
CDC_DATA_PROTOCOL_HDLC = 0x31, // HDLC
|
USB_CDC_DATA_PROTOCOL_HDLC = 0x31, // HDLC
|
||||||
CDC_DATA_PROTOCOL_Q921M = 0x50, // Management protocol for Q.921 data link protocol
|
USB_CDC_DATA_PROTOCOL_Q921M = 0x50, // Management protocol for Q.921 data link protocol
|
||||||
CDC_DATA_PROTOCOL_Q921 = 0x51, // Data link protocol for Q.931
|
USB_CDC_DATA_PROTOCOL_Q921 = 0x51, // Data link protocol for Q.931
|
||||||
CDC_DATA_PROTOCOL_Q921TM = 0x52, // TEI-multiplexor for Q.921 data link protocol
|
USB_CDC_DATA_PROTOCOL_Q921TM = 0x52, // TEI-multiplexor for Q.921 data link protocol
|
||||||
CDC_DATA_PROTOCOL_V42BIS = 0x90, // Data compression procedures
|
USB_CDC_DATA_PROTOCOL_V42BIS = 0x90, // Data compression procedures
|
||||||
CDC_DATA_PROTOCOL_Q931 = 0x91, // Euro-ISDN protocol control
|
USB_CDC_DATA_PROTOCOL_Q931 = 0x91, // Euro-ISDN protocol control
|
||||||
CDC_DATA_PROTOCOL_V120 = 0x92, // V.24 rate adaptation to ISDN
|
USB_CDC_DATA_PROTOCOL_V120 = 0x92, // V.24 rate adaptation to ISDN
|
||||||
CDC_DATA_PROTOCOL_CAPI = 0x93, // CAPI Commands
|
USB_CDC_DATA_PROTOCOL_CAPI = 0x93, // CAPI Commands
|
||||||
CDC_DATA_PROTOCOL_VENDOR = 0xFF // Vendor-specific
|
USB_CDC_DATA_PROTOCOL_VENDOR = 0xFF // Vendor-specific
|
||||||
} __attribute__((packed)) cdc_data_protocol_t;
|
} __attribute__((packed)) cdc_data_protocol_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -107,52 +107,52 @@ typedef enum {
|
|||||||
* @see Table 19, USB CDC specification rev. 1.2
|
* @see Table 19, USB CDC specification rev. 1.2
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CDC_REQ_SEND_ENCAPSULATED_COMMAND = 0x00,
|
USB_CDC_REQ_SEND_ENCAPSULATED_COMMAND = 0x00,
|
||||||
CDC_REQ_GET_ENCAPSULATED_RESPONSE = 0x01,
|
USB_CDC_REQ_GET_ENCAPSULATED_RESPONSE = 0x01,
|
||||||
CDC_REQ_SET_COMM_FEATURE = 0x02,
|
USB_CDC_REQ_SET_COMM_FEATURE = 0x02,
|
||||||
CDC_REQ_GET_COMM_FEATURE = 0x03,
|
USB_CDC_REQ_GET_COMM_FEATURE = 0x03,
|
||||||
CDC_REQ_CLEAR_COMM_FEATURE = 0x04,
|
USB_CDC_REQ_CLEAR_COMM_FEATURE = 0x04,
|
||||||
CDC_REQ_SET_AUX_LINE_STATE = 0x10,
|
USB_CDC_REQ_SET_AUX_LINE_STATE = 0x10,
|
||||||
CDC_REQ_SET_HOOK_STATE = 0x11,
|
USB_CDC_REQ_SET_HOOK_STATE = 0x11,
|
||||||
CDC_REQ_PULSE_SETUP = 0x12,
|
USB_CDC_REQ_PULSE_SETUP = 0x12,
|
||||||
CDC_REQ_SEND_PULSE = 0x13,
|
USB_CDC_REQ_SEND_PULSE = 0x13,
|
||||||
CDC_REQ_SET_PULSE_TIME = 0x14,
|
USB_CDC_REQ_SET_PULSE_TIME = 0x14,
|
||||||
CDC_REQ_RING_AUX_JACK = 0x15,
|
USB_CDC_REQ_RING_AUX_JACK = 0x15,
|
||||||
CDC_REQ_SET_LINE_CODING = 0x20,
|
USB_CDC_REQ_SET_LINE_CODING = 0x20,
|
||||||
CDC_REQ_GET_LINE_CODING = 0x21,
|
USB_CDC_REQ_GET_LINE_CODING = 0x21,
|
||||||
CDC_REQ_SET_CONTROL_LINE_STATE = 0x22,
|
USB_CDC_REQ_SET_CONTROL_LINE_STATE = 0x22,
|
||||||
CDC_REQ_SEND_BREAK = 0x23,
|
USB_CDC_REQ_SEND_BREAK = 0x23,
|
||||||
CDC_REQ_SET_RINGER_PARMS = 0x30,
|
USB_CDC_REQ_SET_RINGER_PARMS = 0x30,
|
||||||
CDC_REQ_GET_RINGER_PARMS = 0x31,
|
USB_CDC_REQ_GET_RINGER_PARMS = 0x31,
|
||||||
CDC_REQ_SET_OPERATION_PARMS = 0x32,
|
USB_CDC_REQ_SET_OPERATION_PARMS = 0x32,
|
||||||
CDC_REQ_GET_OPERATION_PARMS = 0x33,
|
USB_CDC_REQ_GET_OPERATION_PARMS = 0x33,
|
||||||
CDC_REQ_SET_LINE_PARMS = 0x34,
|
USB_CDC_REQ_SET_LINE_PARMS = 0x34,
|
||||||
CDC_REQ_GET_LINE_PARMS = 0x35,
|
USB_CDC_REQ_GET_LINE_PARMS = 0x35,
|
||||||
CDC_REQ_DIAL_DIGITS = 0x36,
|
USB_CDC_REQ_DIAL_DIGITS = 0x36,
|
||||||
CDC_REQ_SET_UNIT_PARAMETER = 0x37,
|
USB_CDC_REQ_SET_UNIT_PARAMETER = 0x37,
|
||||||
CDC_REQ_GET_UNIT_PARAMETER = 0x38,
|
USB_CDC_REQ_GET_UNIT_PARAMETER = 0x38,
|
||||||
CDC_REQ_CLEAR_UNIT_PARAMETER = 0x39,
|
USB_CDC_REQ_CLEAR_UNIT_PARAMETER = 0x39,
|
||||||
CDC_REQ_GET_PROFILE = 0x3A,
|
USB_CDC_REQ_GET_PROFILE = 0x3A,
|
||||||
CDC_REQ_SET_ETHERNET_MULTICAST_FILTERS = 0x40,
|
USB_CDC_REQ_SET_ETHERNET_MULTICAST_FILTERS = 0x40,
|
||||||
CDC_REQ_SET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER = 0x41,
|
USB_CDC_REQ_SET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER = 0x41,
|
||||||
CDC_REQ_GET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER = 0x42,
|
USB_CDC_REQ_GET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER = 0x42,
|
||||||
CDC_REQ_SET_ETHERNET_PACKET_FILTER = 0x43,
|
USB_CDC_REQ_SET_ETHERNET_PACKET_FILTER = 0x43,
|
||||||
CDC_REQ_GET_ETHERNET_STATISTIC = 0x44,
|
USB_CDC_REQ_GET_ETHERNET_STATISTIC = 0x44,
|
||||||
CDC_REQ_SET_ATM_DATA_FORMAT = 0x50,
|
USB_CDC_REQ_SET_ATM_DATA_FORMAT = 0x50,
|
||||||
CDC_REQ_GET_ATM_DEVICE_STATISTICS = 0x51,
|
USB_CDC_REQ_GET_ATM_DEVICE_STATISTICS = 0x51,
|
||||||
CDC_REQ_SET_ATM_DEFAULT_VC = 0x52,
|
USB_CDC_REQ_SET_ATM_DEFAULT_VC = 0x52,
|
||||||
CDC_REQ_GET_ATM_VC_STATISTICS = 0x53,
|
USB_CDC_REQ_GET_ATM_VC_STATISTICS = 0x53,
|
||||||
CDC_REQ_GET_NTB_PARAMETERS = 0x80,
|
USB_CDC_REQ_GET_NTB_PARAMETERS = 0x80,
|
||||||
CDC_REQ_GET_NET_ADDRESS = 0x81,
|
USB_CDC_REQ_GET_NET_ADDRESS = 0x81,
|
||||||
CDC_REQ_SET_NET_ADDRESS = 0x82,
|
USB_CDC_REQ_SET_NET_ADDRESS = 0x82,
|
||||||
CDC_REQ_GET_NTB_FORMAT = 0x83,
|
USB_CDC_REQ_GET_NTB_FORMAT = 0x83,
|
||||||
CDC_REQ_SET_NTB_FORMAT = 0x84,
|
USB_CDC_REQ_SET_NTB_FORMAT = 0x84,
|
||||||
CDC_REQ_GET_NTB_INPUT_SIZE = 0x85,
|
USB_CDC_REQ_GET_NTB_INPUT_SIZE = 0x85,
|
||||||
CDC_REQ_SET_NTB_INPUT_SIZE = 0x86,
|
USB_CDC_REQ_SET_NTB_INPUT_SIZE = 0x86,
|
||||||
CDC_REQ_GET_MAX_DATAGRAM_SIZE = 0x87,
|
USB_CDC_REQ_GET_MAX_DATAGRAM_SIZE = 0x87,
|
||||||
CDC_REQ_SET_MAX_DATAGRAM_SIZE = 0x88,
|
USB_CDC_REQ_SET_MAX_DATAGRAM_SIZE = 0x88,
|
||||||
CDC_REQ_GET_CRC_MODE = 0x89,
|
USB_CDC_REQ_GET_CRC_MODE = 0x89,
|
||||||
CDC_REQ_SET_CRC_MODE = 0x8A
|
USB_CDC_REQ_SET_CRC_MODE = 0x8A
|
||||||
} __attribute__((packed)) cdc_request_code_t;
|
} __attribute__((packed)) cdc_request_code_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -161,14 +161,14 @@ typedef enum {
|
|||||||
* @see Table 20, USB CDC specification rev. 1.2
|
* @see Table 20, USB CDC specification rev. 1.2
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CDC_NOTIF_NETWORK_CONNECTION = 0x00,
|
USB_CDC_NOTIF_NETWORK_CONNECTION = 0x00,
|
||||||
CDC_NOTIF_RESPONSE_AVAILABLE = 0x01,
|
USB_CDC_NOTIF_RESPONSE_AVAILABLE = 0x01,
|
||||||
CDC_NOTIF_AUX_JACK_HOOK_STATE = 0x08,
|
USB_CDC_NOTIF_AUX_JACK_HOOK_STATE = 0x08,
|
||||||
CDC_NOTIF_RING_DETECT = 0x09,
|
USB_CDC_NOTIF_RING_DETECT = 0x09,
|
||||||
CDC_NOTIF_SERIAL_STATE = 0x20,
|
USB_CDC_NOTIF_SERIAL_STATE = 0x20,
|
||||||
CDC_NOTIF_CALL_STATE_CHANGE = 0x28,
|
USB_CDC_NOTIF_CALL_STATE_CHANGE = 0x28,
|
||||||
CDC_NOTIF_LINE_STATE_CHANGE = 0x29,
|
USB_CDC_NOTIF_LINE_STATE_CHANGE = 0x29,
|
||||||
CDC_NOTIF_CONNECTION_SPEED_CHANGE = 0x2A
|
USB_CDC_NOTIF_CONNECTION_SPEED_CHANGE = 0x2A
|
||||||
} __attribute__((packed)) cdc_notification_code_t;
|
} __attribute__((packed)) cdc_notification_code_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@@ -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 "."
|
INCLUDE_DIRS "."
|
||||||
REQUIRES cdc_acm_host unity)
|
REQUIRES cdc_acm_host tinyusb unity)
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
* 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"
|
#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)
|
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 = {
|
usb_phy_config_t phy_config = {
|
||||||
.controller = USB_PHY_CTRL_OTG,
|
.controller = USB_PHY_CTRL_OTG,
|
||||||
.target = USB_PHY_TARGET_INT,
|
.target = USB_PHY_TARGET_INT,
|
||||||
@@ -60,27 +60,27 @@ void usb_lib_task(void *arg)
|
|||||||
printf("USB Host installed\n");
|
printf("USB Host installed\n");
|
||||||
xTaskNotifyGive(arg);
|
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
|
// Start handling system events
|
||||||
uint32_t event_flags;
|
uint32_t event_flags;
|
||||||
usb_host_lib_handle_events(portMAX_DELAY, &event_flags);
|
usb_host_lib_handle_events(portMAX_DELAY, &event_flags);
|
||||||
if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) {
|
if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) {
|
||||||
printf("No more clients: clean up\n");
|
printf("No more clients\n");
|
||||||
// The device should not have been freed yet, so we expect an ESP_ERR_NOT_FINISHED
|
usb_host_device_free_all();
|
||||||
TEST_ASSERT_EQUAL(ESP_ERR_NOT_FINISHED, usb_host_device_free_all());
|
all_clients_gone = true;
|
||||||
}
|
}
|
||||||
if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) {
|
if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) {
|
||||||
printf("All free: uninstall USB lib\n");
|
printf("All devices freed\n");
|
||||||
break;
|
all_dev_free = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up USB Host
|
// Clean up USB Host
|
||||||
vTaskDelay(10); // Short delay to allow clients clean-up
|
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());
|
TEST_ASSERT_EQUAL(ESP_OK, usb_host_uninstall());
|
||||||
//Tear down USB PHY
|
TEST_ASSERT_EQUAL(ESP_OK, usb_del_phy(phy_hdl)); //Tear down USB PHY
|
||||||
TEST_ASSERT_EQUAL(ESP_OK, usb_del_phy(phy_hdl));
|
|
||||||
phy_hdl = NULL;
|
phy_hdl = NULL;
|
||||||
vTaskDelete(NULL);
|
vTaskDelete(NULL);
|
||||||
}
|
}
|
||||||
@@ -88,7 +88,7 @@ void usb_lib_task(void *arg)
|
|||||||
void test_install_cdc_driver(void)
|
void test_install_cdc_driver(void)
|
||||||
{
|
{
|
||||||
// Create a task that will handle USB library events
|
// 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);
|
ulTaskNotifyTake(false, 1000);
|
||||||
|
|
||||||
printf("Installing CDC-ACM driver\n");
|
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:
|
/* Basic test to check CDC communication:
|
||||||
* open/read/write/close device
|
* open/read/write/close device
|
||||||
* CDC-ACM specific commands: set/get_line_coding, set_control_line_state */
|
* 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;
|
nb_of_responses = 0;
|
||||||
cdc_acm_dev_hdl_t cdc_dev = NULL;
|
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 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_responses = 0;
|
||||||
nb_of_responses2 = 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.
|
* In this test, one CDC device is accessed from multiple threads.
|
||||||
* It has to be opened/closed just once, though.
|
* 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;
|
nb_of_responses = 0;
|
||||||
cdc_acm_dev_hdl_t cdc_dev;
|
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 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();
|
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_EQUAL(ESP_OK, cdc_acm_host_open(0x303A, 0x4002, 0, &dev_config, &cdc_dev));
|
||||||
TEST_ASSERT_NOT_NULL(cdc_dev);
|
TEST_ASSERT_NOT_NULL(cdc_dev);
|
||||||
|
|
||||||
force_conn_state(false, pdMS_TO_TICKS(10));
|
force_conn_state(false, pdMS_TO_TICKS(10)); // Simulate device disconnection
|
||||||
// Notify will succeed only if CDC_ACM_HOST_DEVICE_DISCONNECTED notification was generated
|
TEST_ASSERT_EQUAL(1, ulTaskNotifyTake(false, pdMS_TO_TICKS(100))); // 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(true, 0); // Switch back to real PHY
|
|
||||||
TEST_ASSERT_EQUAL(ESP_OK, cdc_acm_host_uninstall());
|
TEST_ASSERT_EQUAL(ESP_OK, cdc_acm_host_uninstall());
|
||||||
vTaskDelay(20); //Short delay to allow task to be cleaned up
|
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
|
* -# Send unsupported CDC request
|
||||||
* -# Write to read-only device
|
* -# 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_dev_hdl_t cdc_dev;
|
||||||
cdc_acm_host_device_config_t dev_config = {
|
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_EQUAL(ESP_OK, cdc_acm_host_open(0x303A, 0x4002, 0, &dev_config, &cdc_dev));
|
||||||
TEST_ASSERT_NOT_NULL(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
|
// Open one CDC-ACM device twice
|
||||||
//cdc_acm_dev_hdl_t cdc_dev_test;
|
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_EQUAL(ESP_ERR_INVALID_STATE, cdc_acm_host_open(0x303A, 0x4002, 0, &dev_config, &cdc_dev_test));
|
||||||
//TEST_ASSERT_NULL(cdc_dev_test);
|
TEST_ASSERT_NULL(cdc_dev_test);
|
||||||
|
|
||||||
// Uninstall driver with open devices
|
// Uninstall driver with open devices
|
||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, cdc_acm_host_uninstall());
|
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);
|
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
|
#endif
|
||||||
|
@@ -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");
|
||||||
|
}
|
@@ -50,7 +50,7 @@ static const char *TAG = "msc_example";
|
|||||||
|
|
||||||
|
|
||||||
/**** Kconfig driven Descriptor ****/
|
/**** Kconfig driven Descriptor ****/
|
||||||
tusb_desc_device_t device_descriptor = {
|
static const tusb_desc_device_t device_descriptor = {
|
||||||
.bLength = sizeof(device_descriptor),
|
.bLength = sizeof(device_descriptor),
|
||||||
.bDescriptorType = TUSB_DESC_DEVICE,
|
.bDescriptorType = TUSB_DESC_DEVICE,
|
||||||
.bcdUSB = 0x0200,
|
.bcdUSB = 0x0200,
|
||||||
@@ -67,12 +67,20 @@ tusb_desc_device_t device_descriptor = {
|
|||||||
.bNumConfigurations = 0x01
|
.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)
|
void device_app(void)
|
||||||
{
|
{
|
||||||
ESP_LOGI(TAG, "USB initialization");
|
ESP_LOGI(TAG, "USB initialization");
|
||||||
|
|
||||||
tinyusb_config_t tusb_cfg = {
|
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));
|
ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
|
||||||
@@ -83,7 +91,6 @@ void device_app(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// whether host does safe-eject
|
// whether host does safe-eject
|
||||||
static bool ejected = false;
|
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
|
// 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, 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,
|
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;
|
return resplen;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif /* SOC_USB_OTG_SUPPORTED */
|
||||||
|
@@ -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
|
#pragma once
|
||||||
|
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: CC0-1.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "unity.h"
|
#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)
|
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) {
|
if (delay_ticks > 0) {
|
||||||
//Delay of 0 ticks causes a yield. So skip if delay_ticks is 0.
|
//Delay of 0 ticks causes a yield. So skip if delay_ticks is 0.
|
||||||
vTaskDelay(delay_ticks);
|
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) {
|
if (waiting_for_sudden_disconnect) {
|
||||||
waiting_for_sudden_disconnect = false;
|
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) {
|
if (event->event == MSC_DEVICE_CONNECTED) {
|
||||||
@@ -83,12 +83,12 @@ static void write_read_file(const char *file_path)
|
|||||||
|
|
||||||
ESP_LOGI(TAG, "Writing file");
|
ESP_LOGI(TAG, "Writing file");
|
||||||
FILE *f = fopen(file_path, "w");
|
FILE *f = fopen(file_path, "w");
|
||||||
TEST_ASSERT( f != NULL);
|
TEST_ASSERT(f);
|
||||||
fprintf(f, TEST_STRING);
|
fprintf(f, TEST_STRING);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Reading file");
|
ESP_LOGI(TAG, "Reading file");
|
||||||
TEST_ASSERT( fopen(file_path, "r") != NULL);
|
TEST_ASSERT(fopen(file_path, "r"));
|
||||||
fgets(line, sizeof(line), f);
|
fgets(line, sizeof(line), f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
// strip newline
|
// 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);
|
ESP_LOGI(TAG, "Reading %s:", file_path);
|
||||||
FILE *file = fopen(file_path, "r");
|
FILE *file = fopen(file_path, "r");
|
||||||
TEST_ASSERT(file != NULL)
|
TEST_ASSERT(file)
|
||||||
|
|
||||||
char content[200];
|
char content[200];
|
||||||
fread(content, 1, sizeof(content), file);
|
fread(content, 1, sizeof(content), file);
|
||||||
@@ -153,12 +153,12 @@ static void check_sudden_disconnect(void)
|
|||||||
|
|
||||||
ESP_LOGI(TAG, "Creating test.tx");
|
ESP_LOGI(TAG, "Creating test.tx");
|
||||||
FILE *file = fopen("/usb/test.txt", "w");
|
FILE *file = fopen("/usb/test.txt", "w");
|
||||||
TEST_ASSERT( file != NULL);
|
TEST_ASSERT(file);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Write data");
|
ESP_LOGI(TAG, "Write data");
|
||||||
TEST_ASSERT( fwrite(data, 1, DATA_SIZE, file) == DATA_SIZE );
|
TEST_ASSERT_EQUAL(DATA_SIZE, fwrite(data, 1, DATA_SIZE, file));
|
||||||
TEST_ASSERT( fwrite(data, 1, DATA_SIZE, file) == DATA_SIZE );
|
TEST_ASSERT_EQUAL(DATA_SIZE, fwrite(data, 1, DATA_SIZE, file));
|
||||||
TEST_ASSERT( fflush(file) == 0 );
|
TEST_ASSERT_EQUAL(0, fflush(file));
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Trigger a disconnect");
|
ESP_LOGI(TAG, "Trigger a disconnect");
|
||||||
//Trigger a disconnect
|
//Trigger a disconnect
|
||||||
@@ -167,10 +167,10 @@ static void check_sudden_disconnect(void)
|
|||||||
|
|
||||||
// Make sure flag was leared in callback
|
// Make sure flag was leared in callback
|
||||||
vTaskDelay( pdMS_TO_TICKS(100) );
|
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");
|
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);
|
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
|
.otg_speed = USB_PHY_SPEED_UNDEFINED, //In Host mode, the speed is determined by the connected device
|
||||||
.gpio_conf = NULL,
|
.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 = {
|
const usb_host_config_t host_config = {
|
||||||
.skip_phy_setup = true,
|
.skip_phy_setup = true,
|
||||||
.intr_flags = ESP_INTR_FLAG_LEVEL1,
|
.intr_flags = ESP_INTR_FLAG_LEVEL1,
|
||||||
};
|
};
|
||||||
ESP_OK_ASSERT( usb_host_install(&host_config) );
|
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);
|
TEST_ASSERT(task_created);
|
||||||
|
|
||||||
const msc_host_driver_config_t msc_config = {
|
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");
|
ESP_LOGI(TAG, "Waiting for USB stick to be connected");
|
||||||
msc_host_event_t app_event;
|
msc_host_event_t app_event;
|
||||||
xQueueReceive(app_queue, &app_event, portMAX_DELAY);
|
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;
|
uint8_t device_addr = app_event.device.address;
|
||||||
|
|
||||||
ESP_OK_ASSERT( msc_host_install_device(device_addr, &device) );
|
ESP_OK_ASSERT( msc_host_install_device(device_addr, &device) );
|
||||||
@@ -232,7 +232,7 @@ static void msc_teardown(void)
|
|||||||
vSemaphoreDelete(ready_to_deinit_usb);
|
vSemaphoreDelete(ready_to_deinit_usb);
|
||||||
ESP_OK_ASSERT( usb_host_uninstall() );
|
ESP_OK_ASSERT( usb_host_uninstall() );
|
||||||
//Tear down USB PHY
|
//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;
|
phy_hdl = NULL;
|
||||||
|
|
||||||
vQueueDelete(app_queue);
|
vQueueDelete(app_queue);
|
||||||
@@ -262,35 +262,40 @@ static void erase_storage(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check_readme_content(void)
|
TEST_CASE("write_and_read_file", "[usb_msc]")
|
||||||
{
|
|
||||||
msc_setup();
|
|
||||||
check_file_content("/usb/README.TXT", README_CONTENTS);
|
|
||||||
msc_teardown();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("Write and read file", "[usb_msc][ignore]")
|
|
||||||
{
|
{
|
||||||
msc_setup();
|
msc_setup();
|
||||||
write_read_file(FILE_NAME);
|
write_read_file(FILE_NAME);
|
||||||
msc_teardown();
|
msc_teardown();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Sudden disconnect", "[usb_msc][ignore]")
|
TEST_CASE("sudden_disconnect", "[usb_msc]")
|
||||||
{
|
{
|
||||||
msc_setup();
|
msc_setup();
|
||||||
check_sudden_disconnect();
|
check_sudden_disconnect();
|
||||||
msc_teardown();
|
msc_teardown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void read_write_sectors(void)
|
TEST_CASE("sectors_can_be_written_and_read", "[usb_msc]")
|
||||||
{
|
{
|
||||||
msc_setup();
|
msc_setup();
|
||||||
write_read_sectors();
|
write_read_sectors();
|
||||||
msc_teardown();
|
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");
|
printf("Create file\n");
|
||||||
msc_setup();
|
msc_setup();
|
||||||
@@ -299,7 +304,7 @@ void check_formatting(void)
|
|||||||
|
|
||||||
printf("File exists after mounting again\n");
|
printf("File exists after mounting again\n");
|
||||||
msc_setup();
|
msc_setup();
|
||||||
TEST_ASSERT( file_exists(FILE_NAME) );
|
TEST_ASSERT(file_exists(FILE_NAME));
|
||||||
printf("Erase storage device\n");
|
printf("Erase storage device\n");
|
||||||
erase_storage();
|
erase_storage();
|
||||||
msc_teardown();
|
msc_teardown();
|
||||||
@@ -307,15 +312,14 @@ void check_formatting(void)
|
|||||||
printf("Check file does not exist after formatting\n");
|
printf("Check file does not exist after formatting\n");
|
||||||
mount_config.format_if_mount_failed = true;
|
mount_config.format_if_mount_failed = true;
|
||||||
msc_setup();
|
msc_setup();
|
||||||
TEST_ASSERT( !file_exists(FILE_NAME) );
|
TEST_ASSERT_FALSE(file_exists(FILE_NAME));
|
||||||
msc_teardown();
|
msc_teardown();
|
||||||
mount_config.format_if_mount_failed = false;
|
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("mock_device_app", "[usb_msc_device][ignore]")
|
||||||
|
{
|
||||||
TEST_CASE_MULTIPLE_DEVICES("Can be Formated", "[usb_msc][ignore]", check_formatting, device_app);
|
device_app();
|
||||||
|
}
|
||||||
TEST_CASE_MULTIPLE_DEVICES("Check README content", "[usb_msc][ignore]", check_readme_content, device_app);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -25,6 +25,7 @@ markers =
|
|||||||
ip101: connected via wired 10/100M ethernet
|
ip101: connected via wired 10/100M ethernet
|
||||||
lan8720: connected via LAN8720 ethernet transceiver
|
lan8720: connected via LAN8720 ethernet transceiver
|
||||||
octal_psram: runners with octal psram
|
octal_psram: runners with octal psram
|
||||||
|
usb_host: usb host runners
|
||||||
|
|
||||||
# log related
|
# log related
|
||||||
log_cli = True
|
log_cli = True
|
||||||
|
@@ -7,6 +7,18 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "unity.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)
|
void app_main(void)
|
||||||
{
|
{
|
||||||
@@ -14,3 +26,19 @@ void app_main(void)
|
|||||||
unity_run_menu();
|
unity_run_menu();
|
||||||
UNITY_END();
|
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");
|
||||||
|
}
|
||||||
|
40
tools/test_apps/peripherals/usb/pytest_usb_host.py
Normal file
40
tools/test_apps/peripherals/usb/pytest_usb_host.py
Normal file
@@ -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")
|
@@ -1,4 +1,16 @@
|
|||||||
|
# Configure TinyUSB, it will be used to mock USB devices
|
||||||
CONFIG_TINYUSB=y
|
CONFIG_TINYUSB=y
|
||||||
CONFIG_TINYUSB_MSC_ENABLED=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_INT_WDT=n
|
||||||
CONFIG_ESP_TASK_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
|
||||||
|
Reference in New Issue
Block a user