mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'change/usb_host_minor_optimizations_v5.2' into 'release/v5.2'
change(usb/host): Remove unecessary features (v5.2) See merge request espressif/esp-idf!27593
This commit is contained in:
commit
4bd5fa28b4
@ -938,7 +938,7 @@ esp_err_t hub_install(hub_config_t *hub_config)
|
||||
HUB_DRIVER_EXIT_CRITICAL();
|
||||
// Allocate Hub driver object
|
||||
hub_driver_t *hub_driver_obj = heap_caps_calloc(1, sizeof(hub_driver_t), MALLOC_CAP_DEFAULT);
|
||||
urb_t *enum_urb = urb_alloc(sizeof(usb_setup_packet_t) + ENUM_CTRL_TRANSFER_MAX_DATA_LEN, 0, 0);
|
||||
urb_t *enum_urb = urb_alloc(sizeof(usb_setup_packet_t) + ENUM_CTRL_TRANSFER_MAX_DATA_LEN, 0);
|
||||
if (hub_driver_obj == NULL || enum_urb == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -43,7 +43,6 @@ struct urb_s {
|
||||
uint32_t hcd_var;
|
||||
// Host Lib Layer:
|
||||
void *usb_host_client; // Currently only used when submitted to shared pipes (i.e., Device default pipes)
|
||||
size_t usb_host_header_size; // USB Host may need the data buffer to have a transparent header
|
||||
bool usb_host_inflight; // Debugging variable, used to prevent re-submitting URBs already inflight
|
||||
// Public transfer structure. Must be last due to variable length array
|
||||
usb_transfer_t transfer;
|
||||
@ -76,15 +75,13 @@ typedef bool (*usb_proc_req_cb_t)(usb_proc_req_source_t source, bool in_isr, voi
|
||||
*
|
||||
* - Data buffer is allocated in DMA capable memory
|
||||
* - The constant fields of the URB are also set
|
||||
* - The data_buffer field of the URB is set to point to start of the allocated data buffer AFTER the header. To access
|
||||
* the header, users need a negative offset from data_buffer.
|
||||
* - The data_buffer field of the URB is set to point to start of the allocated data buffer.
|
||||
*
|
||||
* @param data_buffer_size Size of the URB's data buffer
|
||||
* @param header_size Size of header to put in front of URB's data buffer
|
||||
* @param num_isoc_packets Number of isochronous packet descriptors
|
||||
* @return urb_t* URB object
|
||||
*/
|
||||
urb_t *urb_alloc(size_t data_buffer_size, size_t header_size, int num_isoc_packets);
|
||||
urb_t *urb_alloc(size_t data_buffer_size, int num_isoc_packets);
|
||||
|
||||
/**
|
||||
* @brief Free a URB
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -94,11 +94,9 @@ struct client_s {
|
||||
TAILQ_HEAD(tailhead_done_ctrl_xfers, urb_s) done_ctrl_xfer_tailq;
|
||||
union {
|
||||
struct {
|
||||
uint32_t events_pending: 1;
|
||||
uint32_t handling_events: 1;
|
||||
uint32_t blocked: 1;
|
||||
uint32_t taking_mux: 1;
|
||||
uint32_t reserved4: 4;
|
||||
uint32_t reserved6: 6;
|
||||
uint32_t num_intf_claimed: 8;
|
||||
uint32_t reserved16: 16;
|
||||
};
|
||||
@ -128,10 +126,8 @@ typedef struct {
|
||||
uint32_t lib_event_flags;
|
||||
union {
|
||||
struct {
|
||||
uint32_t process_pending: 1;
|
||||
uint32_t handling_events: 1;
|
||||
uint32_t blocked: 1;
|
||||
uint32_t reserved5: 5;
|
||||
uint32_t reserved7: 7;
|
||||
uint32_t num_clients: 8;
|
||||
uint32_t reserved16: 16;
|
||||
};
|
||||
@ -176,24 +172,16 @@ static inline bool _check_client_opened_device(client_t *client_obj, uint8_t dev
|
||||
|
||||
static bool _unblock_client(client_t *client_obj, bool in_isr)
|
||||
{
|
||||
bool send_sem;
|
||||
if (!client_obj->dynamic.flags.events_pending && !client_obj->dynamic.flags.handling_events) {
|
||||
client_obj->dynamic.flags.events_pending = 1;
|
||||
send_sem = true;
|
||||
} else {
|
||||
send_sem = false;
|
||||
}
|
||||
bool yield;
|
||||
|
||||
HOST_EXIT_CRITICAL_SAFE();
|
||||
bool yield = false;
|
||||
if (send_sem) {
|
||||
if (in_isr) {
|
||||
BaseType_t xTaskWoken = pdFALSE;
|
||||
xSemaphoreGiveFromISR(client_obj->constant.event_sem, &xTaskWoken);
|
||||
yield = (xTaskWoken == pdTRUE);
|
||||
} else {
|
||||
xSemaphoreGive(client_obj->constant.event_sem);
|
||||
}
|
||||
yield = false;
|
||||
}
|
||||
HOST_ENTER_CRITICAL_SAFE();
|
||||
|
||||
@ -202,24 +190,16 @@ static bool _unblock_client(client_t *client_obj, bool in_isr)
|
||||
|
||||
static bool _unblock_lib(bool in_isr)
|
||||
{
|
||||
bool send_sem;
|
||||
if (!p_host_lib_obj->dynamic.flags.process_pending && !p_host_lib_obj->dynamic.flags.handling_events) {
|
||||
p_host_lib_obj->dynamic.flags.process_pending = 1;
|
||||
send_sem = true;
|
||||
} else {
|
||||
send_sem = false;
|
||||
}
|
||||
bool yield;
|
||||
|
||||
HOST_EXIT_CRITICAL_SAFE();
|
||||
bool yield = false;
|
||||
if (send_sem) {
|
||||
if (in_isr) {
|
||||
BaseType_t xTaskWoken = pdFALSE;
|
||||
xSemaphoreGiveFromISR(p_host_lib_obj->constant.event_sem, &xTaskWoken);
|
||||
yield = (xTaskWoken == pdTRUE);
|
||||
} else {
|
||||
xSemaphoreGive(p_host_lib_obj->constant.event_sem);
|
||||
}
|
||||
yield = false;
|
||||
}
|
||||
HOST_ENTER_CRITICAL_SAFE();
|
||||
|
||||
@ -515,45 +495,49 @@ esp_err_t usb_host_uninstall(void)
|
||||
|
||||
esp_err_t usb_host_lib_handle_events(TickType_t timeout_ticks, uint32_t *event_flags_ret)
|
||||
{
|
||||
esp_err_t ret;
|
||||
uint32_t event_flags = 0;
|
||||
// Check arguments and state
|
||||
HOST_CHECK(p_host_lib_obj != NULL, ESP_ERR_INVALID_STATE);
|
||||
|
||||
esp_err_t ret = (timeout_ticks == 0) ? ESP_OK : ESP_ERR_TIMEOUT; // We don't want to return ESP_ERR_TIMEOUT if we aren't blocking
|
||||
uint32_t event_flags;
|
||||
|
||||
HOST_ENTER_CRITICAL();
|
||||
if (!p_host_lib_obj->dynamic.flags.process_pending) {
|
||||
// There is currently processing that needs to be done. Wait for some processing
|
||||
// Set handling_events flag. This prevents the host library from being uninstalled
|
||||
p_host_lib_obj->dynamic.flags.handling_events = 1;
|
||||
HOST_EXIT_CRITICAL();
|
||||
BaseType_t sem_ret = xSemaphoreTake(p_host_lib_obj->constant.event_sem, timeout_ticks);
|
||||
if (sem_ret == pdFALSE) {
|
||||
ret = ESP_ERR_TIMEOUT;
|
||||
goto exit;
|
||||
}
|
||||
HOST_ENTER_CRITICAL();
|
||||
|
||||
while (1) {
|
||||
// Loop until there are no more events
|
||||
if (xSemaphoreTake(p_host_lib_obj->constant.event_sem, timeout_ticks) == pdFALSE) {
|
||||
// Timed out waiting for semaphore or currently no events
|
||||
break;
|
||||
}
|
||||
|
||||
// Read and clear process pending flags
|
||||
HOST_ENTER_CRITICAL();
|
||||
uint32_t process_pending_flags = p_host_lib_obj->dynamic.process_pending_flags;
|
||||
p_host_lib_obj->dynamic.process_pending_flags = 0;
|
||||
p_host_lib_obj->dynamic.flags.handling_events = 1;
|
||||
while (process_pending_flags) {
|
||||
HOST_EXIT_CRITICAL();
|
||||
|
||||
if (process_pending_flags & PROCESS_REQUEST_PENDING_FLAG_USBH) {
|
||||
ESP_ERROR_CHECK(usbh_process());
|
||||
}
|
||||
if (process_pending_flags & PROCESS_REQUEST_PENDING_FLAG_HUB) {
|
||||
ESP_ERROR_CHECK(hub_process());
|
||||
}
|
||||
HOST_ENTER_CRITICAL();
|
||||
// Read and clear process pending flags again, and loop back if there is more to process
|
||||
process_pending_flags = p_host_lib_obj->dynamic.process_pending_flags;
|
||||
p_host_lib_obj->dynamic.process_pending_flags = 0;
|
||||
|
||||
ret = ESP_OK;
|
||||
// Set timeout_ticks to 0 so that we can check for events again without blocking
|
||||
timeout_ticks = 0;
|
||||
}
|
||||
p_host_lib_obj->dynamic.flags.process_pending = 0;
|
||||
|
||||
HOST_ENTER_CRITICAL();
|
||||
p_host_lib_obj->dynamic.flags.handling_events = 0;
|
||||
// Read and clear any event flags
|
||||
event_flags = p_host_lib_obj->dynamic.lib_event_flags;
|
||||
p_host_lib_obj->dynamic.lib_event_flags = 0;
|
||||
HOST_EXIT_CRITICAL();
|
||||
|
||||
ret = ESP_OK;
|
||||
exit:
|
||||
if (event_flags_ret != NULL) {
|
||||
*event_flags_ret = event_flags;
|
||||
}
|
||||
@ -709,7 +693,6 @@ esp_err_t usb_host_client_deregister(usb_host_client_handle_t client_hdl)
|
||||
!TAILQ_EMPTY(&client_obj->dynamic.idle_ep_tailq) ||
|
||||
!TAILQ_EMPTY(&client_obj->dynamic.done_ctrl_xfer_tailq) ||
|
||||
client_obj->dynamic.flags.handling_events ||
|
||||
client_obj->dynamic.flags.blocked ||
|
||||
client_obj->dynamic.flags.taking_mux ||
|
||||
client_obj->dynamic.flags.num_intf_claimed != 0 ||
|
||||
client_obj->dynamic.num_done_ctrl_xfer != 0 ||
|
||||
@ -746,28 +729,26 @@ exit:
|
||||
|
||||
esp_err_t usb_host_client_handle_events(usb_host_client_handle_t client_hdl, TickType_t timeout_ticks)
|
||||
{
|
||||
// Check arguments and state
|
||||
HOST_CHECK(client_hdl != NULL, ESP_ERR_INVALID_ARG);
|
||||
esp_err_t ret;
|
||||
HOST_CHECK(p_host_lib_obj != NULL, ESP_ERR_INVALID_STATE);
|
||||
|
||||
esp_err_t ret = (timeout_ticks == 0) ? ESP_OK : ESP_ERR_TIMEOUT; // We don't want to return ESP_ERR_TIMEOUT if we aren't blocking
|
||||
client_t *client_obj = (client_t *)client_hdl;
|
||||
|
||||
HOST_ENTER_CRITICAL();
|
||||
if (!client_obj->dynamic.flags.events_pending) {
|
||||
// There are currently no events, wait for one to occur
|
||||
client_obj->dynamic.flags.blocked = 1;
|
||||
HOST_EXIT_CRITICAL();
|
||||
BaseType_t sem_ret = xSemaphoreTake(client_obj->constant.event_sem, timeout_ticks);
|
||||
HOST_ENTER_CRITICAL();
|
||||
client_obj->dynamic.flags.blocked = 0;
|
||||
if (sem_ret == pdFALSE) {
|
||||
HOST_EXIT_CRITICAL();
|
||||
// Timed out waiting for semaphore
|
||||
ret = ESP_ERR_TIMEOUT;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
// Mark that we're processing events
|
||||
// Set handling_events flag. This prevents the client from being deregistered
|
||||
client_obj->dynamic.flags.handling_events = 1;
|
||||
while (client_obj->dynamic.flags.handling_events) {
|
||||
HOST_EXIT_CRITICAL();
|
||||
|
||||
while (1) {
|
||||
// Loop until there are no more events
|
||||
if (xSemaphoreTake(client_obj->constant.event_sem, timeout_ticks) == pdFALSE) {
|
||||
// Timed out waiting for semaphore or currently no events
|
||||
break;
|
||||
}
|
||||
|
||||
HOST_ENTER_CRITICAL();
|
||||
// Handle pending endpoints
|
||||
if (!TAILQ_EMPTY(&client_obj->dynamic.pending_ep_tailq)) {
|
||||
_handle_pending_ep(client_obj);
|
||||
@ -784,29 +765,26 @@ esp_err_t usb_host_client_handle_events(usb_host_client_handle_t client_hdl, Tic
|
||||
urb->transfer.callback(&urb->transfer);
|
||||
HOST_ENTER_CRITICAL();
|
||||
}
|
||||
HOST_EXIT_CRITICAL();
|
||||
|
||||
// Handle event messages
|
||||
while (uxQueueMessagesWaiting(client_obj->constant.event_msg_queue) > 0) {
|
||||
HOST_EXIT_CRITICAL();
|
||||
// Dequeue the event message and call the client event callback
|
||||
usb_host_client_event_msg_t event_msg;
|
||||
BaseType_t queue_ret = xQueueReceive(client_obj->constant.event_msg_queue, &event_msg, 0);
|
||||
assert(queue_ret == pdTRUE);
|
||||
client_obj->constant.event_callback(&event_msg, client_obj->constant.callback_arg);
|
||||
HOST_ENTER_CRITICAL();
|
||||
}
|
||||
// Check each event again to see any new events occurred
|
||||
if (TAILQ_EMPTY(&client_obj->dynamic.pending_ep_tailq) &&
|
||||
client_obj->dynamic.num_done_ctrl_xfer == 0 &&
|
||||
uxQueueMessagesWaiting(client_obj->constant.event_msg_queue) == 0) {
|
||||
// All pending endpoints and event messages handled
|
||||
client_obj->dynamic.flags.events_pending = 0;
|
||||
client_obj->dynamic.flags.handling_events = 0;
|
||||
}
|
||||
}
|
||||
HOST_EXIT_CRITICAL();
|
||||
|
||||
ret = ESP_OK;
|
||||
exit:
|
||||
// Set timeout_ticks to 0 so that we can check for events again without blocking
|
||||
timeout_ticks = 0;
|
||||
}
|
||||
|
||||
HOST_ENTER_CRITICAL();
|
||||
client_obj->dynamic.flags.handling_events = 0;
|
||||
HOST_EXIT_CRITICAL();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1245,7 +1223,7 @@ exit:
|
||||
|
||||
esp_err_t usb_host_transfer_alloc(size_t data_buffer_size, int num_isoc_packets, usb_transfer_t **transfer)
|
||||
{
|
||||
urb_t *urb = urb_alloc(data_buffer_size, 0, num_isoc_packets);
|
||||
urb_t *urb = urb_alloc(data_buffer_size, num_isoc_packets);
|
||||
if (urb == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -8,17 +8,16 @@
|
||||
#include "usb_private.h"
|
||||
#include "usb/usb_types_ch9.h"
|
||||
|
||||
urb_t *urb_alloc(size_t data_buffer_size, size_t header_size, int num_isoc_packets)
|
||||
urb_t *urb_alloc(size_t data_buffer_size, int num_isoc_packets)
|
||||
{
|
||||
urb_t *urb = heap_caps_calloc(1, sizeof(urb_t) + (sizeof(usb_isoc_packet_desc_t) * num_isoc_packets), MALLOC_CAP_DEFAULT);
|
||||
uint8_t *data_buffer = heap_caps_malloc(data_buffer_size + header_size, MALLOC_CAP_DMA);
|
||||
uint8_t *data_buffer = heap_caps_malloc(data_buffer_size, MALLOC_CAP_DMA);
|
||||
if (urb == NULL || data_buffer == NULL) {
|
||||
goto err;
|
||||
}
|
||||
urb->usb_host_header_size = header_size; // Indicate that this URB's data_buffer has a header in front of it.
|
||||
// Case as dummy transfer to write to initialize const fields
|
||||
// Cast as dummy transfer so that we can assign to const fields
|
||||
usb_transfer_dummy_t *dummy_transfer = (usb_transfer_dummy_t *)&urb->transfer;
|
||||
dummy_transfer->data_buffer = (uint8_t *)(data_buffer + header_size);
|
||||
dummy_transfer->data_buffer = data_buffer;
|
||||
dummy_transfer->data_buffer_size = data_buffer_size;
|
||||
dummy_transfer->num_isoc_packets = num_isoc_packets;
|
||||
return urb;
|
||||
@ -33,6 +32,6 @@ void urb_free(urb_t *urb)
|
||||
if (urb == NULL) {
|
||||
return;
|
||||
}
|
||||
heap_caps_free((uint8_t *)(urb->transfer.data_buffer - urb->usb_host_header_size));
|
||||
heap_caps_free(urb->transfer.data_buffer);
|
||||
heap_caps_free(urb);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user