1.ESP32-S2 USB烧录 输出日志
2.ESP32-S2 USB 挂载内部Flash,当作U盘使用,无线U盘
3.ESP32-S2 USB 挂载SPI-SD,当作U盘使用,无线U盘
4. ESP32S3 使用USB 加载SD_SDIO 当作 U盘使用
需要IDF-v4.4
的环境,因为后面使用到的tinyusb
依赖v4.4
USB库下载链接:github.com/espressif/esp-iot-solution
tinyusb
添加至项目中这里使用 SDMMC
官方例程进行移植
注意:你放置的esp-iot-solution
是不是在IDF的根目录下!
set(EXTRA_COMPONENT_DIRS {IDF_PATH}/esp-iot-solution/components/usb/tinyusb)
首先将芯片设置为 ESP32S3
,否则下面步骤无法操作
/* SD card and FAT filesystem example.
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
// This example uses SDMMC peripheral to communicate with SD card.
#include
#include
#include
#include "esp_vfs_fat.h"
#include "sdmmc_cmd.h"
#include "driver/sdmmc_host.h"
#include "tusb_msc.h"
#include "tusb_cdc_acm.h"
static const char *TAG = "example";
#define MOUNT_POINT "/sdcard"
static bool usb_install = false;
static bool usb_cdc = false;
static uint8_t buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE + 1];
static void tinyusb_cdc_rx_callback(int itf, cdcacm_event_t *event)
{
/* initialization */
size_t rx_size = 0;
printf("%s need = %d\n", __func__, CONFIG_TINYUSB_CDC_RX_BUFSIZE);
/* read */
esp_err_t ret = tinyusb_cdcacm_read(itf, buf, CONFIG_TINYUSB_CDC_RX_BUFSIZE, &rx_size);
if (ret == ESP_OK) {
printf("rx_buf[%s]\n", buf);
} else {
ESP_LOGE(TAG, "Read error");
}
}
void usb_cdc_init(void)
{
if(usb_install == false)
{
tinyusb_config_t tusb_cfg = {
.descriptor = NULL,
.string_descriptor = NULL,
.external_phy = false // In the most cases you need to use a `false` value
};
ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
usb_install = true;
}
tinyusb_config_cdcacm_t amc_cfg = {
.usb_dev = TINYUSB_USBDEV_0,
.cdc_port = TINYUSB_CDC_ACM_0,
.rx_unread_buf_sz = 4096,
.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
}; // the configuration uses default values
ESP_ERROR_CHECK(tusb_cdc_acm_init(&amc_cfg));
usb_cdc = true;
ESP_LOGI(TAG, "USB initialization cdc device DONE");
}
void usb_msc_init(void)
{
if(usb_install == false)
{
tinyusb_config_t tusb_cfg = {
.descriptor = NULL,
.string_descriptor = NULL,
.external_phy = false // In the most cases you need to use a `false` value
};
ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
usb_install = true;
}
tinyusb_config_msc_t msc_cfg = {
.pdrv = 0,
};
ESP_ERROR_CHECK(tusb_msc_init(&msc_cfg));
ESP_LOGI(TAG, "USB initialization msc device DONE");
}
void cdc_printf(const char* fmt,...)
{
if(usb_cdc == true)
{
uint8_t buffer[256] = {0};
va_list ap;
va_start(ap,fmt); //ap指向fmt的地址
vsprintf((char *)buffer,fmt,ap); //vsprintf返回数组的长度
va_end(ap);
tinyusb_cdcacm_write_queue(0,buffer,strlen((const char *)buffer));
tud_cdc_n_write_flush(0);
// tinyusb_cdcacm_write_flush(0, 0);
}
}
void app_main(void)
{
esp_err_t ret;
// Options for mounting the filesystem.
// If format_if_mount_failed is set to true, SD card will be partitioned and
// formatted in case when mounting fails.
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
#ifdef CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED
.format_if_mount_failed = true,
#else
.format_if_mount_failed = false,
#endif // EXAMPLE_FORMAT_IF_MOUNT_FAILED
.max_files = 5,
.allocation_unit_size = 16 * 1024
};
sdmmc_card_t *card;
const char mount_point[] = MOUNT_POINT;
ESP_LOGI(TAG, "Initializing SD card");
// Use settings defined above to initialize SD card and mount FAT filesystem.
// Note: esp_vfs_fat_sdmmc/sdspi_mount is all-in-one convenience functions.
// Please check its source code and implement error recovery when developing
// production applications.
ESP_LOGI(TAG, "Using SDMMC peripheral");
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
// This initializes the slot without card detect (CD) and write protect (WP) signals.
// Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
// To use 1-line SD mode, change this to 1:
slot_config.width = 4;
// On chips where the GPIOs used for SD card can be configured, set them in
// the slot_config structure:
#ifdef SOC_SDMMC_USE_GPIO_MATRIX
slot_config.clk = GPIO_NUM_14;
slot_config.cmd = GPIO_NUM_11;
slot_config.d0 = GPIO_NUM_4;
slot_config.d1 = GPIO_NUM_45;
slot_config.d2 = GPIO_NUM_48;
slot_config.d3 = GPIO_NUM_13;
#endif
// Enable internal pullups on enabled pins. The internal pullups
// are insufficient however, please make sure 10k external pullups are
// connected on the bus. This is for debug / example purpose only.
slot_config.flags |= SDMMC_SLOT_FLAG_INTERNAL_PULLUP;
ESP_LOGI(TAG, "Mounting filesystem");
ret = esp_vfs_fat_sdmmc_mount(mount_point, &host, &slot_config, &mount_config, &card);
if (ret != ESP_OK) {
if (ret == ESP_FAIL) {
ESP_LOGE(TAG, "Failed to mount filesystem. "
"If you want the card to be formatted, set the EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option.");
} else {
ESP_LOGE(TAG, "Failed to initialize the card (%s). "
"Make sure SD card lines have pull-up resistors in place.", esp_err_to_name(ret));
}
return;
}
ESP_LOGI(TAG, "Filesystem mounted");
// Card has been initialized, print its properties
sdmmc_card_print_info(stdout, card);
// Use POSIX and C standard library functions to work with files:
// First create a file.
const char *file_hello = MOUNT_POINT"/hello.txt";
ESP_LOGI(TAG, "Opening file %s", file_hello);
FILE *f = fopen(file_hello, "w");
if (f == NULL) {
ESP_LOGE(TAG, "Failed to open file for writing");
return;
}
fprintf(f, "Hello %s!\n", card->cid.name);
fclose(f);
ESP_LOGI(TAG, "File written");
const char *file_foo = MOUNT_POINT"/foo.txt";
// Check if destination file exists before renaming
struct stat st;
if (stat(file_foo, &st) == 0) {
// Delete it if it exists
unlink(file_foo);
}
// Rename original file
ESP_LOGI(TAG, "Renaming file %s to %s", file_hello, file_foo);
if (rename(file_hello, file_foo) != 0) {
ESP_LOGE(TAG, "Rename failed");
return;
}
// Open renamed file for reading
ESP_LOGI(TAG, "Reading file %s", file_foo);
f = fopen(file_foo, "r");
if (f == NULL) {
ESP_LOGE(TAG, "Failed to open file for reading");
return;
}
// Read a line from file
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);
usb_cdc_init();
usb_msc_init();
while(1)
{
cdc_printf("test\r\n") ;
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
// All done, unmount partition and disable SDMMC peripheral
// esp_vfs_fat_sdcard_unmount(mount_point, card);
ESP_LOGI(TAG, "Card unmounted");
}
编译烧录
使用的SDIO接口,但是速度都点慢。之前使用SPI_SD 上次速度都有600~300kb/s左右,之后慢慢研究。。。
补充:将 MSC FIFO size
修改成 4096 上传/下载的速度立马提升几倍
感谢 :https://blog.csdn.net/wang123qweasd/article/details/127382780