Add support for the hardware CDC in ESP32-C3 (#5614)
* Add support for the hardware CDC in ESP32-C3
This commit is contained in:
parent
a62979d8a0
commit
4a55ff970d
@ -32,6 +32,7 @@ set(CORE_SRCS
|
||||
cores/esp32/stdlib_noniso.c
|
||||
cores/esp32/Stream.cpp
|
||||
cores/esp32/StreamString.cpp
|
||||
cores/esp32/HWCDC.cpp
|
||||
cores/esp32/USB.cpp
|
||||
cores/esp32/USBCDC.cpp
|
||||
cores/esp32/USBMSC.cpp
|
||||
|
16
boards.txt
16
boards.txt
@ -21,12 +21,16 @@ menu.EventsCore=Events Run On
|
||||
##############################################################
|
||||
|
||||
esp32c3.name=ESP32C3 Dev Module
|
||||
esp32c3.vid.0=0x303a
|
||||
esp32c3.pid.0=0x1001
|
||||
|
||||
esp32c3.upload.tool=esptool_py
|
||||
esp32c3.upload.maximum_size=1310720
|
||||
esp32c3.upload.maximum_data_size=327680
|
||||
esp32c3.upload.flags=
|
||||
esp32c3.upload.extra_flags=
|
||||
esp32c3.upload.use_1200bps_touch=false
|
||||
esp32c3.upload.wait_for_upload_port=false
|
||||
|
||||
esp32c3.serial.disableDTR=false
|
||||
esp32c3.serial.disableRTS=false
|
||||
@ -48,6 +52,18 @@ esp32c3.build.boot=qio
|
||||
esp32c3.build.partitions=default
|
||||
esp32c3.build.defines=
|
||||
|
||||
esp32c3.menu.CDCOnBoot.default=Disabled
|
||||
esp32c3.menu.CDCOnBoot.default.build.cdc_on_boot=0
|
||||
esp32c3.menu.CDCOnBoot.cdc=Enabled
|
||||
esp32c3.menu.CDCOnBoot.cdc.build.cdc_on_boot=1
|
||||
|
||||
esp32c3.menu.UploadMode.default=UART0
|
||||
esp32c3.menu.UploadMode.default.upload.use_1200bps_touch=false
|
||||
esp32c3.menu.UploadMode.default.upload.wait_for_upload_port=false
|
||||
esp32c3.menu.UploadMode.cdc=Internal USB
|
||||
esp32c3.menu.UploadMode.cdc.upload.use_1200bps_touch=true
|
||||
esp32c3.menu.UploadMode.cdc.upload.wait_for_upload_port=true
|
||||
|
||||
esp32c3.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS)
|
||||
esp32c3.menu.PartitionScheme.default.build.partitions=default
|
||||
esp32c3.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS)
|
||||
|
283
cores/esp32/HWCDC.cpp
Normal file
283
cores/esp32/HWCDC.cpp
Normal file
@ -0,0 +1,283 @@
|
||||
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include "USB.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
|
||||
#include "esp32-hal.h"
|
||||
#include "HWCDC.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/ringbuf.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "soc/periph_defs.h"
|
||||
#include "hal/usb_serial_jtag_ll.h"
|
||||
|
||||
static RingbufHandle_t tx_ring_buf = NULL;
|
||||
static xQueueHandle rx_queue = NULL;
|
||||
static uint8_t rx_data_buf[64];
|
||||
static intr_handle_t intr_handle = NULL;
|
||||
static volatile bool initial_empty = false;
|
||||
|
||||
static void hw_cdc_isr_handler(void *arg) {
|
||||
portBASE_TYPE xTaskWoken = 0;
|
||||
uint32_t usbjtag_intr_status = 0;
|
||||
usbjtag_intr_status = usb_serial_jtag_ll_get_intsts_mask();
|
||||
|
||||
if (usbjtag_intr_status & USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY) {
|
||||
// Interrupt tells us the host picked up the data we sent.
|
||||
if (usb_serial_jtag_ll_txfifo_writable() == 1) {
|
||||
// We disable the interrupt here so that the interrupt won't be triggered if there is no data to send.
|
||||
usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
|
||||
|
||||
if(!initial_empty){
|
||||
initial_empty = true;
|
||||
//send event?
|
||||
//ets_printf("CONNECTED\n");
|
||||
}
|
||||
size_t queued_size;
|
||||
uint8_t *queued_buff = (uint8_t *)xRingbufferReceiveUpToFromISR(tx_ring_buf, &queued_size, 64);
|
||||
// If the hardware fifo is avaliable, write in it. Otherwise, do nothing.
|
||||
if (queued_buff != NULL) { //Although tx_queued_bytes may be larger than 0. We may have interrupt before xRingbufferSend() was called.
|
||||
//Copy the queued buffer into the TX FIFO
|
||||
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
|
||||
usb_serial_jtag_ll_write_txfifo(queued_buff, queued_size);
|
||||
usb_serial_jtag_ll_txfifo_flush();
|
||||
vRingbufferReturnItemFromISR(tx_ring_buf, queued_buff, &xTaskWoken);
|
||||
usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
|
||||
//send event?
|
||||
//ets_printf("TX:%u\n", queued_size);
|
||||
}
|
||||
} else {
|
||||
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
|
||||
}
|
||||
}
|
||||
|
||||
if (usbjtag_intr_status & USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT) {
|
||||
// read rx buffer(max length is 64), and send avaliable data to ringbuffer.
|
||||
// Ensure the rx buffer size is larger than RX_MAX_SIZE.
|
||||
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT);
|
||||
uint32_t rx_fifo_len = usb_serial_jtag_ll_read_rxfifo(rx_data_buf, 64);
|
||||
uint32_t i=0;
|
||||
for(i=0; i<rx_fifo_len; i++){
|
||||
if(rx_queue == NULL || !xQueueSendFromISR(rx_queue, rx_data_buf+i, &xTaskWoken)){
|
||||
break;
|
||||
}
|
||||
}
|
||||
//send event?
|
||||
//ets_printf("RX:%u/%u\n", i, rx_fifo_len);
|
||||
}
|
||||
|
||||
if (usbjtag_intr_status & USB_SERIAL_JTAG_INTR_BUS_RESET) {
|
||||
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_BUS_RESET);
|
||||
initial_empty = false;
|
||||
usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
|
||||
//ets_printf("BUS_RESET\n");
|
||||
}
|
||||
|
||||
if (xTaskWoken == pdTRUE) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
}
|
||||
|
||||
static void ARDUINO_ISR_ATTR cdc0_write_char(char c) {
|
||||
if(xPortInIsrContext()){
|
||||
xRingbufferSendFromISR(tx_ring_buf, (void*) (&c), 1, NULL);
|
||||
} else {
|
||||
xRingbufferSend(tx_ring_buf, (void*) (&c), 1, 0);
|
||||
}
|
||||
usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
|
||||
}
|
||||
|
||||
HWCDC::HWCDC() {
|
||||
|
||||
}
|
||||
|
||||
HWCDC::~HWCDC(){
|
||||
end();
|
||||
}
|
||||
|
||||
HWCDC::operator bool() const
|
||||
{
|
||||
return initial_empty;
|
||||
}
|
||||
|
||||
void HWCDC::begin(unsigned long baud)
|
||||
{
|
||||
setRxBufferSize(256);//default if not preset
|
||||
setTxBufferSize(256);//default if not preset
|
||||
|
||||
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY | USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT | USB_SERIAL_JTAG_INTR_BUS_RESET);
|
||||
usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY | USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT | USB_SERIAL_JTAG_INTR_BUS_RESET);
|
||||
if(!intr_handle && esp_intr_alloc(ETS_USB_INTR_SOURCE/*ETS_USB_SERIAL_JTAG_INTR_SOURCE*/, 0, hw_cdc_isr_handler, NULL, &intr_handle) != ESP_OK){
|
||||
isr_log_e("HW USB CDC failed to init interrupts");
|
||||
end();
|
||||
}
|
||||
}
|
||||
|
||||
void HWCDC::end()
|
||||
{
|
||||
//Disable tx/rx interrupt.
|
||||
usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY | USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT | USB_SERIAL_JTAG_INTR_BUS_RESET);
|
||||
esp_intr_free(intr_handle);
|
||||
intr_handle = NULL;
|
||||
setRxBufferSize(0);
|
||||
setTxBufferSize(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* WRITING
|
||||
*/
|
||||
|
||||
size_t HWCDC::setTxBufferSize(size_t tx_queue_len){
|
||||
if(tx_ring_buf){
|
||||
if(!tx_queue_len){
|
||||
vRingbufferDelete(tx_ring_buf);
|
||||
tx_ring_buf = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
tx_ring_buf = xRingbufferCreate(tx_queue_len, RINGBUF_TYPE_BYTEBUF);
|
||||
if(!tx_ring_buf){
|
||||
return 0;
|
||||
}
|
||||
return tx_queue_len;
|
||||
}
|
||||
|
||||
int HWCDC::availableForWrite(void)
|
||||
{
|
||||
if(tx_ring_buf == NULL){
|
||||
return -1;
|
||||
}
|
||||
return xRingbufferGetCurFreeSize(tx_ring_buf);
|
||||
}
|
||||
|
||||
size_t HWCDC::write(const uint8_t *buffer, size_t size)
|
||||
{
|
||||
// Blocking method, Sending data to ringbuffer, and handle the data in ISR.
|
||||
if(xRingbufferSend(tx_ring_buf, (void*) (buffer), size, 200 / portTICK_PERIOD_MS) != pdTRUE){
|
||||
log_e("Write Failed");
|
||||
return 0;
|
||||
}
|
||||
// Now trigger the ISR to read data from the ring buffer.
|
||||
usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
|
||||
return size;
|
||||
}
|
||||
|
||||
size_t HWCDC::write(uint8_t c)
|
||||
{
|
||||
return write(&c, 1);
|
||||
}
|
||||
|
||||
void HWCDC::flush(void)
|
||||
{
|
||||
if(tx_ring_buf == NULL){
|
||||
return;
|
||||
}
|
||||
UBaseType_t uxItemsWaiting = 0;
|
||||
vRingbufferGetInfo(tx_ring_buf, NULL, NULL, NULL, NULL, &uxItemsWaiting);
|
||||
while(uxItemsWaiting){
|
||||
delay(5);
|
||||
vRingbufferGetInfo(tx_ring_buf, NULL, NULL, NULL, NULL, &uxItemsWaiting);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* READING
|
||||
*/
|
||||
|
||||
size_t HWCDC::setRxBufferSize(size_t rx_queue_len){
|
||||
if(rx_queue){
|
||||
if(!rx_queue_len){
|
||||
vQueueDelete(rx_queue);
|
||||
rx_queue = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
rx_queue = xQueueCreate(rx_queue_len, sizeof(uint8_t));
|
||||
if(!rx_queue){
|
||||
return 0;
|
||||
}
|
||||
if(!tx_ring_buf){
|
||||
tx_ring_buf = xRingbufferCreate(rx_queue_len, RINGBUF_TYPE_BYTEBUF);
|
||||
}
|
||||
return rx_queue_len;
|
||||
}
|
||||
|
||||
int HWCDC::available(void)
|
||||
{
|
||||
if(rx_queue == NULL){
|
||||
return -1;
|
||||
}
|
||||
return uxQueueMessagesWaiting(rx_queue);
|
||||
}
|
||||
|
||||
int HWCDC::peek(void)
|
||||
{
|
||||
if(rx_queue == NULL){
|
||||
return -1;
|
||||
}
|
||||
uint8_t c;
|
||||
if(xQueuePeek(rx_queue, &c, 0)) {
|
||||
return c;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int HWCDC::read(void)
|
||||
{
|
||||
if(rx_queue == NULL){
|
||||
return -1;
|
||||
}
|
||||
uint8_t c = 0;
|
||||
if(xQueueReceive(rx_queue, &c, 0)) {
|
||||
return c;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t HWCDC::read(uint8_t *buffer, size_t size)
|
||||
{
|
||||
if(rx_queue == NULL){
|
||||
return -1;
|
||||
}
|
||||
uint8_t c = 0;
|
||||
size_t count = 0;
|
||||
while(count < size && xQueueReceive(rx_queue, &c, 0)){
|
||||
buffer[count++] = c;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* DEBUG
|
||||
*/
|
||||
|
||||
void HWCDC::setDebugOutput(bool en)
|
||||
{
|
||||
if(en) {
|
||||
uartSetDebug(NULL);
|
||||
ets_install_putc1((void (*)(char)) &cdc0_write_char);
|
||||
} else {
|
||||
ets_install_putc1(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#if ARDUINO_HW_CDC_ON_BOOT //Serial used for USB CDC
|
||||
HWCDC Serial;
|
||||
#else
|
||||
HWCDC USBSerial;
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_TINYUSB_CDC_ENABLED */
|
82
cores/esp32/HWCDC.h
Normal file
82
cores/esp32/HWCDC.h
Normal file
@ -0,0 +1,82 @@
|
||||
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#pragma once
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "Stream.h"
|
||||
|
||||
class HWCDC: public Stream
|
||||
{
|
||||
public:
|
||||
HWCDC();
|
||||
~HWCDC();
|
||||
|
||||
size_t setRxBufferSize(size_t);
|
||||
size_t setTxBufferSize(size_t);
|
||||
void begin(unsigned long baud=0);
|
||||
void end();
|
||||
|
||||
int available(void);
|
||||
int availableForWrite(void);
|
||||
int peek(void);
|
||||
int read(void);
|
||||
size_t read(uint8_t *buffer, size_t size);
|
||||
size_t write(uint8_t);
|
||||
size_t write(const uint8_t *buffer, size_t size);
|
||||
void flush(void);
|
||||
|
||||
inline size_t read(char * buffer, size_t size)
|
||||
{
|
||||
return read((uint8_t*) buffer, size);
|
||||
}
|
||||
inline size_t write(const char * buffer, size_t size)
|
||||
{
|
||||
return write((uint8_t*) buffer, size);
|
||||
}
|
||||
inline size_t write(const char * s)
|
||||
{
|
||||
return write((uint8_t*) s, strlen(s));
|
||||
}
|
||||
inline size_t write(unsigned long n)
|
||||
{
|
||||
return write((uint8_t) n);
|
||||
}
|
||||
inline size_t write(long n)
|
||||
{
|
||||
return write((uint8_t) n);
|
||||
}
|
||||
inline size_t write(unsigned int n)
|
||||
{
|
||||
return write((uint8_t) n);
|
||||
}
|
||||
inline size_t write(int n)
|
||||
{
|
||||
return write((uint8_t) n);
|
||||
}
|
||||
operator bool() const;
|
||||
void setDebugOutput(bool);
|
||||
uint32_t baudRate(){return 115200;}
|
||||
|
||||
};
|
||||
|
||||
#if ARDUINO_HW_CDC_ON_BOOT //Serial used for USB CDC
|
||||
extern HWCDC Serial;
|
||||
#else
|
||||
extern HWCDC USBSerial;
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_IDF_TARGET_ESP32C3 */
|
@ -76,6 +76,8 @@ void serialEvent2(void) {}
|
||||
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)
|
||||
#if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC
|
||||
HardwareSerial Serial0(0);
|
||||
#elif ARDUINO_HW_CDC_ON_BOOT
|
||||
HardwareSerial Serial0(0);
|
||||
#else
|
||||
HardwareSerial Serial(0);
|
||||
#endif
|
||||
@ -91,6 +93,8 @@ void serialEventRun(void)
|
||||
{
|
||||
#if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC
|
||||
if(Serial0.available()) serialEvent();
|
||||
#elif ARDUINO_HW_CDC_ON_BOOT
|
||||
if(Serial0.available()) serialEvent();
|
||||
#else
|
||||
if(Serial.available()) serialEvent();
|
||||
#endif
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include "Stream.h"
|
||||
#include "esp32-hal.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "HWCDC.h"
|
||||
|
||||
class HardwareSerial: public Stream
|
||||
{
|
||||
@ -121,6 +122,8 @@ extern void serialEventRun(void) __attribute__((weak));
|
||||
#include "USB.h"
|
||||
#include "USBCDC.h"
|
||||
extern HardwareSerial Serial0;
|
||||
#elif ARDUINO_HW_CDC_ON_BOOT
|
||||
extern HardwareSerial Serial0;
|
||||
#else
|
||||
extern HardwareSerial Serial;
|
||||
#endif
|
||||
|
@ -60,7 +60,7 @@ compiler.cpp.flags.esp32c3=-march=rv32imc -ffunction-sections -fdata-sections -W
|
||||
compiler.S.flags.esp32c3=-ffunction-sections -fdata-sections -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -ggdb -Wno-error=format= -nostartfiles -Wno-format -Og -fstrict-volatile-bitfields -Wno-error=unused-but-set-variable -fno-jump-tables -fno-tree-switch-conversion -x assembler-with-cpp -MMD -c
|
||||
compiler.c.elf.flags.esp32c3=-T memory.ld -T sections.ld -T esp32c3.rom.ld -T esp32c3.rom.api.ld -T esp32c3.rom.libgcc.ld -T esp32c3.rom.newlib.ld -T esp32c3.rom.version.ld -T esp32c3.peripherals.ld -nostartfiles -march=rv32imc --specs=nosys.specs -Wl,--cref -Wl,--gc-sections -fno-rtti -fno-lto -u _Z5setupv -u _Z4loopv -Wl,--wrap=mbedtls_mpi_exp_mod -u esp_app_desc -u pthread_include_pthread_impl -u pthread_include_pthread_cond_impl -u pthread_include_pthread_local_storage_impl -u start_app -u __ubsan_include -u __assert_func -u vfs_include_syscalls_impl -Wl,--undefined=uxTopUsedPriority -u app_main -u newlib_include_heap_impl -u newlib_include_syscalls_impl -u newlib_include_pthread_impl -Wl,--wrap=_Unwind_SetEnableExceptionFdeSorting -Wl,--wrap=__register_frame_info_bases -Wl,--wrap=__register_frame_info -Wl,--wrap=__register_frame -Wl,--wrap=__register_frame_info_table_bases -Wl,--wrap=__register_frame_info_table -Wl,--wrap=__register_frame_table -Wl,--wrap=__deregister_frame_info_bases -Wl,--wrap=__deregister_frame_info -Wl,--wrap=_Unwind_Find_FDE -Wl,--wrap=_Unwind_GetGR -Wl,--wrap=_Unwind_GetCFA -Wl,--wrap=_Unwind_GetIP -Wl,--wrap=_Unwind_GetIPInfo -Wl,--wrap=_Unwind_GetRegionStart -Wl,--wrap=_Unwind_GetDataRelBase -Wl,--wrap=_Unwind_GetTextRelBase -Wl,--wrap=_Unwind_SetIP -Wl,--wrap=_Unwind_SetGR -Wl,--wrap=_Unwind_GetLanguageSpecificData -Wl,--wrap=_Unwind_FindEnclosingFunction -Wl,--wrap=_Unwind_Resume -Wl,--wrap=_Unwind_RaiseException -Wl,--wrap=_Unwind_DeleteException -Wl,--wrap=_Unwind_ForcedUnwind -Wl,--wrap=_Unwind_Resume_or_Rethrow -Wl,--wrap=_Unwind_Backtrace -Wl,--wrap=__cxa_call_unexpected -Wl,--wrap=__gxx_personality_v0 -u __cxa_guard_dummy -u __cxx_fatal_exception
|
||||
compiler.ar.flags.esp32c3=cr
|
||||
build.extra_flags.esp32c3=-DARDUINO_USB_CDC_ON_BOOT=0
|
||||
build.extra_flags.esp32c3=-DARDUINO_HW_CDC_ON_BOOT={build.cdc_on_boot}
|
||||
#
|
||||
# ESP32C3 Support End
|
||||
#
|
||||
|
Loading…
Reference in New Issue
Block a user