2025-01-28 18:18:50 +01:00

99 lines
3.2 KiB
C++

#include "../include/SerialUSBHost.h"
static SemaphoreHandle_t device_disconnected_sem;//XXX
static const char *TAG = "VCP example";
/**
* @brief Data received callback
*
* Just pass received data to stdout
*
* @param[in] data Pointer to received data
* @param[in] data_len Length of received data in bytes
* @param[in] arg Argument we passed to the device open function
* @return
* true: We have processed the received data
* false: We expect more data
*/
bool SerialUSBHost::handle_rx(const uint8_t *data, size_t data_len, void *arg)
{
printf("%.*s", data_len, data);
return true;
}
/**
* @brief Device event callback
*
* Apart from handling device disconnection it doesn't do anything useful
*
* @param[in] event Device event type and data
* @param[in] user_ctx Argument we passed to the device open function
*/
void SerialUSBHost::handle_event(const cdc_acm_host_dev_event_data_t *event, void *user_ctx)
{
switch (event->type) {
case CDC_ACM_HOST_ERROR:
ESP_LOGE(TAG, "CDC-ACM error has occurred, err_no = %d", event->data.error);
break;
case CDC_ACM_HOST_DEVICE_DISCONNECTED:
ESP_LOGI(TAG, "Device suddenly disconnected");
xSemaphoreGive(device_disconnected_sem);
break;
case CDC_ACM_HOST_SERIAL_STATE:
ESP_LOGI(TAG, "Serial state notif 0x%04X", event->data.serial_state.val);
break;
case CDC_ACM_HOST_NETWORK_CONNECTION:
default: break;
}
}
void SerialUSBHost::usb_lib_task(void* arg) {
const String TAG = "SerialUSBHost_usb_lib_task";
while (1) {
// Start handling system events
uint32_t event_flags;
usb_host_lib_handle_events(portMAX_DELAY, &event_flags);
if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) {
ESP_ERROR_CHECK(usb_host_device_free_all());
}
if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) {
ESP_LOGI(TAG.c_str(), "USB: All devices freed");
// Continue handling USB events to allow device reconnection
}
}
}
void SerialUSBHost::init() {
const String TAG = "SerialUSBHost_constructor";
device_disconnected_sem = xSemaphoreCreateBinary();
assert(device_disconnected_sem);
// Install USB Host driver. Should only be called once in entire application
ESP_LOGI(TAG.c_str(), "Installing USB Host");
const usb_host_config_t host_config = {
.skip_phy_setup = false,
.intr_flags = ESP_INTR_FLAG_LEVEL1,
.enum_filter_cb = nullptr,
};
ESP_ERROR_CHECK(usb_host_install(&host_config));
// Create a task that will handle USB library events
BaseType_t task_created = xTaskCreate(SerialUSBHost::usb_lib_task, "usb_lib", 4096, NULL, 10, NULL);
assert(task_created == pdTRUE);
ESP_LOGI(TAG.c_str(), "Installing CDC-ACM driver");
ESP_ERROR_CHECK(cdc_acm_host_install(NULL));
// Register VCP drivers to VCP service
esp_usb::VCP::register_driver<esp_usb::FT23x>();
esp_usb::VCP::register_driver<esp_usb::CP210x>();
esp_usb::VCP::register_driver<esp_usb::CH34x>();
}
void SerialUSBHost::takeSem(){//XXX
xSemaphoreTake(device_disconnected_sem, portMAX_DELAY);
}