/* * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ #include #include #include #include "esp_partition.h" #include "esp_check.h" #include "tinyusb.h" #include "tusb_msc_storage.h" #include "tusb_cdc_acm.h" #define BASE_PATH "/usb" // base path to mount the partition static const char *TAG = "example_main"; static uint8_t buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE + 1]; void tinyusb_cdc_rx_callback(int itf, cdcacm_event_t *event) { /* initialization */ size_t rx_size = 0; /* read */ esp_err_t ret = tinyusb_cdcacm_read(itf, buf, CONFIG_TINYUSB_CDC_RX_BUFSIZE, &rx_size); if (ret == ESP_OK) { ESP_LOGI(TAG, "Data from channel %d:", itf); ESP_LOG_BUFFER_HEXDUMP(TAG, buf, rx_size, ESP_LOG_INFO); } else { ESP_LOGE(TAG, "Read error"); } /* write back */ tinyusb_cdcacm_write_queue(itf, buf, rx_size); tinyusb_cdcacm_write_flush(itf, 0); } void tinyusb_cdc_line_state_changed_callback(int itf, cdcacm_event_t *event) { int dtr = event->line_state_changed_data.dtr; int rts = event->line_state_changed_data.rts; ESP_LOGI(TAG, "Line state changed on channel %d: DTR:%d, RTS:%d", itf, dtr, rts); } static bool file_exists(const char *file_path) { struct stat buffer; return stat(file_path, &buffer) == 0; } static void file_operations(void) { const char *directory = "/usb/esp"; const char *file_path = "/usb/esp/test.txt"; struct stat s = {0}; bool directory_exists = stat(directory, &s) == 0; if (!directory_exists) { if (mkdir(directory, 0775) != 0) { ESP_LOGE(TAG, "mkdir failed with errno: %s", strerror(errno)); } } if (!file_exists(file_path)) { ESP_LOGI(TAG, "Creating file"); FILE *f = fopen(file_path, "w"); if (f == NULL) { ESP_LOGE(TAG, "Failed to open file for writing"); return; } fprintf(f, "Hello World!\n"); fclose(f); } FILE *f; ESP_LOGI(TAG, "Reading file"); f = fopen(file_path, "r"); if (f == NULL) { ESP_LOGE(TAG, "Failed to open file for reading"); return; } char line[64]; fgets(line, sizeof(line), f); fclose(f); // strip newline char *pos = strchr(line, '\n'); if (pos) { *pos = '\0'; } ESP_LOGI(TAG, "Read from file: '%s'", line); } static esp_err_t storage_init_spiflash(wl_handle_t *wl_handle) { ESP_LOGI(TAG, "Initializing wear levelling"); const esp_partition_t *data_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, NULL); if (data_partition == NULL) { ESP_LOGE(TAG, "Failed to find FATFS partition. Check the partition table."); return ESP_ERR_NOT_FOUND; } return wl_mount(data_partition, wl_handle); } void app_main(void) { ESP_LOGI(TAG, "Initializing storage..."); static wl_handle_t wl_handle = WL_INVALID_HANDLE; ESP_ERROR_CHECK(storage_init_spiflash(&wl_handle)); const tinyusb_msc_spiflash_config_t config_spi = { .wl_handle = wl_handle }; ESP_ERROR_CHECK(tinyusb_msc_storage_init_spiflash(&config_spi)); ESP_ERROR_CHECK(tinyusb_msc_storage_mount(BASE_PATH)); file_operations(); ESP_LOGI(TAG, "USB Composite initialization"); const tinyusb_config_t tusb_cfg = { .device_descriptor = NULL, .string_descriptor = NULL, .string_descriptor_count = 0, .external_phy = false, .configuration_descriptor = NULL, }; ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg)); tinyusb_config_cdcacm_t acm_cfg = { .usb_dev = TINYUSB_USBDEV_0, .cdc_port = TINYUSB_CDC_ACM_0, .rx_unread_buf_sz = 64, .callback_rx = &tinyusb_cdc_rx_callback, // the first way to register a callback .callback_rx_wanted_char = NULL, .callback_line_state_changed = NULL, .callback_line_coding_changed = NULL }; ESP_ERROR_CHECK(tusb_cdc_acm_init(&acm_cfg)); /* the second way to register a callback */ ESP_ERROR_CHECK(tinyusb_cdcacm_register_callback( TINYUSB_CDC_ACM_0, CDC_EVENT_LINE_STATE_CHANGED, &tinyusb_cdc_line_state_changed_callback)); ESP_LOGI(TAG, "USB Composite initialization DONE"); }