176 lines
5 KiB
C
176 lines
5 KiB
C
/*
|
|
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
|
*
|
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
|
*/
|
|
|
|
#include <errno.h>
|
|
#include <dirent.h>
|
|
#include <sys/stat.h>
|
|
#include "esp_heap_caps.h"
|
|
#include "esp_partition.h"
|
|
#include "esp_check.h"
|
|
#include "tinyusb.h"
|
|
#include "tusb_msc_psram.h"
|
|
#include "tusb_msc_storage.h"
|
|
#include "tusb_cdc_acm.h"
|
|
|
|
#define BASE_PATH "/usb" // base path to mount the partition
|
|
|
|
#ifdef CONFIG_USB_PSRAM_DRIVE
|
|
#define PSRAM_PARTITON_SIZE (4*1024*1024)
|
|
#endif
|
|
|
|
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);
|
|
}
|
|
|
|
#ifndef CONFIG_USB_PSRAM_DRIVE
|
|
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);
|
|
}
|
|
#endif
|
|
|
|
void app_main(void)
|
|
{
|
|
ESP_LOGI(TAG, "Initializing storage...");
|
|
|
|
#ifdef CONFIG_USB_PSRAM_DRIVE
|
|
uint8_t* const psram_fs_mem = heap_caps_malloc(PSRAM_PARTITON_SIZE, MALLOC_CAP_SPIRAM);
|
|
|
|
const tinyusb_msc_psram_config_t config_psram = {
|
|
.memory=psram_fs_mem,
|
|
.memory_size = PSRAM_PARTITON_SIZE
|
|
};
|
|
|
|
ESP_LOGI(TAG, "Initializing psram msc");
|
|
|
|
ESP_ERROR_CHECK(tinyusb_msc_storage_init_psram(&config_psram));
|
|
ESP_ERROR_CHECK(tinyusb_msc_psram_mount(BASE_PATH));
|
|
|
|
#else
|
|
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));
|
|
#endif
|
|
|
|
ESP_LOGI(TAG, "Initializing file system");
|
|
|
|
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");
|
|
}
|