99 lines
3.2 KiB
C++
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);
|
|
} |