mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-07 14:44:32 +02:00
Merge branch 'feature/usb/voltage_monitoring' into 'master'
tinyusb: Add voltage monitoring feature Closes IDFGH-6065 and IDF-5229 See merge request espressif/esp-idf!20296
This commit is contained in:
@@ -18,7 +18,7 @@ set(srcs
|
|||||||
"uart_periph.c"
|
"uart_periph.c"
|
||||||
"usb_periph.c"
|
"usb_periph.c"
|
||||||
"temperature_sensor_periph.c"
|
"temperature_sensor_periph.c"
|
||||||
"usb_phy_periph.c")
|
"usb_otg_periph.c")
|
||||||
|
|
||||||
add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}")
|
add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}")
|
||||||
|
|
||||||
|
34
components/soc/esp32s2/usb_otg_periph.c
Normal file
34
components/soc/esp32s2/usb_otg_periph.c
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "soc/usb_otg_periph.h"
|
||||||
|
#include "soc/gpio_sig_map.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Bunch of constants for USB peripheral: GPIO signals
|
||||||
|
*/
|
||||||
|
const usb_phy_signal_conn_t usb_otg_periph_signal = {
|
||||||
|
.extphy_vp_in = USB_EXTPHY_VP_IDX,
|
||||||
|
.extphy_vm_in = USB_EXTPHY_VM_IDX,
|
||||||
|
.extphy_rcv_in = USB_EXTPHY_RCV_IDX,
|
||||||
|
.extphy_oen_out = USB_EXTPHY_OEN_IDX,
|
||||||
|
.extphy_vpo_out = USB_EXTPHY_VPO_IDX,
|
||||||
|
.extphy_vmo_out = USB_EXTPHY_VMO_IDX,
|
||||||
|
.extphy_suspend_in = USB_EXTPHY_SUSPND_IDX,
|
||||||
|
.extphy_speed_in = USB_EXTPHY_SPEED_IDX,
|
||||||
|
.srp_bvalid_in = USB_SRP_BVALID_IN_IDX,
|
||||||
|
.srp_sessend_in = USB_SRP_SESSEND_IN_IDX,
|
||||||
|
.srp_chrgvbus_out = USB_SRP_CHRGVBUS_IDX,
|
||||||
|
.srp_dischrgvbus_out = USB_SRP_DISCHRGVBUS_IDX,
|
||||||
|
.otg_iddig_in = USB_OTG_IDDIG_IN_IDX,
|
||||||
|
.otg_avalid_in = USB_OTG_AVALID_IN_IDX,
|
||||||
|
.otg_vbusvalid_in = USB_OTG_VBUSVALID_IN_IDX,
|
||||||
|
.otg_idpullup_out = USB_OTG_IDPULLUP_IDX,
|
||||||
|
.otg_dppulldown_out = USB_OTG_DPPULLDOWN_IDX,
|
||||||
|
.otg_dmpulldown_out = USB_OTG_DMPULLDOWN_IDX,
|
||||||
|
.otg_drvvbus_out = USB_OTG_DRVVBUS_IDX,
|
||||||
|
.module = PERIPH_USB_MODULE
|
||||||
|
};
|
@@ -1,23 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "soc/usb_phy_periph.h"
|
|
||||||
#include "soc/gpio_sig_map.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
Bunch of constants for USB peripheral: GPIO signals
|
|
||||||
*/
|
|
||||||
const usb_phy_signal_conn_t usb_phy_periph_signal = {
|
|
||||||
.extphy_vp_in = USB_EXTPHY_VP_IDX,
|
|
||||||
.extphy_vm_in = USB_EXTPHY_VM_IDX,
|
|
||||||
.extphy_rcv_in = USB_EXTPHY_RCV_IDX,
|
|
||||||
.extphy_oen_out = USB_EXTPHY_OEN_IDX,
|
|
||||||
.extphy_vpo_out = USB_EXTPHY_VPO_IDX,
|
|
||||||
.extphy_vmo_out = USB_EXTPHY_VMO_IDX,
|
|
||||||
.extphy_suspend_in = USB_EXTPHY_SUSPND_IDX,
|
|
||||||
.extphy_speed_in = USB_EXTPHY_SPEED_IDX,
|
|
||||||
.module = PERIPH_USB_MODULE
|
|
||||||
};
|
|
@@ -21,7 +21,7 @@ set(srcs
|
|||||||
"temperature_sensor_periph.c"
|
"temperature_sensor_periph.c"
|
||||||
"uart_periph.c"
|
"uart_periph.c"
|
||||||
"usb_periph.c"
|
"usb_periph.c"
|
||||||
"usb_phy_periph.c")
|
"usb_otg_periph.c")
|
||||||
|
|
||||||
add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}")
|
add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}")
|
||||||
|
|
||||||
|
34
components/soc/esp32s3/usb_otg_periph.c
Normal file
34
components/soc/esp32s3/usb_otg_periph.c
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "soc/usb_otg_periph.h"
|
||||||
|
#include "soc/gpio_sig_map.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Bunch of constants for USB peripheral: GPIO signals
|
||||||
|
*/
|
||||||
|
const usb_phy_signal_conn_t usb_otg_periph_signal = {
|
||||||
|
.extphy_vp_in = USB_EXTPHY_VP_IDX,
|
||||||
|
.extphy_vm_in = USB_EXTPHY_VM_IDX,
|
||||||
|
.extphy_rcv_in = USB_EXTPHY_RCV_IDX,
|
||||||
|
.extphy_oen_out = USB_EXTPHY_OEN_IDX,
|
||||||
|
.extphy_vpo_out = USB_EXTPHY_VPO_IDX,
|
||||||
|
.extphy_vmo_out = USB_EXTPHY_VMO_IDX,
|
||||||
|
.extphy_suspend_in = USB_EXTPHY_SUSPND_IDX,
|
||||||
|
.extphy_speed_in = USB_EXTPHY_SPEED_IDX,
|
||||||
|
.srp_bvalid_in = USB_SRP_BVALID_IN_IDX,
|
||||||
|
.srp_sessend_in = USB_SRP_SESSEND_IN_IDX,
|
||||||
|
.srp_chrgvbus_out = USB_SRP_CHRGVBUS_IDX,
|
||||||
|
.srp_dischrgvbus_out = USB_SRP_DISCHRGVBUS_IDX,
|
||||||
|
.otg_iddig_in = USB_OTG_IDDIG_IN_IDX,
|
||||||
|
.otg_avalid_in = USB_OTG_AVALID_IN_IDX,
|
||||||
|
.otg_vbusvalid_in = USB_OTG_VBUSVALID_IN_IDX,
|
||||||
|
.otg_idpullup_out = USB_OTG_IDPULLUP_IDX,
|
||||||
|
.otg_dppulldown_out = USB_OTG_DPPULLDOWN_IDX,
|
||||||
|
.otg_dmpulldown_out = USB_OTG_DMPULLDOWN_IDX,
|
||||||
|
.otg_drvvbus_out = USB_OTG_DRVVBUS_IDX,
|
||||||
|
.module = PERIPH_USB_MODULE
|
||||||
|
};
|
@@ -1,23 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "soc/usb_phy_periph.h"
|
|
||||||
#include "soc/gpio_sig_map.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
Bunch of constants for USB peripheral: GPIO signals
|
|
||||||
*/
|
|
||||||
const usb_phy_signal_conn_t usb_phy_periph_signal = {
|
|
||||||
.extphy_vp_in = USB_EXTPHY_VP_IDX,
|
|
||||||
.extphy_vm_in = USB_EXTPHY_VM_IDX,
|
|
||||||
.extphy_rcv_in = USB_EXTPHY_RCV_IDX,
|
|
||||||
.extphy_oen_out = USB_EXTPHY_OEN_IDX,
|
|
||||||
.extphy_vpo_out = USB_EXTPHY_VPO_IDX,
|
|
||||||
.extphy_vmo_out = USB_EXTPHY_VMO_IDX,
|
|
||||||
.extphy_suspend_in = USB_EXTPHY_SUSPND_IDX,
|
|
||||||
.extphy_speed_in = USB_EXTPHY_SPEED_IDX,
|
|
||||||
.module = PERIPH_USB_MODULE
|
|
||||||
};
|
|
@@ -25,10 +25,21 @@ typedef struct {
|
|||||||
const uint8_t extphy_vmo_out;
|
const uint8_t extphy_vmo_out;
|
||||||
const uint8_t extphy_suspend_in;
|
const uint8_t extphy_suspend_in;
|
||||||
const uint8_t extphy_speed_in;
|
const uint8_t extphy_speed_in;
|
||||||
|
const uint8_t srp_bvalid_in;
|
||||||
|
const uint8_t srp_sessend_in;
|
||||||
|
const uint8_t srp_chrgvbus_out;
|
||||||
|
const uint8_t srp_dischrgvbus_out;
|
||||||
|
const uint8_t otg_iddig_in;
|
||||||
|
const uint8_t otg_avalid_in;
|
||||||
|
const uint8_t otg_vbusvalid_in;
|
||||||
|
const uint8_t otg_idpullup_out;
|
||||||
|
const uint8_t otg_dppulldown_out;
|
||||||
|
const uint8_t otg_dmpulldown_out;
|
||||||
|
const uint8_t otg_drvvbus_out;
|
||||||
const periph_module_t module;
|
const periph_module_t module;
|
||||||
} usb_phy_signal_conn_t;
|
} usb_phy_signal_conn_t;
|
||||||
|
|
||||||
extern const usb_phy_signal_conn_t usb_phy_periph_signal;
|
extern const usb_phy_signal_conn_t usb_otg_periph_signal;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
@@ -19,7 +19,12 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Configuration structure of the tinyUSB core
|
* @brief Configuration structure of the TinyUSB core
|
||||||
|
*
|
||||||
|
* USB specification mandates self-powered devices to monitor USB VBUS to detect connection/disconnection events.
|
||||||
|
* If you want to use this feature, connected VBUS to any free GPIO through a voltage divider or voltage comparator.
|
||||||
|
* The voltage divider output should be (0.75 * Vdd) if VBUS is 4.4V (lowest valid voltage at device port).
|
||||||
|
* The comparator thresholds should be set with hysteresis: 4.35V (falling edge) and 4.75V (raising edge).
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
union {
|
union {
|
||||||
@@ -29,6 +34,8 @@ typedef struct {
|
|||||||
const char **string_descriptor; /*!< Pointer to an array of string descriptors */
|
const char **string_descriptor; /*!< Pointer to an array of string descriptors */
|
||||||
bool external_phy; /*!< Should USB use an external PHY */
|
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 */
|
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 */
|
||||||
|
bool self_powered; /*!< This is a self-powered USB device. USB VBUS must be monitored. */
|
||||||
|
int vbus_monitor_io; /*!< GPIO for VBUS monitoring. Ignored if not self_powered. */
|
||||||
} tinyusb_config_t;
|
} tinyusb_config_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -32,7 +32,9 @@ esp_err_t tinyusb_driver_install(const tinyusb_config_t *config)
|
|||||||
.controller = USB_PHY_CTRL_OTG,
|
.controller = USB_PHY_CTRL_OTG,
|
||||||
.otg_mode = USB_OTG_MODE_DEVICE,
|
.otg_mode = USB_OTG_MODE_DEVICE,
|
||||||
};
|
};
|
||||||
usb_phy_gpio_conf_t gpio_conf = {
|
|
||||||
|
// External PHY IOs config
|
||||||
|
usb_phy_ext_io_conf_t ext_io_conf = {
|
||||||
.vp_io_num = USBPHY_VP_NUM,
|
.vp_io_num = USBPHY_VP_NUM,
|
||||||
.vm_io_num = USBPHY_VM_NUM,
|
.vm_io_num = USBPHY_VM_NUM,
|
||||||
.rcv_io_num = USBPHY_RCV_NUM,
|
.rcv_io_num = USBPHY_RCV_NUM,
|
||||||
@@ -42,10 +44,16 @@ esp_err_t tinyusb_driver_install(const tinyusb_config_t *config)
|
|||||||
};
|
};
|
||||||
if (config->external_phy) {
|
if (config->external_phy) {
|
||||||
phy_conf.target = USB_PHY_TARGET_EXT;
|
phy_conf.target = USB_PHY_TARGET_EXT;
|
||||||
phy_conf.gpio_conf = &gpio_conf;
|
phy_conf.ext_io_conf = &ext_io_conf;
|
||||||
} else {
|
} else {
|
||||||
phy_conf.target = USB_PHY_TARGET_INT;
|
phy_conf.target = USB_PHY_TARGET_INT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OTG IOs config
|
||||||
|
const usb_phy_otg_io_conf_t otg_io_conf = USB_PHY_SELF_POWERED_DEVICE(config->vbus_monitor_io);
|
||||||
|
if (config->self_powered) {
|
||||||
|
phy_conf.otg_io_conf = &otg_io_conf;
|
||||||
|
}
|
||||||
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");
|
||||||
|
|
||||||
#if (CONFIG_TINYUSB_HID_COUNT > 0)
|
#if (CONFIG_TINYUSB_HID_COUNT > 0)
|
||||||
|
@@ -15,6 +15,24 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialization for usb_phy_otg_io_conf_t: Self-powered device
|
||||||
|
*/
|
||||||
|
#define USB_PHY_SELF_POWERED_DEVICE(vbus_monitor_io) \
|
||||||
|
{ \
|
||||||
|
.iddig_io_num = -1, \
|
||||||
|
.avalid_io_num = -1, \
|
||||||
|
.vbusvalid_io_num = -1, \
|
||||||
|
.idpullup_io_num = -1, \
|
||||||
|
.dppulldown_io_num = -1, \
|
||||||
|
.dmpulldown_io_num = -1, \
|
||||||
|
.drvvbus_io_num = -1, \
|
||||||
|
.bvalid_io_num = vbus_monitor_io, \
|
||||||
|
.sessend_io_num = -1, \
|
||||||
|
.chrgvbus_io_num = -1, \
|
||||||
|
.dischrgvbus_io_num = -1, \
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief USB PHY status
|
* @brief USB PHY status
|
||||||
*/
|
*/
|
||||||
@@ -33,7 +51,7 @@ typedef enum {
|
|||||||
} usb_phy_action_t;
|
} usb_phy_action_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief USB external PHY iopins configure struct
|
* @brief USB external PHY IO pins configuration structure
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int vp_io_num; /**< GPIO pin to USB_EXTPHY_VP_IDX */
|
int vp_io_num; /**< GPIO pin to USB_EXTPHY_VP_IDX */
|
||||||
@@ -42,7 +60,24 @@ typedef struct {
|
|||||||
int oen_io_num; /**< GPIO pin to USB_EXTPHY_OEN_IDX */
|
int oen_io_num; /**< GPIO pin to USB_EXTPHY_OEN_IDX */
|
||||||
int vpo_io_num; /**< GPIO pin to USB_EXTPHY_VPO_IDX */
|
int vpo_io_num; /**< GPIO pin to USB_EXTPHY_VPO_IDX */
|
||||||
int vmo_io_num; /**< GPIO pin to USB_EXTPHY_VMO_IDX */
|
int vmo_io_num; /**< GPIO pin to USB_EXTPHY_VMO_IDX */
|
||||||
} usb_phy_gpio_conf_t;
|
} usb_phy_ext_io_conf_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USB OTG IO pins configuration structure
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
int iddig_io_num; /**< GPIO pin to USB_OTG_IDDIG_IN_IDX */
|
||||||
|
int avalid_io_num; /**< GPIO pin to USB_OTG_AVALID_IN_IDX */
|
||||||
|
int vbusvalid_io_num; /**< GPIO pin to USB_OTG_VBUSVALID_IN_IDX */
|
||||||
|
int idpullup_io_num; /**< GPIO pin to USB_OTG_IDPULLUP_IDX */
|
||||||
|
int dppulldown_io_num; /**< GPIO pin to USB_OTG_DPPULLDOWN_IDX */
|
||||||
|
int dmpulldown_io_num; /**< GPIO pin to USB_OTG_DMPULLDOWN_IDX */
|
||||||
|
int drvvbus_io_num; /**< GPIO pin to USB_OTG_DRVVBUS_IDX */
|
||||||
|
int bvalid_io_num; /**< GPIO pin to USB_SRP_BVALID_IN_IDX */
|
||||||
|
int sessend_io_num; /**< GPIO pin to USB_SRP_SESSEND_IN_IDX */
|
||||||
|
int chrgvbus_io_num; /**< GPIO pin to USB_SRP_CHRGVBUS_IDX */
|
||||||
|
int dischrgvbus_io_num; /**< GPIO pin to USB_SRP_DISCHRGVBUS_IDX */
|
||||||
|
} usb_phy_otg_io_conf_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief USB PHY configure struct
|
* @brief USB PHY configure struct
|
||||||
@@ -54,7 +89,8 @@ typedef struct {
|
|||||||
usb_phy_target_t target; /**< USB PHY target INT/EXT */
|
usb_phy_target_t target; /**< USB PHY target INT/EXT */
|
||||||
usb_otg_mode_t otg_mode; /**< USB OTG mode */
|
usb_otg_mode_t otg_mode; /**< USB OTG mode */
|
||||||
usb_phy_speed_t otg_speed; /**< USB OTG speed */
|
usb_phy_speed_t otg_speed; /**< USB OTG speed */
|
||||||
usb_phy_gpio_conf_t *gpio_conf; /**< USB external PHY iopins configure */
|
const usb_phy_ext_io_conf_t *ext_io_conf; /**< USB external PHY IO pins configuration */
|
||||||
|
const usb_phy_otg_io_conf_t *otg_io_conf; /**< USB OTG IO pins configuration */
|
||||||
} usb_phy_config_t;
|
} usb_phy_config_t;
|
||||||
|
|
||||||
typedef struct phy_context_t *usb_phy_handle_t; /**< USB PHY context handle */
|
typedef struct phy_context_t *usb_phy_handle_t; /**< USB PHY context handle */
|
||||||
|
@@ -22,7 +22,8 @@ void test_usb_init_phy(void)
|
|||||||
.target = USB_PHY_TARGET_INT,
|
.target = USB_PHY_TARGET_INT,
|
||||||
.otg_mode = USB_OTG_MODE_HOST,
|
.otg_mode = USB_OTG_MODE_HOST,
|
||||||
.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,
|
.ext_io_conf = NULL,
|
||||||
|
.otg_io_conf = NULL,
|
||||||
};
|
};
|
||||||
ESP_ERROR_CHECK(usb_new_phy(&phy_config, &phy_hdl));
|
ESP_ERROR_CHECK(usb_new_phy(&phy_config, &phy_hdl));
|
||||||
}
|
}
|
||||||
|
@@ -384,7 +384,8 @@ esp_err_t usb_host_install(const usb_host_config_t *config)
|
|||||||
.target = USB_PHY_TARGET_INT,
|
.target = USB_PHY_TARGET_INT,
|
||||||
.otg_mode = USB_OTG_MODE_HOST,
|
.otg_mode = USB_OTG_MODE_HOST,
|
||||||
.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,
|
.ext_io_conf = NULL,
|
||||||
|
.otg_io_conf = NULL,
|
||||||
};
|
};
|
||||||
ret = usb_new_phy(&phy_config, &host_lib_obj->constant.phy_handle);
|
ret = usb_new_phy(&phy_config, &host_lib_obj->constant.phy_handle);
|
||||||
if (ret != ESP_OK) {
|
if (ret != ESP_OK) {
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
#include "esp_check.h"
|
#include "esp_check.h"
|
||||||
#include "esp_private/periph_ctrl.h"
|
#include "esp_private/periph_ctrl.h"
|
||||||
#include "esp_private/usb_phy.h"
|
#include "esp_private/usb_phy.h"
|
||||||
#include "soc/usb_phy_periph.h"
|
#include "soc/usb_otg_periph.h"
|
||||||
#include "hal/usb_phy_hal.h"
|
#include "hal/usb_phy_hal.h"
|
||||||
#include "hal/usb_phy_ll.h"
|
#include "hal/usb_phy_ll.h"
|
||||||
#include "esp_rom_gpio.h"
|
#include "esp_rom_gpio.h"
|
||||||
@@ -31,7 +31,7 @@ struct phy_context_t {
|
|||||||
usb_phy_status_t status; /**< PHY status */
|
usb_phy_status_t status; /**< PHY status */
|
||||||
usb_otg_mode_t otg_mode; /**< USB OTG mode */
|
usb_otg_mode_t otg_mode; /**< USB OTG mode */
|
||||||
usb_phy_speed_t otg_speed; /**< USB speed */
|
usb_phy_speed_t otg_speed; /**< USB speed */
|
||||||
usb_phy_gpio_conf_t *iopins; /**< external PHY I/O pins */
|
usb_phy_ext_io_conf_t *iopins; /**< external PHY I/O pins */
|
||||||
usb_phy_hal_context_t hal_context; /**< USB_PHY hal context */
|
usb_phy_hal_context_t hal_context; /**< USB_PHY hal context */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -53,20 +53,11 @@ typedef struct {
|
|||||||
static phy_ctrl_obj_t *p_phy_ctrl_obj = NULL;
|
static phy_ctrl_obj_t *p_phy_ctrl_obj = NULL;
|
||||||
static portMUX_TYPE phy_spinlock = portMUX_INITIALIZER_UNLOCKED;
|
static portMUX_TYPE phy_spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||||
|
|
||||||
static esp_err_t phy_external_iopins_configure(usb_phy_gpio_conf_t *gpio_conf)
|
static esp_err_t phy_iopins_configure(const usb_iopin_dsc_t *usb_periph_iopins, int iopins_num)
|
||||||
{
|
{
|
||||||
const usb_iopin_dsc_t usb_periph_iopins[] = {
|
for (int i = 0; i < iopins_num; i++) {
|
||||||
{gpio_conf->vp_io_num, usb_phy_periph_signal.extphy_vp_in, 0},
|
|
||||||
{gpio_conf->vm_io_num, usb_phy_periph_signal.extphy_vm_in, 0},
|
|
||||||
{gpio_conf->rcv_io_num, usb_phy_periph_signal.extphy_rcv_in, 0},
|
|
||||||
{gpio_conf->oen_io_num, usb_phy_periph_signal.extphy_oen_out, 1},
|
|
||||||
{gpio_conf->vpo_io_num, usb_phy_periph_signal.extphy_vpo_out, 1},
|
|
||||||
{gpio_conf->vmo_io_num, usb_phy_periph_signal.extphy_vmo_out, 1},
|
|
||||||
};
|
|
||||||
|
|
||||||
for (int i = 0; i < sizeof(usb_periph_iopins)/sizeof(usb_iopin_dsc_t); i++) {
|
|
||||||
const usb_iopin_dsc_t iopin = usb_periph_iopins[i];
|
const usb_iopin_dsc_t iopin = usb_periph_iopins[i];
|
||||||
if (iopin.pin != -1) {
|
if (iopin.pin != GPIO_NUM_NC) {
|
||||||
ESP_RETURN_ON_FALSE((iopin.is_output && GPIO_IS_VALID_OUTPUT_GPIO(iopin.pin)) ||
|
ESP_RETURN_ON_FALSE((iopin.is_output && GPIO_IS_VALID_OUTPUT_GPIO(iopin.pin)) ||
|
||||||
(!iopin.is_output && GPIO_IS_VALID_GPIO(iopin.pin)),
|
(!iopin.is_output && GPIO_IS_VALID_GPIO(iopin.pin)),
|
||||||
ESP_ERR_INVALID_ARG, USBPHY_TAG, "io_num argument is invalid");
|
ESP_ERR_INVALID_ARG, USBPHY_TAG, "io_num argument is invalid");
|
||||||
@@ -83,6 +74,38 @@ static esp_err_t phy_external_iopins_configure(usb_phy_gpio_conf_t *gpio_conf)
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static esp_err_t phy_external_iopins_configure(const usb_phy_ext_io_conf_t *ext_io_conf)
|
||||||
|
{
|
||||||
|
const usb_iopin_dsc_t usb_periph_iopins[] = {
|
||||||
|
{ext_io_conf->vp_io_num, usb_otg_periph_signal.extphy_vp_in, false},
|
||||||
|
{ext_io_conf->vm_io_num, usb_otg_periph_signal.extphy_vm_in, false},
|
||||||
|
{ext_io_conf->rcv_io_num, usb_otg_periph_signal.extphy_rcv_in, false},
|
||||||
|
{ext_io_conf->oen_io_num, usb_otg_periph_signal.extphy_oen_out, true},
|
||||||
|
{ext_io_conf->vpo_io_num, usb_otg_periph_signal.extphy_vpo_out, true},
|
||||||
|
{ext_io_conf->vmo_io_num, usb_otg_periph_signal.extphy_vmo_out, true},
|
||||||
|
};
|
||||||
|
|
||||||
|
return phy_iopins_configure(usb_periph_iopins, sizeof(usb_periph_iopins)/sizeof(usb_iopin_dsc_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t phy_otg_iopins_configure(const usb_phy_otg_io_conf_t *otg_io_conf)
|
||||||
|
{
|
||||||
|
const usb_iopin_dsc_t usb_periph_iopins[] = {
|
||||||
|
{otg_io_conf->iddig_io_num, usb_otg_periph_signal.otg_iddig_in, false},
|
||||||
|
{otg_io_conf->avalid_io_num, usb_otg_periph_signal.otg_avalid_in, false},
|
||||||
|
{otg_io_conf->vbusvalid_io_num, usb_otg_periph_signal.otg_vbusvalid_in, false},
|
||||||
|
{otg_io_conf->idpullup_io_num, usb_otg_periph_signal.otg_idpullup_out, true},
|
||||||
|
{otg_io_conf->dppulldown_io_num, usb_otg_periph_signal.otg_dppulldown_out, true},
|
||||||
|
{otg_io_conf->dmpulldown_io_num, usb_otg_periph_signal.otg_dmpulldown_out, true},
|
||||||
|
{otg_io_conf->drvvbus_io_num, usb_otg_periph_signal.otg_drvvbus_out, true},
|
||||||
|
{otg_io_conf->bvalid_io_num, usb_otg_periph_signal.srp_bvalid_in, false},
|
||||||
|
{otg_io_conf->sessend_io_num, usb_otg_periph_signal.srp_sessend_in, false},
|
||||||
|
{otg_io_conf->chrgvbus_io_num, usb_otg_periph_signal.srp_chrgvbus_out, true},
|
||||||
|
{otg_io_conf->dischrgvbus_io_num, usb_otg_periph_signal.srp_dischrgvbus_out, true},
|
||||||
|
};
|
||||||
|
return phy_iopins_configure(usb_periph_iopins, sizeof(usb_periph_iopins)/sizeof(usb_iopin_dsc_t));
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t usb_phy_otg_set_mode(usb_phy_handle_t handle, usb_otg_mode_t mode)
|
esp_err_t usb_phy_otg_set_mode(usb_phy_handle_t handle, usb_otg_mode_t mode)
|
||||||
{
|
{
|
||||||
ESP_RETURN_ON_FALSE(handle, ESP_ERR_INVALID_ARG, USBPHY_TAG, "handle argument is invalid");
|
ESP_RETURN_ON_FALSE(handle, ESP_ERR_INVALID_ARG, USBPHY_TAG, "handle argument is invalid");
|
||||||
@@ -197,8 +220,8 @@ static esp_err_t usb_phy_install(void)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
portEXIT_CRITICAL(&phy_spinlock);
|
portEXIT_CRITICAL(&phy_spinlock);
|
||||||
periph_module_enable(usb_phy_periph_signal.module);
|
periph_module_enable(usb_otg_periph_signal.module);
|
||||||
periph_module_reset(usb_phy_periph_signal.module);
|
periph_module_reset(usb_otg_periph_signal.module);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
@@ -254,10 +277,10 @@ esp_err_t usb_new_phy(const usb_phy_config_t *config, usb_phy_handle_t *handle_r
|
|||||||
}
|
}
|
||||||
|
|
||||||
*handle_ret = (usb_phy_handle_t) phy_context;
|
*handle_ret = (usb_phy_handle_t) phy_context;
|
||||||
if (config->gpio_conf && config->target == USB_PHY_TARGET_EXT) {
|
if (config->ext_io_conf && config->target == USB_PHY_TARGET_EXT) {
|
||||||
phy_context->iopins = (usb_phy_gpio_conf_t *) calloc(1, sizeof(usb_phy_gpio_conf_t));
|
phy_context->iopins = (usb_phy_ext_io_conf_t *) calloc(1, sizeof(usb_phy_ext_io_conf_t));
|
||||||
ESP_GOTO_ON_FALSE(phy_context->iopins, ESP_ERR_NO_MEM, cleanup, USBPHY_TAG, "no mem for storing I/O pins");
|
ESP_GOTO_ON_FALSE(phy_context->iopins, ESP_ERR_NO_MEM, cleanup, USBPHY_TAG, "no mem for storing I/O pins");
|
||||||
memcpy(phy_context->iopins, config->gpio_conf, sizeof(usb_phy_gpio_conf_t));
|
memcpy(phy_context->iopins, config->ext_io_conf, sizeof(usb_phy_ext_io_conf_t));
|
||||||
ESP_ERROR_CHECK(phy_external_iopins_configure(phy_context->iopins));
|
ESP_ERROR_CHECK(phy_external_iopins_configure(phy_context->iopins));
|
||||||
}
|
}
|
||||||
if (config->otg_mode != USB_PHY_MODE_DEFAULT) {
|
if (config->otg_mode != USB_PHY_MODE_DEFAULT) {
|
||||||
@@ -266,6 +289,9 @@ esp_err_t usb_new_phy(const usb_phy_config_t *config, usb_phy_handle_t *handle_r
|
|||||||
if (config->otg_speed != USB_PHY_SPEED_UNDEFINED) {
|
if (config->otg_speed != USB_PHY_SPEED_UNDEFINED) {
|
||||||
ESP_ERROR_CHECK(usb_phy_otg_dev_set_speed(*handle_ret, config->otg_speed));
|
ESP_ERROR_CHECK(usb_phy_otg_dev_set_speed(*handle_ret, config->otg_speed));
|
||||||
}
|
}
|
||||||
|
if (config->otg_io_conf && (phy_context->controller == USB_PHY_CTRL_OTG)) {
|
||||||
|
ESP_ERROR_CHECK(phy_otg_iopins_configure(config->otg_io_conf));
|
||||||
|
}
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
@@ -286,7 +312,7 @@ static void phy_uninstall(void)
|
|||||||
p_phy_ctrl_obj_free = p_phy_ctrl_obj;
|
p_phy_ctrl_obj_free = p_phy_ctrl_obj;
|
||||||
p_phy_ctrl_obj = NULL;
|
p_phy_ctrl_obj = NULL;
|
||||||
// Disable USB peripheral
|
// Disable USB peripheral
|
||||||
periph_module_disable(usb_phy_periph_signal.module);
|
periph_module_disable(usb_otg_periph_signal.module);
|
||||||
}
|
}
|
||||||
portEXIT_CRITICAL(&phy_spinlock);
|
portEXIT_CRITICAL(&phy_spinlock);
|
||||||
free(p_phy_ctrl_obj_free);
|
free(p_phy_ctrl_obj_free);
|
||||||
|
BIN
docs/_static/diagrams/usb/usb_vbus_voltage_monitor.png
vendored
Normal file
BIN
docs/_static/diagrams/usb/usb_vbus_voltage_monitor.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.4 KiB |
BIN
docs/_static/usb-board-connection.png
vendored
BIN
docs/_static/usb-board-connection.png
vendored
Binary file not shown.
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 92 KiB |
@@ -13,7 +13,7 @@ Overview
|
|||||||
|
|
||||||
The driver allows you to use {IDF_TARGET_NAME} chips to develop USB devices on a top of TinyUSB stack. TinyUSB is integrated with ESP-IDF to provide USB features of the framework. Using this driver the chip works as simple or composite device supporting several USB devices simultaneously.
|
The driver allows you to use {IDF_TARGET_NAME} chips to develop USB devices on a top of TinyUSB stack. TinyUSB is integrated with ESP-IDF to provide USB features of the framework. Using this driver the chip works as simple or composite device supporting several USB devices simultaneously.
|
||||||
|
|
||||||
Our USB-OTG implementation is limited to {IDF_TARGET_USB_EP_NUM} number of USB endpoints ({IDF_TARGET_USB_EP_NUM_INOUT} IN/OUT endpoints and {IDF_TARGET_USB_EP_NUM_IN} IN endpoint) - find more information in `technical reference manual <{IDF_TARGET_TRM_EN_URL}>`_.
|
Our USB-OTG implementation is limited to {IDF_TARGET_USB_EP_NUM} USB endpoints ({IDF_TARGET_USB_EP_NUM_INOUT} IN/OUT endpoints and {IDF_TARGET_USB_EP_NUM_IN} IN endpoint) - find more information in `technical reference manual <{IDF_TARGET_TRM_EN_URL}>`_.
|
||||||
|
|
||||||
Features
|
Features
|
||||||
--------
|
--------
|
||||||
@@ -22,7 +22,7 @@ Features
|
|||||||
- USB Serial Device (CDC-ACM)
|
- USB Serial Device (CDC-ACM)
|
||||||
- Input and output streams through USB Serial Device
|
- Input and output streams through USB Serial Device
|
||||||
- Other USB classes (MIDI, MSC, HID...) support directly via TinyUSB
|
- Other USB classes (MIDI, MSC, HID...) support directly via TinyUSB
|
||||||
|
- VBUS monitoring for self-powered devices
|
||||||
|
|
||||||
Hardware USB Connection
|
Hardware USB Connection
|
||||||
-----------------------
|
-----------------------
|
||||||
@@ -36,9 +36,11 @@ On {IDF_TARGET_NAME}, connect GPIO {IDF_TARGET_USB_DP_GPIO_NUM} and {IDF_TARGET_
|
|||||||
|
|
||||||
.. figure:: ../../../_static/usb-board-connection.png
|
.. figure:: ../../../_static/usb-board-connection.png
|
||||||
:align: center
|
:align: center
|
||||||
:alt: Connection of a board to a host ESP chip
|
:alt: Connection of an ESP board to a USB host
|
||||||
:figclass: align-center
|
:figclass: align-center
|
||||||
|
|
||||||
|
Self-powered devices must also connect VBUS through voltage divider or comparator, more details in :ref:`self-powered-device` subchapter.
|
||||||
|
|
||||||
Driver Structure
|
Driver Structure
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
@@ -51,8 +53,6 @@ On top of it the driver implements:
|
|||||||
- Redirecting of standard streams through the Serial device
|
- Redirecting of standard streams through the Serial device
|
||||||
- Encapsulated driver's task servicing the TinyUSB
|
- Encapsulated driver's task servicing the TinyUSB
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Configuration
|
Configuration
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
@@ -63,7 +63,6 @@ Via Menuconfig options you can specify:
|
|||||||
- The verbosity of the TinyUSB's log
|
- The verbosity of the TinyUSB's log
|
||||||
- Disable the TinyUSB main task (for the custom implementation)
|
- Disable the TinyUSB main task (for the custom implementation)
|
||||||
|
|
||||||
|
|
||||||
Descriptors Configuration
|
Descriptors Configuration
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
@@ -81,9 +80,9 @@ However, the driver also provides default descriptors. You can install the drive
|
|||||||
|
|
||||||
If you want to use your own descriptors with extended modification, you can define them during the driver installation process.
|
If you want to use your own descriptors with extended modification, you can define them during the driver installation process.
|
||||||
|
|
||||||
|
|
||||||
Install Driver
|
Install Driver
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
To initialize the driver, users should call :cpp:func:`tinyusb_driver_install`. The driver's configuration is specified in a :cpp:type:`tinyusb_config_t` structure that is passed as an argument to :cpp:func:`tinyusb_driver_install`.
|
To initialize the driver, users should call :cpp:func:`tinyusb_driver_install`. The driver's configuration is specified in a :cpp:type:`tinyusb_config_t` structure that is passed as an argument to :cpp:func:`tinyusb_driver_install`.
|
||||||
|
|
||||||
Note that the :cpp:type:`tinyusb_config_t` structure can be zero initialized (e.g. ``const tinyusb_config_t tusb_cfg = { 0 };``) or partially (as shown below). For any member that is initialized to `0` or `NULL`, the driver will use its default configuration values for that member (see example below)
|
Note that the :cpp:type:`tinyusb_config_t` structure can be zero initialized (e.g. ``const tinyusb_config_t tusb_cfg = { 0 };``) or partially (as shown below). For any member that is initialized to `0` or `NULL`, the driver will use its default configuration values for that member (see example below)
|
||||||
@@ -97,6 +96,24 @@ To initialize the driver, users should call :cpp:func:`tinyusb_driver_install`.
|
|||||||
.configuration_descriptor = NULL, // Use default configuration descriptor according to settings in Menuconfig
|
.configuration_descriptor = NULL, // Use default configuration descriptor according to settings in Menuconfig
|
||||||
};
|
};
|
||||||
|
|
||||||
|
.. _self-powered-device:
|
||||||
|
|
||||||
|
Self-Powered Device
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
USB specification mandates self-powered devices to monitor voltage level on USB's VBUS signal. As opposed to bus-powered devices, a self-powered device can be fully functional even without USB connection. The self-powered device detects connection and disconnection events by monitoring the VBUS voltage level. VBUS is considered valid if it rises above 4.75V and invalid if it falls below 4.35V.
|
||||||
|
|
||||||
|
No {IDF_TARGET_NAME} pin is 5V tolerant, so you must connect the VBUS to {IDF_TARGET_NAME} via a comparator with voltage thresholds as described above, or use a simple resistor voltage divider that will output (0.75 x Vdd) if VBUS is 4.4V (see figure below). In both cases, voltage on the sensing pin must be logic low within 3ms after the device is unplugged from USB host.
|
||||||
|
|
||||||
|
.. figure:: ../../../_static/diagrams/usb/usb_vbus_voltage_monitor.png
|
||||||
|
:align: center
|
||||||
|
:alt: Simple voltage divider for VBUS monitoring
|
||||||
|
:figclass: align-center
|
||||||
|
|
||||||
|
Simple voltage divider for VBUS monitoring
|
||||||
|
|
||||||
|
To use this feature, in :cpp:type:`tinyusb_config_t` you must set :cpp:member:`self_powered` to ``true`` and :cpp:member:`vbus_monitor_io` to GPIO number that will be used for VBUS monitoring.
|
||||||
|
|
||||||
USB Serial Device (CDC-ACM)
|
USB Serial Device (CDC-ACM)
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
@@ -122,7 +139,6 @@ USB Serial Console
|
|||||||
|
|
||||||
The driver allows to redirect all standard application streams (stdinm stdout, stderr) to the USB Serial Device and return them to UART using :cpp:func:`esp_tusb_init_console`/:cpp:func:`esp_tusb_deinit_console` functions.
|
The driver allows to redirect all standard application streams (stdinm stdout, stderr) to the USB Serial Device and return them to UART using :cpp:func:`esp_tusb_init_console`/:cpp:func:`esp_tusb_deinit_console` functions.
|
||||||
|
|
||||||
|
|
||||||
Application Examples
|
Application Examples
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
@@ -143,7 +159,6 @@ The table below describes the code examples available in the directory :example:
|
|||||||
* - :example:`peripherals/usb/device/tusb_hid`
|
* - :example:`peripherals/usb/device/tusb_hid`
|
||||||
- How to set up {IDF_TARGET_NAME} chip to work as a USB Human Interface Device
|
- How to set up {IDF_TARGET_NAME} chip to work as a USB Human Interface Device
|
||||||
|
|
||||||
|
|
||||||
API Reference
|
API Reference
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
@@ -153,4 +168,3 @@ API Reference
|
|||||||
.. include-build-file:: inc/tusb_console.inc
|
.. include-build-file:: inc/tusb_console.inc
|
||||||
.. include-build-file:: inc/tusb_tasks.inc
|
.. include-build-file:: inc/tusb_tasks.inc
|
||||||
.. include-build-file:: inc/vfs_tinyusb.inc
|
.. include-build-file:: inc/vfs_tinyusb.inc
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user