/* SPDX-License-Identifier: GPL-3.0-or-later * Copyright 2022-2023 King Kévin */ #include #include #include #include "esp_log.h" #include "esp_mac.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "tinyusb.h" #include "tusb_cdc_acm.h" #include "tusb_dfu_rt.h" #include "tusb_console.h" #include "sdkconfig.h" #include "driver/gpio.h" // GPIO to force DFU mode (on high) #define DFU_PIN 14 // GPIO for on-board LED (WEMOS S2 mini, source on) #define LED_BOARD 15 static const char *TAG = "main"; /** * @brief USB string descriptor */ static const char* usb_str_desc[USB_STRING_DESCRIPTOR_ARRAY_SIZE] = { (char[]){0x09, 0x04}, // 0: language: English CONFIG_TINYUSB_DESC_MANUFACTURER_STRING, // 1: Manufacturer CONFIG_TINYUSB_DESC_PRODUCT_STRING, // 2: Product CONFIG_TINYUSB_DESC_SERIAL_STRING, // 3: Serials, should use chip ID CONFIG_TINYUSB_DESC_CDC_STRING, // 4: CDC Interface "", // 5: MSC Interface "DFU (runtime mode)" // 6: DFU RT }; void app_main(void) { // check DFU force gpio_config_t io_conf = {}; // to configure GPIO // GPIO0 can also be pressed while soft reboot io_conf.pin_bit_mask = (1ULL << 0); // GPIO to configure io_conf.intr_type = GPIO_INTR_DISABLE; // disable interrupt io_conf.mode = GPIO_MODE_INPUT; // set as input io_conf.pull_down_en = false; // disable pull-down mode io_conf.pull_up_en = true; // enable pull-up mode ESP_ERROR_CHECK( gpio_config(&io_conf) ); // configure GPIO // dedicated DFU button io_conf.pin_bit_mask = (1ULL << DFU_PIN); // GPIO to configure io_conf.intr_type = GPIO_INTR_DISABLE; // disable interrupt io_conf.mode = GPIO_MODE_INPUT; // set as input io_conf.pull_down_en = 1; // enable pull-down mode io_conf.pull_up_en = 0; // disable pull-up mode ESP_ERROR_CHECK( gpio_config(&io_conf) ); // configure GPIO if (!gpio_get_level(0) || gpio_get_level(DFU_PIN)) { // DFU mode asserted tud_dfu_runtime_reboot_to_dfu_cb(); // reboot to DFU mode } // configure LEDs io_conf.pin_bit_mask = (1ULL << LED_BOARD); // GPIO to configure io_conf.intr_type = GPIO_INTR_DISABLE; // disable interrupt io_conf.mode = GPIO_MODE_INPUT_OUTPUT; // set as output (push-pull), and input to read state io_conf.pull_down_en = 0; // disable pull-down mode io_conf.pull_up_en = 0; // disable pull-up mode ESP_ERROR_CHECK( gpio_config(&io_conf) ); // configure GPIO gpio_set_level(LED_BOARD, 0); // switch running LED off until all is ready // setup USB CDC ACM for printing ESP_LOGI(TAG, "USB initialization"); // get MAC uint8_t mac[6]; esp_read_mac(mac, ESP_MAC_ETH); static char usb_serial[13] = {0}; snprintf(usb_serial, sizeof(usb_serial), "%02X%02X%02X%02X%02X%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); usb_str_desc[3] = usb_serial; const tinyusb_config_t tusb_cfg = { .device_descriptor = NULL, // use default USB descriptor .string_descriptor = usb_str_desc, // use custom string description to set serial .external_phy = false, // use integrated phy .configuration_descriptor = NULL, }; ESP_ERROR_CHECK( tinyusb_driver_install(&tusb_cfg) ); // configure USB tinyusb_config_cdcacm_t amc_cfg = { 0 }; // the configuration uses default values ESP_ERROR_CHECK( tusb_cdc_acm_init(&amc_cfg) ); // configure CDC ACM ESP_ERROR_CHECK( tusb_dfu_rf_init() ); // configure DFU runtime (ensures we can use it) esp_tusb_init_console(TINYUSB_CDC_ACM_0); // log to USB ESP_LOGI(TAG, "USB initialized"); ESP_LOGI(TAG, "application ready"); gpio_set_level(LED_BOARD, 0); // switch running LED on to indicate all is ready while (1) { vTaskDelay(1000 / portTICK_PERIOD_MS); // toggle LED as heart beat if (gpio_get_level(LED_BOARD)) { gpio_set_level(LED_BOARD, 0); } else { gpio_set_level(LED_BOARD, 1); } } }