10浏览
查看: 10|回复: 2

[ESP8266/ESP32] ESP32S3制作的ESP32S3烧写器

[复制链接]
很多年前开始玩Arduino的时候使用的是Arduino Uno,它使用 Atmel328P 的主控。当时有一个有趣的项目是使用Uno给另外一个设备刷写BootLoader。这个项目能够极大的方便使用Arduino
这次的项目是一个使用ESP32-S3 实现的 ESP32 下载器。
硬件部分非常简单,可以看做是一个ESP32S3 的最小系统。



zoologist  高级技匠
 楼主|

发表于 2 小时前

ESP32S3制作的ESP32S3烧写器图1

ESP32S3制作的ESP32S3烧写器图2
回复

使用道具 举报

zoologist  高级技匠
 楼主|

发表于 2 小时前

代码使用 IDF 编写,首先实现基于 TinyUSB 的 USB CDC 功能。
1.TinyUSB 是 IDF 内置的原生 USB 库,通过下面的代码就可以实现 USB CDC 功能
  ESP_LOGI(TAG, "USB initialization");
  const tinyusb_config_t tusb_cfg = {
    .device_descriptor = NULL,
    .string_descriptor = NULL,
    .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 = &tinyusb_cdc_line_state_changed_callback,
    .callback_line_coding_changed = &tinyusb_cdc_line_coding_changed_callback
  };
  ESP_ERROR_CHECK(tusb_cdc_acm_init(&acm_cfg));
  ESP_LOGI(TAG, "USB initialization DONE");

2.之后, USB CDC收到的数据会出现在下面再合格回调函数中
void tinyusb_cdc_rx_callback(int itf, cdcacm_event_t *event)
{
  // USB CDC 接收的处理
  uint8_t rx_buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE];
  size_t rx_size = 0;
  // 读取放入 rx_buf 缓冲区
  esp_err_t ret = tinyusb_cdcacm_read(itf, rx_buf, CONFIG_TINYUSB_CDC_RX_BUFSIZE, &rx_size);
  if (ret == ESP_OK) {
    // 根据资料,如果缓冲区有足够的空间,那么不会阻塞
    uart_write_bytes(UART_NUM_1,rx_buf,rx_size);
  } else {
    ESP_LOGE(TAG, "Read Error");
  }
}
3.Arduino ESP32 的烧写工具是 ESPTool,它通过将串口波特率从 9600切换到 115200 来通知 ESP32S3进入下载模式(这部分代码可以在 ESP32 的库中看到)
对饮的,我们在代码中做一个判断,如果出现了这样的切换,那么通过2个 GPIO 拉被刷机进入下载模式,然后通过串口通讯完成下载

// 设置波特率的回调函数
void tinyusb_cdc_line_coding_changed_callback(int itf, cdcacm_event_t *event)
{
  cdc_line_coding_t *line_coding = event->line_coding_changed_data.p_line_coding;
  Baudrate = line_coding->bit_rate;
  if (previous_Baudrate != Baudrate) {
    ESP_LOGI(TAG, "Change Baudrate from %lu to %lu", previous_Baudrate, Baudrate);
   
    // 如果出现从 9600 波特率到 115200 的切换,那么说明是要进入下载模式
    if ((previous_Baudrate==9600)&&(Baudrate==115200)) {
        DownloadMode=true;
    }
    if ((Baudrate==115200)||(Baudrate==921600)) {
        uart_set_baudrate(UART_NUM_1, Baudrate);
    }
    previous_Baudrate=Baudrate;
  }
}

最终烧写代码后,可以通过下面这个命令进行简单测试,它会让ESP32 S3进入下载模式,然后通过命令读取MAC地址,基本上这个命令如果可以跑过,那么烧写也没有问题

Esptool5 --trace -c esp32s3 -p com19 read-mac
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail