1 /*
2 * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: CC0-1.0
5 */
6
7 #include <stdio.h>
8 #include <string.h>
9 #include "esp_system.h"
10 #include "freertos/FreeRTOS.h"
11 #include "freertos/task.h"
12 #include "esp_log.h"
13 #include "esp_err.h"
14 #include "usb/usb_host.h"
15 #include "usb/cdc_acm_host.h"
16
17 #define EXAMPLE_USB_HOST_PRIORITY 20
18 #define EXAMPLE_USB_DEVICE_VID 0x303A // 0x303A:0x4001 (TinyUSB CDC device)
19 #define EXAMPLE_USB_DEVICE_PID 0x4001
20
21 static const char *TAG = "USB-CDC";
22
23 /* ------------------------------- Callbacks -------------------------------- */
handle_rx(uint8_t * data,size_t data_len,void * arg)24 static void handle_rx(uint8_t *data, size_t data_len, void *arg)
25 {
26 ESP_LOGI(TAG, "Data received");
27 ESP_LOG_BUFFER_HEXDUMP(TAG, data, data_len, ESP_LOG_INFO);
28 }
29
usb_lib_task(void * arg)30 void usb_lib_task(void *arg)
31 {
32 while (1) {
33 //Start handling system events
34 uint32_t event_flags;
35 usb_host_lib_handle_events(portMAX_DELAY, &event_flags);
36 if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) {
37 ESP_LOGI(TAG, "All clients deregistered");
38 ESP_ERROR_CHECK(usb_host_device_free_all());
39 }
40 if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) {
41 break;
42 }
43 }
44
45 //Clean up USB Host
46 ESP_ERROR_CHECK(usb_host_uninstall());
47 vTaskDelete(NULL);
48 }
49
50 /* ---------------------------------- Main ---------------------------------- */
app_main(void)51 void app_main(void)
52 {
53 //Install USB Host driver. Should only be called once in entire application
54 ESP_LOGI(TAG, "Installing USB Host");
55 usb_host_config_t host_config = {
56 .skip_phy_setup = false,
57 .intr_flags = ESP_INTR_FLAG_LEVEL1,
58 };
59 ESP_ERROR_CHECK(usb_host_install(&host_config));
60
61 // Create a task that will handle USB library events
62 xTaskCreate(usb_lib_task, "usb_lib", 4096, xTaskGetCurrentTaskHandle(), EXAMPLE_USB_HOST_PRIORITY, NULL);
63
64 ESP_LOGI(TAG, "Installing CDC-ACM driver");
65 ESP_ERROR_CHECK(cdc_acm_host_install(NULL));
66
67 ESP_LOGI(TAG, "Opening CDC ACM device 0x%04X:0x%04X", EXAMPLE_USB_DEVICE_VID, EXAMPLE_USB_DEVICE_PID);
68 cdc_acm_dev_hdl_t cdc_dev;
69 const cdc_acm_host_device_config_t dev_config = {
70 .connection_timeout_ms = 5000,
71 .out_buffer_size = 64,
72 .user_arg = NULL,
73 .event_cb = NULL,
74 .data_cb = handle_rx
75 };
76 ESP_ERROR_CHECK(cdc_acm_host_open(EXAMPLE_USB_DEVICE_VID, EXAMPLE_USB_DEVICE_PID, 0, &dev_config, &cdc_dev));
77 assert(cdc_dev);
78 cdc_acm_host_desc_print(cdc_dev);
79 vTaskDelay(100);
80
81 // Test sending and receiving: Send AT commands, responses are handled in handle_rx callback
82 static char text1[] = "AT\r";
83 ESP_ERROR_CHECK(cdc_acm_host_data_tx_blocking(cdc_dev, (uint8_t *)text1, strlen(text1), 1000));
84 vTaskDelay(100);
85
86 static char text2[] = "AT+GSN\r";
87 ESP_ERROR_CHECK(cdc_acm_host_data_tx_blocking(cdc_dev, (uint8_t *)text2, strlen(text2), 1000));
88 vTaskDelay(100);
89
90 // Test Line Coding commands: Get current line coding, change it 9600 7N1 and read again
91 ESP_LOGI(TAG, "Setting up line coding");
92
93 cdc_acm_line_coding_t line_coding;
94 ESP_ERROR_CHECK(cdc_acm_host_line_coding_get(cdc_dev, &line_coding));
95 ESP_LOGI(TAG, "Line Get: Rate: %d, Stop bits: %d, Parity: %d, Databits: %d", line_coding.dwDTERate,
96 line_coding.bCharFormat, line_coding.bParityType, line_coding.bDataBits);
97
98 line_coding.dwDTERate = 9600;
99 line_coding.bDataBits = 7;
100 line_coding.bParityType = 1;
101 line_coding.bCharFormat = 1;
102 ESP_ERROR_CHECK(cdc_acm_host_line_coding_set(cdc_dev, &line_coding));
103 ESP_LOGI(TAG, "Line Set: Rate: %d, Stop bits: %d, Parity: %d, Databits: %d", line_coding.dwDTERate,
104 line_coding.bCharFormat, line_coding.bParityType, line_coding.bDataBits);
105
106 ESP_ERROR_CHECK(cdc_acm_host_line_coding_get(cdc_dev, &line_coding));
107 ESP_LOGI(TAG, "Line Get: Rate: %d, Stop bits: %d, Parity: %d, Databits: %d", line_coding.dwDTERate,
108 line_coding.bCharFormat, line_coding.bParityType, line_coding.bDataBits);
109
110 ESP_ERROR_CHECK(cdc_acm_host_set_control_line_state(cdc_dev, true, false));
111
112 ESP_LOGI(TAG, "Example finished successfully!");
113 }
114