mirror of
https://github.com/espressif/esp-idf
synced 2025-03-10 09:39:10 -04: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:
commit
446daa9865
@ -18,7 +18,7 @@ set(srcs
|
||||
"uart_periph.c"
|
||||
"usb_periph.c"
|
||||
"temperature_sensor_periph.c"
|
||||
"usb_phy_periph.c")
|
||||
"usb_otg_periph.c")
|
||||
|
||||
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"
|
||||
"uart_periph.c"
|
||||
"usb_periph.c"
|
||||
"usb_phy_periph.c")
|
||||
"usb_otg_periph.c")
|
||||
|
||||
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_suspend_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;
|
||||
} 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
|
||||
}
|
@ -19,7 +19,12 @@ extern "C" {
|
||||
#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 {
|
||||
union {
|
||||
@ -29,6 +34,8 @@ typedef struct {
|
||||
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 */
|
||||
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;
|
||||
|
||||
/**
|
||||
|
@ -32,7 +32,9 @@ esp_err_t tinyusb_driver_install(const tinyusb_config_t *config)
|
||||
.controller = USB_PHY_CTRL_OTG,
|
||||
.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,
|
||||
.vm_io_num = USBPHY_VM_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) {
|
||||
phy_conf.target = USB_PHY_TARGET_EXT;
|
||||
phy_conf.gpio_conf = &gpio_conf;
|
||||
phy_conf.ext_io_conf = &ext_io_conf;
|
||||
} else {
|
||||
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");
|
||||
|
||||
#if (CONFIG_TINYUSB_HID_COUNT > 0)
|
||||
|
@ -15,6 +15,24 @@
|
||||
extern "C" {
|
||||
#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
|
||||
*/
|
||||
@ -33,7 +51,7 @@ typedef enum {
|
||||
} usb_phy_action_t;
|
||||
|
||||
/**
|
||||
* @brief USB external PHY iopins configure struct
|
||||
* @brief USB external PHY IO pins configuration structure
|
||||
*/
|
||||
typedef struct {
|
||||
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 vpo_io_num; /**< GPIO pin to USB_EXTPHY_VPO_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
|
||||
@ -50,11 +85,12 @@ typedef struct {
|
||||
* At minimum the PHY controller and PHY target must be initialized.
|
||||
*/
|
||||
typedef struct {
|
||||
usb_phy_controller_t controller; /**< USB PHY controller */
|
||||
usb_phy_target_t target; /**< USB PHY target INT/EXT */
|
||||
usb_otg_mode_t otg_mode; /**< USB OTG mode */
|
||||
usb_phy_speed_t otg_speed; /**< USB OTG speed */
|
||||
usb_phy_gpio_conf_t *gpio_conf; /**< USB external PHY iopins configure */
|
||||
usb_phy_controller_t controller; /**< USB PHY controller */
|
||||
usb_phy_target_t target; /**< USB PHY target INT/EXT */
|
||||
usb_otg_mode_t otg_mode; /**< USB OTG mode */
|
||||
usb_phy_speed_t otg_speed; /**< USB OTG speed */
|
||||
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;
|
||||
|
||||
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,
|
||||
.otg_mode = USB_OTG_MODE_HOST,
|
||||
.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));
|
||||
}
|
||||
|
@ -384,7 +384,8 @@ esp_err_t usb_host_install(const usb_host_config_t *config)
|
||||
.target = USB_PHY_TARGET_INT,
|
||||
.otg_mode = USB_OTG_MODE_HOST,
|
||||
.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);
|
||||
if (ret != ESP_OK) {
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "esp_check.h"
|
||||
#include "esp_private/periph_ctrl.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_ll.h"
|
||||
#include "esp_rom_gpio.h"
|
||||
@ -31,7 +31,7 @@ struct phy_context_t {
|
||||
usb_phy_status_t status; /**< PHY status */
|
||||
usb_otg_mode_t otg_mode; /**< USB OTG mode */
|
||||
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 */
|
||||
};
|
||||
|
||||
@ -53,20 +53,11 @@ typedef struct {
|
||||
static phy_ctrl_obj_t *p_phy_ctrl_obj = NULL;
|
||||
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[] = {
|
||||
{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++) {
|
||||
for (int i = 0; i < iopins_num; 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)) ||
|
||||
(!iopin.is_output && GPIO_IS_VALID_GPIO(iopin.pin)),
|
||||
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;
|
||||
}
|
||||
|
||||
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_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;
|
||||
}
|
||||
portEXIT_CRITICAL(&phy_spinlock);
|
||||
periph_module_enable(usb_phy_periph_signal.module);
|
||||
periph_module_reset(usb_phy_periph_signal.module);
|
||||
periph_module_enable(usb_otg_periph_signal.module);
|
||||
periph_module_reset(usb_otg_periph_signal.module);
|
||||
return ESP_OK;
|
||||
|
||||
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;
|
||||
if (config->gpio_conf && config->target == USB_PHY_TARGET_EXT) {
|
||||
phy_context->iopins = (usb_phy_gpio_conf_t *) calloc(1, sizeof(usb_phy_gpio_conf_t));
|
||||
if (config->ext_io_conf && config->target == USB_PHY_TARGET_EXT) {
|
||||
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");
|
||||
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));
|
||||
}
|
||||
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) {
|
||||
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;
|
||||
|
||||
cleanup:
|
||||
@ -286,7 +312,7 @@ static void phy_uninstall(void)
|
||||
p_phy_ctrl_obj_free = p_phy_ctrl_obj;
|
||||
p_phy_ctrl_obj = NULL;
|
||||
// Disable USB peripheral
|
||||
periph_module_disable(usb_phy_periph_signal.module);
|
||||
periph_module_disable(usb_otg_periph_signal.module);
|
||||
}
|
||||
portEXIT_CRITICAL(&phy_spinlock);
|
||||
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.
|
||||
|
||||
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
|
||||
--------
|
||||
@ -22,7 +22,7 @@ Features
|
||||
- USB Serial Device (CDC-ACM)
|
||||
- Input and output streams through USB Serial Device
|
||||
- Other USB classes (MIDI, MSC, HID...) support directly via TinyUSB
|
||||
|
||||
- VBUS monitoring for self-powered devices
|
||||
|
||||
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
|
||||
: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
|
||||
|
||||
Self-powered devices must also connect VBUS through voltage divider or comparator, more details in :ref:`self-powered-device` subchapter.
|
||||
|
||||
Driver Structure
|
||||
----------------
|
||||
|
||||
@ -51,8 +53,6 @@ On top of it the driver implements:
|
||||
- Redirecting of standard streams through the Serial device
|
||||
- Encapsulated driver's task servicing the TinyUSB
|
||||
|
||||
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
@ -63,7 +63,6 @@ Via Menuconfig options you can specify:
|
||||
- The verbosity of the TinyUSB's log
|
||||
- Disable the TinyUSB main task (for the custom implementation)
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
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`.
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
.. _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)
|
||||
---------------------------
|
||||
|
||||
@ -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.
|
||||
|
||||
|
||||
Application Examples
|
||||
--------------------
|
||||
|
||||
@ -143,7 +159,6 @@ The table below describes the code examples available in the directory :example:
|
||||
* - :example:`peripherals/usb/device/tusb_hid`
|
||||
- How to set up {IDF_TARGET_NAME} chip to work as a USB Human Interface Device
|
||||
|
||||
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
@ -153,4 +168,3 @@ API Reference
|
||||
.. include-build-file:: inc/tusb_console.inc
|
||||
.. include-build-file:: inc/tusb_tasks.inc
|
||||
.. include-build-file:: inc/vfs_tinyusb.inc
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user