Dual CDC implementation (#5)

* Move cli-related files to subfolder
* TinyUSB as our component
* Disable TinyUSB module in SDKConfig
* USB-CDC 0: GDB
* Cli: show MOTD on reboot
* Uart: simple driver
* Cli: use simple uart driver
* Simple UART driver documentation
* Software uart driver
* Forward esp logs to software uart at pin 7, baud 57600
* Delete network uart driver
* Disable booltoader and main esp log output
* Connect uart 0 and cdc port 1
* USB-UART: removed unused tx cache
* Simple UART driver: clear interrupts mask on start
* USB: better startup logging
* LOG: critical section on log print
This commit is contained in:
SG 2021-12-20 22:15:35 +10:00 committed by GitHub
parent 3f87d9c276
commit f7e4e686fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 1392 additions and 453 deletions

3
.gitmodules vendored
View File

@ -4,3 +4,6 @@
[submodule "components/mlib/mlib"]
path = components/mlib/mlib
url = https://github.com/P-p-H-d/mlib.git
[submodule "components/tinyusb/tinyusb"]
path = components/tinyusb/tinyusb
url = https://github.com/hathach/tinyusb

View File

@ -24,7 +24,7 @@ bool network_gdb_connected(void);
void network_gdb_send(uint8_t* buffer, size_t size);
/* USB-CDC */
void usb_cdc_tx_char(uint8_t c, bool flush);
void usb_cdc_gdb_tx_char(uint8_t c, bool flush);
size_t gdb_glue_get_free_size(void) {
return xStreamBufferSpacesAvailable(gdb_glue.rx_stream);
@ -94,6 +94,6 @@ void gdb_if_putchar(unsigned char c, int flush) {
}
} else {
// Not sure why, but I could not get it to work with buffer
usb_cdc_tx_char(c, flush);
usb_cdc_gdb_tx_char(c, flush);
}
}

View File

@ -0,0 +1,2 @@
idf_component_register(SRCS "simple-uart.c"
INCLUDE_DIRS ".")

View File

@ -0,0 +1,189 @@
#include <driver/gpio.h>
#include <driver/periph_ctrl.h>
#include <hal/uart_ll.h>
#include <hal/uart_hal.h>
#include <hal/gpio_hal.h>
#include <esp_rom_gpio.h>
#include "simple-uart.h"
/***********************************************/
typedef struct {
uart_hal_context_t hal; /*!< UART hal context*/
uint8_t uart_index;
void* isr_context;
uart_isr rx_isr;
} uart_context_t;
#define UART_CONTEX_INIT_DEF(uart_num) \
{ \
.hal.dev = UART_LL_GET_HW(uart_num), .uart_index = uart_num, .isr_context = NULL, \
.rx_isr = NULL \
}
static uart_context_t uart_context[UART_NUM_MAX] = {
UART_CONTEX_INIT_DEF(UART_NUM_0),
UART_CONTEX_INIT_DEF(UART_NUM_1),
#if UART_NUM_MAX > 2
UART_CONTEX_INIT_DEF(UART_NUM_2),
#endif
};
#define UART_HAL(uart_num) &(uart_context[uart_num].hal)
/***********************************************/
#define UART_FIFO_LIMIT (UART_LL_FIFO_DEF_LEN)
#define UART_TX_FIFO_THRESH 0x1
#define UART_RX_FIFO_THRESH 0x16
static void simple_uart_isr(void* arg);
static void simple_uart_init_pins(uint8_t uart_num, int tx_pin_num, int rx_pin_num) {
if(tx_pin_num >= 0) {
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[tx_pin_num], PIN_FUNC_GPIO);
gpio_set_level(tx_pin_num, 1);
esp_rom_gpio_connect_out_signal(
tx_pin_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_TX_PIN_IDX), 0, 0);
}
if(rx_pin_num >= 0) {
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[rx_pin_num], PIN_FUNC_GPIO);
gpio_set_pull_mode(rx_pin_num, GPIO_PULLUP_ONLY);
gpio_set_direction(rx_pin_num, GPIO_MODE_INPUT);
esp_rom_gpio_connect_in_signal(
rx_pin_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), 0);
}
}
static void simple_uart_init_module(uint8_t uart_num) {
periph_module_enable(uart_periph_signal[uart_num].module);
periph_module_reset(uart_periph_signal[uart_num].module);
}
void simple_uart_init(UartConfig* cfg) {
uart_context[cfg->uart_num].rx_isr = cfg->rx_isr;
uart_context[cfg->uart_num].isr_context = cfg->isr_context;
simple_uart_init_pins(cfg->uart_num, cfg->tx_pin_num, cfg->rx_pin_num);
simple_uart_init_module(cfg->uart_num);
uart_hal_set_sclk(UART_HAL(cfg->uart_num), UART_SCLK_APB);
uart_hal_set_rxfifo_full_thr(UART_HAL(cfg->uart_num), UART_RX_FIFO_THRESH);
uart_hal_set_txfifo_empty_thr(UART_HAL(cfg->uart_num), UART_TX_FIFO_THRESH);
uart_hal_rxfifo_rst(UART_HAL(cfg->uart_num));
uart_hal_set_hw_flow_ctrl(UART_HAL(cfg->uart_num), UART_HW_FLOWCTRL_DISABLE, 0);
uart_hal_set_rx_timeout(UART_HAL(cfg->uart_num), 0x16);
simple_uart_set_baud_rate(cfg->uart_num, cfg->baud_rate);
simple_uart_set_stop_bits(cfg->uart_num, cfg->stop_bits);
simple_uart_set_parity(cfg->uart_num, cfg->parity);
simple_uart_set_data_bits(cfg->uart_num, cfg->data_bits);
esp_intr_alloc(
uart_periph_signal[cfg->uart_num].irq,
0,
simple_uart_isr,
&uart_context[cfg->uart_num],
NULL);
// disable interrupts
uart_hal_clr_intsts_mask(UART_HAL(cfg->uart_num), UART_INTR_RXFIFO_FULL);
uart_hal_clr_intsts_mask(UART_HAL(cfg->uart_num), UART_INTR_TXFIFO_EMPTY);
uart_hal_clr_intsts_mask(UART_HAL(cfg->uart_num), UART_INTR_PARITY_ERR);
uart_hal_clr_intsts_mask(UART_HAL(cfg->uart_num), UART_INTR_FRAM_ERR);
uart_hal_clr_intsts_mask(UART_HAL(cfg->uart_num), UART_INTR_RXFIFO_OVF);
uart_hal_clr_intsts_mask(UART_HAL(cfg->uart_num), UART_INTR_DSR_CHG);
uart_hal_clr_intsts_mask(UART_HAL(cfg->uart_num), UART_INTR_CTS_CHG);
uart_hal_clr_intsts_mask(UART_HAL(cfg->uart_num), UART_INTR_BRK_DET);
uart_hal_clr_intsts_mask(UART_HAL(cfg->uart_num), UART_INTR_RXFIFO_TOUT);
uart_hal_clr_intsts_mask(UART_HAL(cfg->uart_num), UART_INTR_SW_XON);
uart_hal_clr_intsts_mask(UART_HAL(cfg->uart_num), UART_INTR_SW_XOFF);
uart_hal_clr_intsts_mask(UART_HAL(cfg->uart_num), UART_INTR_GLITCH_DET);
uart_hal_clr_intsts_mask(UART_HAL(cfg->uart_num), UART_INTR_TX_BRK_DONE);
uart_hal_clr_intsts_mask(UART_HAL(cfg->uart_num), UART_INTR_TX_BRK_IDLE);
uart_hal_clr_intsts_mask(UART_HAL(cfg->uart_num), UART_INTR_TX_DONE);
uart_hal_clr_intsts_mask(UART_HAL(cfg->uart_num), UART_INTR_RS485_PARITY_ERR);
uart_hal_clr_intsts_mask(UART_HAL(cfg->uart_num), UART_INTR_RS485_FRM_ERR);
uart_hal_clr_intsts_mask(UART_HAL(cfg->uart_num), UART_INTR_RS485_CLASH);
uart_hal_clr_intsts_mask(UART_HAL(cfg->uart_num), UART_INTR_CMD_CHAR_DET);
// enable rx interrupts
uart_hal_ena_intr_mask(UART_HAL(cfg->uart_num), UART_INTR_RXFIFO_FULL);
uart_hal_ena_intr_mask(UART_HAL(cfg->uart_num), UART_INTR_RXFIFO_TOUT);
}
void simple_uart_write(uint8_t uart_num, const uint8_t* data, const uint32_t data_size) {
uint32_t to_write = data_size;
while(to_write > 0) {
while(uart_hal_get_txfifo_len(UART_HAL(uart_num)) == 0) {
; /* Wait */
}
uint32_t write_size = 0;
uart_hal_write_txfifo(
UART_HAL(uart_num), data + (data_size - to_write), to_write, &write_size);
to_write -= write_size;
}
}
bool simple_uart_available(uint8_t uart_num) {
const int num_rx = uart_hal_get_rxfifo_len(UART_HAL(uart_num));
return num_rx > 0;
}
uint32_t simple_uart_read(uint8_t uart_num, uint8_t* data, const uint32_t data_size) {
const int num_rx = uart_hal_get_rxfifo_len(UART_HAL(uart_num));
int read = ((data_size) < (num_rx) ? (data_size) : (num_rx));
if(!read) {
return 0;
}
uart_hal_read_rxfifo(UART_HAL(uart_num), data, &read);
return read;
}
static void simple_uart_isr(void* arg) {
uart_context_t* context = arg;
uart_hal_context_t* hal_context = &context->hal;
uint8_t hal_num = context->uart_index;
uint32_t uart_intr_status = uart_hal_get_intsts_mask(hal_context);
if(uart_intr_status == 0) {
return;
}
uart_hal_clr_intsts_mask(hal_context, uart_intr_status);
if(uart_intr_status & UART_INTR_TXFIFO_EMPTY) {
}
if((uart_intr_status & UART_INTR_RXFIFO_TOUT) || (uart_intr_status & UART_INTR_RXFIFO_FULL)) {
if(context->rx_isr) {
context->rx_isr(context->isr_context);
} else {
// purge rx fifo
uint8_t data;
while(simple_uart_available(hal_num)) {
simple_uart_read(hal_num, &data, 1);
}
}
}
}
void simple_uart_set_baud_rate(uint8_t uart_num, uint32_t baud_rate) {
uart_hal_set_baudrate(UART_HAL(uart_num), baud_rate);
}
void simple_uart_set_stop_bits(uint8_t uart_num, uart_stop_bits_t stop_bits) {
uart_hal_set_stop_bits(UART_HAL(uart_num), stop_bits);
}
void simple_uart_set_parity(uint8_t uart_num, uart_parity_t parity) {
uart_hal_set_parity(UART_HAL(uart_num), parity);
}
void simple_uart_set_data_bits(uint8_t uart_num, uart_word_length_t data_bits) {
uart_hal_set_data_bit_num(UART_HAL(uart_num), data_bits);
}

View File

@ -0,0 +1,90 @@
/**
* @file uart.h
* @author Sergey Gavrilov (who.just.the.doctor@gmail.com)
* @version 1.0
* @date 2021-12-17
*
*
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <hal/uart_types.h>
#include <soc/soc_caps.h>
#define UART_NUM_0 (0) /*!< UART port 0 */
#define UART_NUM_1 (1) /*!< UART port 1 */
#define UART_NUM_MAX (SOC_UART_NUM)
typedef void (*uart_isr)(void* context);
typedef struct {
uint8_t uart_num; /*!< UART index */
uint32_t baud_rate; /*!< UART baud rate*/
uart_word_length_t data_bits; /*!< UART byte size*/
uart_parity_t parity; /*!< UART parity mode*/
uart_stop_bits_t stop_bits; /*!< UART stop bits*/
int tx_pin_num; /*!< UART tx pin*/
int rx_pin_num; /*!< UART rx pin*/
void* isr_context; /*!< UART isr context*/
uart_isr rx_isr; /*!< UART isr callback*/
} UartConfig;
/**
* Init UART driver
* @param config
*/
void simple_uart_init(UartConfig* config);
/**
* Write data to UART
* @param uart_num
* @param data
* @param data_size
*/
void simple_uart_write(uint8_t uart_num, const uint8_t* data, const uint32_t data_size);
/**
* Check if rx data available
* @param uart_num
* @return true
* @return false
*/
bool simple_uart_available(uint8_t uart_num);
/**
* Read rx data
* @param uart_num
* @param data
* @param data_size
* @return uint32_t
*/
uint32_t simple_uart_read(uint8_t uart_num, uint8_t* data, const uint32_t data_size);
/**
* Set UART baud rate
* @param uart_num
* @param baud_rate
*/
void simple_uart_set_baud_rate(uint8_t uart_num, uint32_t baud_rate);
/**
* Set UART stop bits
* @param uart_num
* @param stop_bits
*/
void simple_uart_set_stop_bits(uint8_t uart_num, uart_stop_bits_t stop_bits);
/**
* Set UART parity
* @param uart_num
* @param parity
*/
void simple_uart_set_parity(uint8_t uart_num, uart_parity_t parity);
/**
* Set UART data bits
* @param uart_num
* @param data_bits
*/
void simple_uart_set_data_bits(uint8_t uart_num, uart_word_length_t data_bits);

View File

@ -0,0 +1,2 @@
idf_component_register(SRCS "soft-uart.c"
INCLUDE_DIRS ".")

View File

@ -0,0 +1,69 @@
#include "soft-uart.h"
#include <string.h>
#include <freertos/portmacro.h>
#include <esp32/clk.h>
#include <driver/gpio.h>
struct SoftUart {
uint32_t baudrate;
uint32_t bit_time;
uint8_t tx_pin;
bool invert;
};
#define wait_cycles(cycles) \
for(uint32_t start = cycle_count_get(); cycle_count_get() - start < cycles;)
static uint32_t cycle_count_get() {
uint32_t ccount;
__asm__ __volatile__("esync; rsr %0,ccount" : "=a"(ccount));
return ccount;
}
void soft_uart_transmit_byte(SoftUart* uart, uint8_t byte) {
if(uart->invert) {
byte = ~byte;
}
// disable interrupts
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
portENTER_CRITICAL(&mux);
// create tx interrupts to start bit.
gpio_set_level(uart->tx_pin, 1), gpio_set_level(uart->tx_pin, 0);
wait_cycles(uart->bit_time);
for(uint8_t i = 0; i != 8; i++) {
gpio_set_level(uart->tx_pin, (byte & 1) ? 1 : 0);
wait_cycles(uart->bit_time);
byte >>= 1;
}
// Stop bit
gpio_set_level(uart->tx_pin, 1);
wait_cycles(uart->bit_time);
// re-enable interrupts
portEXIT_CRITICAL(&mux);
}
SoftUart* soft_uart_init(uint32_t baudrate, uint8_t tx_pin) {
SoftUart* uart = malloc(sizeof(SoftUart));
uart->baudrate = baudrate;
uart->tx_pin = tx_pin;
uart->invert = false;
uart->bit_time = (esp_clk_cpu_freq() / uart->baudrate);
gpio_pad_select_gpio(uart->tx_pin);
gpio_set_direction(uart->tx_pin, GPIO_MODE_OUTPUT);
gpio_set_level(uart->tx_pin, !uart->invert);
return uart;
}
void soft_uart_transmit(SoftUart* uart, const uint8_t* data, uint32_t data_size) {
for(size_t i = 0; i < data_size; i++) {
soft_uart_transmit_byte(uart, data[i]);
}
}

View File

@ -0,0 +1,16 @@
/**
* @file soft-uart.h
* @author Sergey Gavrilov (who.just.the.doctor@gmail.com)
* @version 1.0
* @date 2021-12-18
*
*
*/
#pragma once
#include <stdint.h>
typedef struct SoftUart SoftUart;
SoftUart* soft_uart_init(uint32_t baudrate, uint8_t tx_pin);
void soft_uart_transmit(SoftUart* uart, const uint8_t* data, uint32_t data_size);

View File

@ -0,0 +1,57 @@
idf_component_register(REQUIRES esp_rom app_update spi_flash freertos soc driver)
idf_component_get_property( FREERTOS_ORIG_INCLUDE_PATH freertos ORIG_INCLUDE_PATH)
idf_build_get_property(idf_target IDF_TARGET)
if(${idf_target} STREQUAL "esp32s2")
target_compile_options(${COMPONENT_TARGET} INTERFACE
"-DCFG_TUSB_MCU=OPT_MCU_ESP32S2"
)
endif()
if(${idf_target} STREQUAL "esp32s3")
target_compile_options(${COMPONENT_TARGET} INTERFACE
"-DCFG_TUSB_MCU=OPT_MCU_ESP32S3"
)
endif()
target_include_directories(${COMPONENT_TARGET} INTERFACE
"${FREERTOS_ORIG_INCLUDE_PATH}"
"${COMPONENT_DIR}/config/"
"${COMPONENT_DIR}/dual-cdc/"
"${COMPONENT_DIR}/tinyusb/hw/bsp/"
"${COMPONENT_DIR}/tinyusb/src/"
"${COMPONENT_DIR}/tinyusb/src/device"
"${COMPONENT_DIR}/tinyusb/src/class"
)
target_sources(${COMPONENT_TARGET} INTERFACE
"${COMPONENT_DIR}/tinyusb/src/tusb.c"
"${COMPONENT_DIR}/tinyusb/src/common/tusb_fifo.c"
"${COMPONENT_DIR}/tinyusb/src/device/usbd.c"
"${COMPONENT_DIR}/tinyusb/src/device/usbd_control.c"
"${COMPONENT_DIR}/tinyusb/src/class/audio/audio_device.c"
"${COMPONENT_DIR}/tinyusb/src/class/bth/bth_device.c"
"${COMPONENT_DIR}/tinyusb/src/class/cdc/cdc_device.c"
"${COMPONENT_DIR}/tinyusb/src/class/cdc/cdc_host.c"
"${COMPONENT_DIR}/tinyusb/src/class/cdc/cdc_rndis_host.c"
"${COMPONENT_DIR}/tinyusb/src/class/dfu/dfu_rt_device.c"
"${COMPONENT_DIR}/tinyusb/src/class/dfu/dfu_device.c"
"${COMPONENT_DIR}/tinyusb/src/class/hid/hid_device.c"
"${COMPONENT_DIR}/tinyusb/src/class/hid/hid_host.c"
"${COMPONENT_DIR}/tinyusb/src/class/midi/midi_device.c"
"${COMPONENT_DIR}/tinyusb/src/class/msc/msc_device.c"
"${COMPONENT_DIR}/tinyusb/src/class/msc/msc_host.c"
"${COMPONENT_DIR}/tinyusb/src/class/net/ncm_device.c"
"${COMPONENT_DIR}/tinyusb/src/class/net/ecm_rndis_device.c"
"${COMPONENT_DIR}/tinyusb/src/class/usbtmc/usbtmc_device.c"
"${COMPONENT_DIR}/tinyusb/src/class/vendor/vendor_device.c"
"${COMPONENT_DIR}/tinyusb/src/class/vendor/vendor_host.c"
"${COMPONENT_DIR}/tinyusb/src/class/video/video_device.c"
"${COMPONENT_DIR}/tinyusb/src/portable/espressif/esp32sx/dcd_esp32sx.c"
"${COMPONENT_DIR}/tinyusb/src/host/hub.c"
"${COMPONENT_DIR}/tinyusb/src/host/usbh.c"
"${COMPONENT_DIR}/tinyusb/src/host/usbh_control.c"
"${COMPONENT_DIR}/dual-cdc/dual-cdc-driver.c"
"${COMPONENT_DIR}/dual-cdc/usb_descriptors.c"
)

View File

@ -0,0 +1,168 @@
// Copyright 2020 Espressif Systems (Shanghai) Co. Ltd.
// Copyright 2020 Mike Dunston (https://github.com/atanisoft)
//
// 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"
#ifdef __cplusplus
extern "C" {
#endif
//--------------------------------------------------------------------
// COMMON CONFIGURATION
//--------------------------------------------------------------------
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE
#define CFG_TUSB_OS OPT_OS_FREERTOS
// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
#define CFG_TUSB_DEBUG CONFIG_ESPUSB_DEBUG
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
* TinyUSB use follows macros to declare transferring memory so that they can be put
* into those specific section.
* e.g
* - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") ))
* - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4)))
*/
#ifndef CFG_TUSB_MEM_SECTION
#define CFG_TUSB_MEM_SECTION
#endif
#ifndef CFG_TUSB_MEM_ALIGN
#define CFG_TUSB_MEM_ALIGN __attribute__((aligned(4)))
#endif
//--------------------------------------------------------------------
// ENDPOINT FIFO SIZE CONFIGURATION
//--------------------------------------------------------------------
#ifndef CFG_TUD_ENDPOINT0_SIZE
#define CFG_TUD_ENDPOINT0_SIZE 64
#endif
//--------------------------------------------------------------------
// KCONFIG DEFAULT CONFIGURATION
//--------------------------------------------------------------------
#ifndef CONFIG_ESPUSB_CDC
#define CONFIG_ESPUSB_CDC 0
#endif
#ifndef CONFIG_ESPUSB_MSC
#define CONFIG_ESPUSB_MSC 0
#endif
#ifndef CONFIG_ESPUSB_HID
#define CONFIG_ESPUSB_HID 0
#endif
#ifndef CONFIG_ESPUSB_MIDI
#define CONFIG_ESPUSB_MIDI 0
#endif
#ifndef CONFIG_ESPUSB_VENDOR
#define CONFIG_ESPUSB_VENDOR 0
#endif
#ifndef CONFIG_ESPUSB_DFU
#define CONFIG_ESPUSB_DFU 0
#endif
#ifndef CONFIG_ESPUSB_CUSTOM_CLASS
#define CONFIG_ESPUSB_CUSTOM_CLASS 0
#endif
#ifndef CONFIG_ESPUSB_CDC_RX_BUFSIZE
#define CONFIG_ESPUSB_CDC_RX_BUFSIZE 64
#endif
#ifndef CONFIG_ESPUSB_CDC_TX_BUFSIZE
#define CONFIG_ESPUSB_CDC_TX_BUFSIZE 64
#endif
#ifndef CONFIG_ESPUSB_MSC_BUFSIZE
#define CONFIG_ESPUSB_MSC_BUFSIZE 512
#endif
#ifndef CONFIG_ESPUSB_HID_BUFSIZE
#define CONFIG_ESPUSB_HID_BUFSIZE 16
#endif
#ifndef CONFIG_ESPUSB_VENDOR_RX_BUFSIZE
#define CONFIG_ESPUSB_VENDOR_RX_BUFSIZE 64
#endif
#ifndef CONFIG_ESPUSB_VENDOR_TX_BUFSIZE
#define CONFIG_ESPUSB_VENDOR_TX_BUFSIZE 64
#endif
#ifndef CONFIG_ESPUSB_MIDI_RX_BUFSIZE
#define CONFIG_ESPUSB_MIDI_RX_BUFSIZE 64
#endif
#ifndef CONFIG_ESPUSB_MIDI_TX_BUFSIZE
#define CONFIG_ESPUSB_MIDI_TX_BUFSIZE 64
#endif
#ifndef CONFIG_ESPUSB_DFU_BUFSIZE
#define CONFIG_ESPUSB_DFU_BUFSIZE 1024
#endif
//--------------------------------------------------------------------
// DEVICE CONFIGURATION
//--------------------------------------------------------------------
#define CFG_TUD_CDC 2
#define CFG_TUD_MSC CONFIG_ESPUSB_MSC
#define CFG_TUD_HID CONFIG_ESPUSB_HID
#define CFG_TUD_MIDI CONFIG_ESPUSB_MIDI
#define CFG_TUD_VENDOR CONFIG_ESPUSB_VENDOR
#define CFG_TUD_CUSTOM_CLASS CONFIG_ESPUSB_CUSTOM_CLASS
#define CFG_TUD_DFU_RT CONFIG_ESPUSB_DFU
//--------------------------------------------------------------------
// CDC FIFO CONFIGURATION
//--------------------------------------------------------------------
#define CFG_TUD_CDC_RX_BUFSIZE CONFIG_ESPUSB_CDC_RX_BUFSIZE
#define CFG_TUD_CDC_TX_BUFSIZE CONFIG_ESPUSB_CDC_TX_BUFSIZE
//--------------------------------------------------------------------
// MSC BUFFER CONFIGURATION
//
// NOTE: This is the block size for read/write operations via all
// defined callbacks.
//--------------------------------------------------------------------
#define CFG_TUD_MSC_BUFSIZE CONFIG_ESPUSB_MSC_BUFSIZE
//--------------------------------------------------------------------
// HID BUFFER CONFIGURATION
//
// NOTE: This should be sufficient to hold ID (if any) + Data
//--------------------------------------------------------------------
#define CFG_TUD_HID_BUFSIZE CONFIG_ESPUSB_HID_BUFSIZE
//--------------------------------------------------------------------
// VENDOR FIFO CONFIGURATION
//--------------------------------------------------------------------
#define CFG_TUD_VENDOR_RX_BUFSIZE CONFIG_ESPUSB_VENDOR_RX_BUFSIZE
#define CFG_TUD_VENDOR_TX_BUFSIZE CONFIG_ESPUSB_VENDOR_TX_BUFSIZE
//--------------------------------------------------------------------
// MIDI FIFO CONFIGURATION
//--------------------------------------------------------------------
#define CFG_TUD_MIDI_RX_BUFSIZE CONFIG_ESPUSB_MIDI_RX_BUFSIZE
#define CFG_TUD_MIDI_TX_BUFSIZE CONFIG_ESPUSB_MIDI_TX_BUFSIZE
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,76 @@
#include <tusb.h>
#include <class/cdc/cdc_device.h>
#include <driver/gpio.h>
#include <driver/periph_ctrl.h>
#include <hal/usb_hal.h>
#include <soc/gpio_periph.h>
#include <soc/usb_periph.h>
#include <esp_rom_gpio.h>
#include <hal/gpio_ll.h>
#include <esp_log.h>
#include <esp_check.h>
#include "dual-cdc-driver.h"
#define TAG "usb-dual-cdc"
#define CONFIG_TINYUSB_TASK_STACK_SIZE 4096
#define CONFIG_TINYUSB_TASK_PRIORITY 17
static void configure_pins(usb_hal_context_t* usb) {
/* usb_periph_iopins currently configures USB_OTG as USB Device.
* Introduce additional parameters in usb_hal_context_t when adding support
* for USB Host.
*/
for(const usb_iopin_dsc_t* iopin = usb_periph_iopins; iopin->pin != -1; ++iopin) {
if((usb->use_external_phy) || (iopin->ext_phy_only == 0)) {
esp_rom_gpio_pad_select_gpio(iopin->pin);
if(iopin->is_output) {
esp_rom_gpio_connect_out_signal(iopin->pin, iopin->func, false, false);
} else {
esp_rom_gpio_connect_in_signal(iopin->pin, iopin->func, false);
if((iopin->pin != GPIO_FUNC_IN_LOW) && (iopin->pin != GPIO_FUNC_IN_HIGH)) {
gpio_ll_input_enable(&GPIO, iopin->pin);
}
}
esp_rom_gpio_pad_unhold(iopin->pin);
}
}
if(!usb->use_external_phy) {
gpio_set_drive_capability(USBPHY_DM_NUM, GPIO_DRIVE_CAP_3);
gpio_set_drive_capability(USBPHY_DP_NUM, GPIO_DRIVE_CAP_3);
}
}
static void tusb_device_task(void* arg) {
ESP_LOGD(TAG, "tinyusb task started");
while(1) { // RTOS forever loop
tud_task();
}
}
esp_err_t dual_cdc_driver_install(void) {
// Enable APB CLK to USB peripheral
periph_module_enable(PERIPH_USB_MODULE);
periph_module_reset(PERIPH_USB_MODULE);
// Initialize HAL layer
usb_hal_context_t hal = {.use_external_phy = false};
usb_hal_init(&hal);
configure_pins(&hal);
ESP_RETURN_ON_FALSE(tusb_init(), ESP_FAIL, TAG, "init TinyUSB failed");
TaskHandle_t s_tusb_tskh;
xTaskCreate(
tusb_device_task,
"TinyUSB",
CONFIG_TINYUSB_TASK_STACK_SIZE,
NULL,
CONFIG_TINYUSB_TASK_PRIORITY,
&s_tusb_tskh);
ESP_RETURN_ON_FALSE(s_tusb_tskh, ESP_FAIL, TAG, "create TinyUSB main task failed");
ESP_LOGI(TAG, "TinyUSB Driver installed");
return ESP_OK;
}

View File

@ -0,0 +1,22 @@
/**
* @file dual-cdc-driver.h
* @author Sergey Gavrilov (who.just.the.doctor@gmail.com)
* @version 1.0
* @date 2021-12-16
*
* Dual CDC driver
*/
#pragma once
#include <stdint.h>
#include <esp_err.h>
#include <tusb_config.h>
#define CDC_IF_COUNT CFG_TUD_CDC
/**
*
* @return esp_err_t
*/
esp_err_t dual_cdc_driver_install(void);

View File

@ -0,0 +1,222 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
#include <tusb.h>
#include <class/cdc/cdc_device.h>
#include "tusb_config.h"
#include <esp_log.h>
//--------------------------------------------------------------------+
// Device Descriptors
//--------------------------------------------------------------------+
tusb_desc_device_t const blackmagic_desc_device = {
.bLength = sizeof(tusb_desc_device_t),
.bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = 0x0200,
// Use Interface Association Descriptor (IAD) for CDC
// As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1)
.bDeviceClass = TUSB_CLASS_MISC,
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
.bDeviceProtocol = MISC_PROTOCOL_IAD,
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
.idVendor = 0x303A, // USB_ESPRESSIF_VID,
.idProduct = 0x4001, // USB_TUSB_PID,
.bcdDevice = 0x0100,
.iManufacturer = 0x01,
.iProduct = 0x02,
.iSerialNumber = 0x03,
.bNumConfigurations = 0x01,
};
// Invoked when received GET DEVICE DESCRIPTOR
// Application return pointer to descriptor
uint8_t const* tud_descriptor_device_cb(void) {
return (uint8_t const*)&blackmagic_desc_device;
}
//--------------------------------------------------------------------+
// Configuration Descriptor
//--------------------------------------------------------------------+
enum { ITF_NUM_CDC_0 = 0, ITF_NUM_CDC_0_DATA, ITF_NUM_CDC_1, ITF_NUM_CDC_1_DATA, ITF_NUM_TOTAL };
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_CDC * TUD_CDC_DESC_LEN)
#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || \
CFG_TUSB_MCU == OPT_MCU_LPC40XX
// LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number
// 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ...
#define EPNUM_CDC_0_NOTIF 0x81
#define EPNUM_CDC_0_DATA 0x02
#define EPNUM_CDC_1_NOTIF 0x84
#define EPNUM_CDC_1_DATA 0x05
#else
#define EPNUM_CDC_0_NOTIF 0x81
#define EPNUM_CDC_0_DATA 0x02
#define EPNUM_CDC_1_NOTIF 0x83
#define EPNUM_CDC_1_DATA 0x04
#endif
uint8_t const blackmagic_desc_fs_configuration[] = {
// Config number, interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(
1,
ITF_NUM_TOTAL,
0,
CONFIG_TOTAL_LEN,
TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP,
100),
// 1st CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
TUD_CDC_DESCRIPTOR(
ITF_NUM_CDC_0,
4,
EPNUM_CDC_0_NOTIF,
8,
EPNUM_CDC_0_DATA,
0x80 | EPNUM_CDC_0_DATA,
64),
// 2nd CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
TUD_CDC_DESCRIPTOR(
ITF_NUM_CDC_1,
4,
EPNUM_CDC_1_NOTIF,
8,
EPNUM_CDC_1_DATA,
0x80 | EPNUM_CDC_1_DATA,
64),
};
#if TUD_OPT_HIGH_SPEED
uint8_t const blackmagic_desc_hs_configuration[] = {
// Config number, interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(
1,
ITF_NUM_TOTAL,
0,
CONFIG_TOTAL_LEN,
TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP,
100),
// 1st CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
TUD_CDC_DESCRIPTOR(
ITF_NUM_CDC_0,
4,
EPNUM_CDC_0_NOTIF,
8,
EPNUM_CDC_0_DATA,
0x80 | EPNUM_CDC_0_DATA,
512),
// 2nd CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
TUD_CDC_DESCRIPTOR(
ITF_NUM_CDC_1,
4,
EPNUM_CDC_1_NOTIF,
8,
EPNUM_CDC_1_DATA,
0x80 | EPNUM_CDC_1_DATA,
512),
};
#endif
// Invoked when received GET CONFIGURATION DESCRIPTOR
// Application return pointer to descriptor
// Descriptor contents must exist long enough for transfer to complete
uint8_t const* tud_descriptor_configuration_cb(uint8_t index) {
(void)index; // for multiple configurations
#if TUD_OPT_HIGH_SPEED
// Although we are highspeed, host may be fullspeed.
return (tud_speed_get() == TUSB_SPEED_HIGH) ? blackmagic_desc_hs_configuration :
blackmagic_desc_fs_configuration;
#else
return blackmagic_desc_fs_configuration;
#endif
}
//--------------------------------------------------------------------+
// String Descriptors
//--------------------------------------------------------------------+
// array of pointer to string descriptors
char const* blackmagic_string_desc[] = {
(const char[]){0x09, 0x04}, // 0: is supported language is English (0x0409)
"Flipper Devices Inc.", // 1: Manufacturer
"Blackmagic ESP32", // 2: Product
"blackmagic", // 3: Serials, should use chip ID
"Blackmagic ESP32", // 4: CDC Interface
"", // 5: MSC Interface
"", // 6: HIDs
};
#define MAX_DESC_BUF_SIZE 32
static uint16_t _desc_str[MAX_DESC_BUF_SIZE];
// Invoked when received GET STRING DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
(void)langid;
uint8_t chr_count;
if(index == 0) {
memcpy(&_desc_str[1], blackmagic_string_desc[0], 2);
chr_count = 1;
} else {
// Convert ASCII string into UTF-16
if(index >= sizeof(blackmagic_string_desc) / sizeof(blackmagic_string_desc[0])) {
// ESP_LOGI("usb-str", "answer NULL");
return NULL;
}
const char* str = blackmagic_string_desc[index];
// Cap at max char
chr_count = strlen(str);
if(chr_count > MAX_DESC_BUF_SIZE - 1) {
chr_count = MAX_DESC_BUF_SIZE - 1;
}
for(uint8_t i = 0; i < chr_count; i++) {
_desc_str[1 + i] = str[i];
}
}
// first byte is length (including header), second byte is string type
_desc_str[0] = (TUSB_DESC_STRING << 8) | (2 * chr_count + 2);
// ESP_LOG_BUFFER_HEXDUMP("usb-str", _desc_str, (2 * chr_count + 2), ESP_LOG_INFO);
return _desc_str;
}

@ -0,0 +1 @@
Subproject commit dd30f2c648b984949b858d7dcc914297985a20bb

View File

@ -1,6 +1,7 @@
set(SOURCES
"main.c"
"usb-cdc.c"
"usb-uart.c"
"nvs.c"
"nvs-config.c"
"led.c"
@ -9,16 +10,16 @@ set(SOURCES
"delay.c"
"network.c"
"network-http.c"
"network-uart.c"
"network-gdb.c"
"cli.c"
"cli-uart.c"
"cli-commands.c"
"cli-commands-gpio.c"
"cli-commands-wifi.c"
"cli-commands-config.c"
"cli-commands-device-info.c"
"cli-args.c"
"cli/cli.c"
"cli/cli-commands.c"
"cli/cli-commands-gpio.c"
"cli/cli-commands-wifi.c"
"cli/cli-commands-config.c"
"cli/cli-commands-device-info.c"
"cli/cli-args.c"
"soft-uart-log.c"
)
set(INCLUDES
@ -74,4 +75,4 @@ message(STATUS "FW branch: ${FW_GIT_BRANCH}")
message(STATUS "FW branch num: ${FW_GIT_BRANCH_NUM}")
message(STATUS "FW version: ${FW_GIT_VERSION}")
set_property(SOURCE "cli-commands-device-info.c" APPEND PROPERTY COMPILE_OPTIONS ${INFO_FLAGS})
set_property(SOURCE "cli/cli-commands-device-info.c" APPEND PROPERTY COMPILE_OPTIONS ${INFO_FLAGS})

View File

@ -1,52 +1,41 @@
#include <driver/uart.h>
#include <driver/gpio.h>
// #include <driver/uart.h>
// #include <driver/gpio.h>
#include <string.h>
#include "cli.h"
#include "led.h"
#include "cli/cli.h"
#include <simple-uart.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/stream_buffer.h>
#define CLI_UART_PORT_NUM UART_NUM_1
#define CLI_UART_TXD_PIN (17)
#define CLI_UART_RXD_PIN (18)
#define CLI_UART_RTS_PIN (UART_PIN_NO_CHANGE)
#define CLI_UART_CTS_PIN (UART_PIN_NO_CHANGE)
#define CLI_UART_BAUD_RATE (115200)
#define CLI_UART_BUF_SIZE (128)
#define CLI_UART_TX_BUF_SIZE (64)
#define CLI_UART_RX_BUF_SIZE (64)
static Cli* cli_uart;
static QueueHandle_t cli_uart_queue;
static uint8_t cli_rx_buffer[CLI_UART_RX_BUF_SIZE];
static size_t cli_rx_index = 0;
static uint8_t uart_tx_buffer[CLI_UART_TX_BUF_SIZE];
static size_t uart_tx_index = 0;
static StreamBufferHandle_t uart_rx_stream;
static void cli_uart_write(const uint8_t* data, size_t data_size, void* context);
static void cli_uart_flush(void* context);
static void cli_uart_rx_isr(void* context);
static void cli_uart_rx_task(void* pvParameters) {
uart_event_t event;
uint8_t* rx_buffer = (uint8_t*)malloc(CLI_UART_BUF_SIZE);
int received = 0;
for(;;) {
//Waiting for UART event.
if(xQueueReceive(cli_uart_queue, (void*)&event, (portTickType)portMAX_DELAY)) {
bzero(rx_buffer, CLI_UART_BUF_SIZE);
switch(event.type) {
case UART_DATA:
received =
uart_read_bytes(CLI_UART_PORT_NUM, rx_buffer, event.size, portMAX_DELAY);
for(int i = 0; i < received; i++) {
cli_handle_char(cli_uart, rx_buffer[i]);
}
break;
default:
break;
while(1) {
uint8_t data[CLI_UART_RX_BUF_SIZE];
size_t length =
xStreamBufferReceive(uart_rx_stream, data, CLI_UART_RX_BUF_SIZE, portMAX_DELAY);
if(length > 0) {
for(size_t i = 0; i < length; i++) {
cli_handle_char(cli_uart, data[i]);
}
}
}
free(rx_buffer);
rx_buffer = NULL;
vTaskDelete(NULL);
}
void cli_uart_init() {
@ -54,49 +43,59 @@ void cli_uart_init() {
cli_set_write_cb(cli_uart, cli_uart_write);
cli_set_flush_cb(cli_uart, cli_uart_flush);
uart_config_t uart_config = {
uart_rx_stream = xStreamBufferCreate(CLI_UART_RX_BUF_SIZE * 4, 1);
xTaskCreate(cli_uart_rx_task, "cli_uart_rx", 4096, NULL, 5, NULL);
UartConfig config = {
.uart_num = CLI_UART_PORT_NUM,
.baud_rate = CLI_UART_BAUD_RATE,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_APB,
.tx_pin_num = CLI_UART_TXD_PIN,
.rx_pin_num = CLI_UART_RXD_PIN,
.isr_context = uart_rx_stream,
.rx_isr = cli_uart_rx_isr,
};
int intr_alloc_flags = 0;
#if CONFIG_UART_ISR_IN_IRAM
intr_alloc_flags = ESP_INTR_FLAG_IRAM;
#endif
simple_uart_init(&config);
ESP_ERROR_CHECK(uart_driver_install(
CLI_UART_PORT_NUM,
CLI_UART_BUF_SIZE * 4,
0,
10,
&cli_uart_queue,
intr_alloc_flags));
ESP_ERROR_CHECK(uart_param_config(CLI_UART_PORT_NUM, &uart_config));
ESP_ERROR_CHECK(uart_set_pin(
CLI_UART_PORT_NUM, CLI_UART_TXD_PIN, CLI_UART_RXD_PIN, CLI_UART_RTS_PIN, CLI_UART_CTS_PIN));
xTaskCreate(cli_uart_rx_task, "cli_uart_rx", 4096, NULL, 5, NULL);
cli_force_motd(cli_uart);
}
static void cli_uart_write(const uint8_t* data, size_t data_size, void* context) {
for(size_t i = 0; i < data_size; i++) {
cli_rx_buffer[cli_rx_index] = data[i];
cli_rx_index++;
uart_tx_buffer[uart_tx_index] = data[i];
uart_tx_index++;
if(cli_rx_index == CLI_UART_RX_BUF_SIZE) {
if(uart_tx_index == CLI_UART_TX_BUF_SIZE) {
cli_uart_flush(NULL);
}
}
}
static void cli_uart_flush(void* context) {
if(cli_rx_index > 0) {
uart_write_bytes(CLI_UART_PORT_NUM, cli_rx_buffer, cli_rx_index);
if(uart_tx_index > 0) {
simple_uart_write(CLI_UART_PORT_NUM, uart_tx_buffer, uart_tx_index);
}
cli_rx_index = 0;
uart_tx_index = 0;
}
static void cli_uart_rx_isr(void* context) {
StreamBufferHandle_t stream = context;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
uint8_t data;
while(simple_uart_available(CLI_UART_PORT_NUM)) {
simple_uart_read(CLI_UART_PORT_NUM, &data, 1);
size_t ret __attribute__((unused));
ret = xStreamBufferSendFromISR(stream, &data, 1, &xHigherPriorityTaskWoken);
// we will drop data if the stream overflows
// ESP_ERROR_CHECK(ret != 1);
}
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

View File

@ -96,13 +96,44 @@ void cli_printf(Cli* cli, char* format, ...) {
}
static void cli_write_motd(Cli* cli) {
cli_write_str(cli, "Hello!\r\nThis is MOTD\r\n");
cli_write_str(cli, " \r\n");
cli_write_str(cli, " ____ BLACK \r\n");
cli_write_str(cli, " / /\\ MAGIC \r\n");
cli_write_str(cli, " / /\\ \\ \r\n");
cli_write_str(cli, " ( / \\ \\ ' \r\n");
cli_write_str(cli, " _/ (___/ /_ . ' \r\n");
cli_write_str(cli, " ( _____._.__ ) ,'o \r\n");
cli_write_str(cli, " // / 'o' | O . \r\n");
cli_write_str(cli, " // / ' ' |\\ ,,, \r\n");
cli_write_str(cli, " // /\\ ' '| \\_/''/ \r\n");
cli_write_str(cli, " // / )______/\\ \\_/ \r\n");
cli_write_str(cli, "// \\ ( ) `---' \r\n");
cli_write_str(cli, "\\\\___/ | \\ \r\n");
cli_write_str(cli, " \\( \\ | \\ \r\n");
cli_write_str(cli, " / \\_@ | ) \r\n");
cli_write_str(cli, " \\ , | \\ \r\n");
cli_write_str(cli, " / / / | / \r\n");
cli_write_str(cli, " \\ \\ : /\\ / \r\n");
cli_write_str(cli, " \\ \\ \\ : / |\\) \r\n");
cli_write_str(cli, " \\ / |\\/| | \r\n");
cli_write_str(cli, " / / | |- \r\n");
cli_write_str(cli, " \\ /|__| \r\n");
cli_write_str(cli, " \\ / |''| \r\n");
cli_write_str(cli, " \\ \\ -- \r\n");
cli_write_str(cli, " \\/ \r\n");
}
static void cli_write_prompt(Cli* cli) {
cli_write_str(cli, ">: ");
}
void cli_force_motd(Cli* cli) {
cli_write_motd(cli);
cli_write_eol(cli);
cli_write_prompt(cli);
cli_flush(cli);
}
static const CliItem* cli_search_item(Cli* cli, const mstring_t* command) {
const CliItem* item = NULL;
@ -199,9 +230,7 @@ void cli_handle_char(Cli* cli, uint8_t c) {
break;
case CliSymbolAsciiSOH:
delay(33);
cli_write_motd(cli);
cli_write_eol(cli);
cli_write_prompt(cli);
cli_force_motd(cli);
break;
case CliSymbolAsciiETX:
cli_reset(cli);

View File

@ -37,4 +37,6 @@ void cli_handle_char(Cli* cli, uint8_t c);
void cli_write_eol(Cli* cli);
void cli_printf(Cli* cli, char* format, ...);
void cli_printf(Cli* cli, char* format, ...);
void cli_force_motd(Cli* cli);

26
main/cli/cli.motd.art Normal file
View File

@ -0,0 +1,26 @@
____ BLACK
/ /\ MAGIC
/ /\ \
( / \ \ '
_/ (___/ /_ . '
( _____._.__ ) ,'o
// / '"' | O .
// / ' ' |\ ,,,
// /\ ' '| \_/''/
// / )______/\ \_/
// \ ( ) `---'
\\___/ | \
\( \ | \
/ \_@ | )
\ , | \
/ / / | /
\ \ : /\ /
\ \ \ : / |\)
\ / |\/| |
/ / | |-
\ /|__|
\ / |''|
\ \ --
\/

View File

@ -16,6 +16,7 @@
#include "network-gdb.h"
#include <gdb-glue.h>
#include <soft-uart-log.h>
static const char* TAG = "main";
@ -46,10 +47,10 @@ void pins_init() {
gpio_config(&io_conf);
}
void tcp_uart_init(void);
void tcp_web_log(void);
void app_main(void) {
// Software UART logging at pin 7, 57600 baud
soft_uart_log_init(7, 57600);
ESP_LOGI(TAG, "start");
gdb_glue_init();
@ -60,11 +61,10 @@ void app_main(void) {
nvs_init();
network_init();
network_http_server_init();
network_uart_server_init();
// network_uart_server_init();
network_gdb_server_init();
usb_cdc_init();
cli_uart_init();
// TODO uart and i2c share the same pins, need switching mechanics

View File

@ -1,198 +0,0 @@
#include <string.h>
#include <sys/param.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <esp_system.h>
#include <esp_wifi.h>
#include <esp_event.h>
#include <esp_log.h>
#include <nvs_flash.h>
#include <esp_netif.h>
#include <lwip/err.h>
#include <lwip/sockets.h>
#include <lwip/sys.h>
#include <lwip/netdb.h>
#include "led.h"
#include "delay.h"
#include <driver/uart.h>
#include <soc/uart_reg.h>
#define PORT 4444
#define KEEPALIVE_IDLE 5
#define KEEPALIVE_INTERVAL 5
#define KEEPALIVE_COUNT 3
#define BUF_SIZE (128)
#define RD_BUF_SIZE (128)
#define TAG "network-uart"
static int socket_id;
static bool connected;
static QueueHandle_t uart0_queue;
static void receive_and_send_to_uart(const int socket_id) {
int received;
char rx_buffer[BUF_SIZE];
do {
received = recv(socket_id, rx_buffer, sizeof(rx_buffer) - 1, 0);
led_set_green(255);
if(received > 0) {
uart_write_bytes(UART_NUM_0, rx_buffer, received);
}
led_set_green(0);
} while(received > 0);
}
static void network_uart_rx_task(void* pvParameters) {
uart_event_t event;
uint8_t* rx_buffer = (uint8_t*)malloc(BUF_SIZE);
int received = 0;
for(;;) {
//Waiting for UART event.
if(xQueueReceive(uart0_queue, (void*)&event, (portTickType)portMAX_DELAY)) {
bzero(rx_buffer, BUF_SIZE);
switch(event.type) {
case UART_DATA:
received = uart_read_bytes(UART_NUM_0, rx_buffer, event.size, portMAX_DELAY);
if(connected) {
int to_write = received;
while(to_write > 0) {
led_set_green(255);
int written =
send(socket_id, rx_buffer + (received - to_write), to_write, 0);
led_set_green(0);
to_write -= written;
}
}
break;
default:
break;
}
}
}
free(rx_buffer);
rx_buffer = NULL;
vTaskDelete(NULL);
}
static void network_uart_server_task(void* pvParameters) {
char addr_str[128];
int addr_family = (int)pvParameters;
int ip_protocol = 0;
int keepAlive = 1;
int keepIdle = KEEPALIVE_IDLE;
int keepInterval = KEEPALIVE_INTERVAL;
int keepCount = KEEPALIVE_COUNT;
connected = false;
struct sockaddr_storage dest_addr;
if(addr_family == AF_INET) {
struct sockaddr_in* dest_addr_ip4 = (struct sockaddr_in*)&dest_addr;
dest_addr_ip4->sin_addr.s_addr = htonl(INADDR_ANY);
dest_addr_ip4->sin_family = AF_INET;
dest_addr_ip4->sin_port = htons(PORT);
ip_protocol = IPPROTO_IP;
}
int listen_sock = socket(addr_family, SOCK_STREAM, ip_protocol);
if(listen_sock < 0) {
ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);
vTaskDelete(NULL);
return;
}
int opt = 1;
setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
ESP_LOGI(TAG, "Socket created");
int err = bind(listen_sock, (struct sockaddr*)&dest_addr, sizeof(dest_addr));
if(err != 0) {
ESP_LOGE(TAG, "Socket unable to bind: errno %d", errno);
ESP_LOGE(TAG, "IPPROTO: %d", addr_family);
goto CLEAN_UP;
}
ESP_LOGI(TAG, "Socket bound, port %d", PORT);
err = listen(listen_sock, 1);
if(err != 0) {
ESP_LOGE(TAG, "Error occurred during listen: errno %d", errno);
goto CLEAN_UP;
}
while(1) {
ESP_LOGI(TAG, "Socket listening");
struct sockaddr_storage source_addr; // Large enough for both IPv4 or IPv6
socklen_t addr_len = sizeof(source_addr);
int sock = accept(listen_sock, (struct sockaddr*)&source_addr, &addr_len);
if(sock < 0) {
ESP_LOGE(TAG, "Unable to accept connection: errno %d", errno);
break;
}
// Set tcp keepalive option
setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &keepAlive, sizeof(int));
setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, &keepIdle, sizeof(int));
setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, &keepInterval, sizeof(int));
setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT, &keepCount, sizeof(int));
// Convert ip address to string
if(source_addr.ss_family == PF_INET) {
inet_ntoa_r(
((struct sockaddr_in*)&source_addr)->sin_addr, addr_str, sizeof(addr_str) - 1);
}
ESP_LOGI(TAG, "Socket accepted ip address: %s", addr_str);
esp_log_level_set("*", ESP_LOG_NONE);
led_set_green(255);
delay(10);
led_set_green(0);
socket_id = sock;
connected = true;
receive_and_send_to_uart(sock);
connected = false;
socket_id = -1;
led_set_green(255);
delay(10);
led_set_green(0);
esp_log_level_set("*", CONFIG_LOG_DEFAULT_LEVEL);
shutdown(sock, 0);
close(sock);
}
CLEAN_UP:
close(listen_sock);
vTaskDelete(NULL);
}
void network_uart_server_init(void) {
xTaskCreate(network_uart_server_task, "network_uart_server", 4096, (void*)AF_INET, 5, NULL);
uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_APB,
};
uart_driver_install(UART_NUM_0, BUF_SIZE * 2, BUF_SIZE * 2, 20, &uart0_queue, 0);
uart_param_config(UART_NUM_0, &uart_config);
xTaskCreate(network_uart_rx_task, "tcp_uart_rx", 4096, (void*)AF_INET, 5, NULL);
}

27
main/soft-uart-log.c Normal file
View File

@ -0,0 +1,27 @@
#include <esp_log.h>
#include <soft-uart.h>
#include <freertos/FreeRTOS.h>
#include <stdio.h>
#include <string.h>
#define LOG_BUFFER_SIZE (128)
static SoftUart* log_uart = NULL;
static char log_buffer[LOG_BUFFER_SIZE];
static int soft_uart_log_vprintf(const char* str, va_list l) {
portMUX_TYPE myMutex = portMUX_INITIALIZER_UNLOCKED;
portENTER_CRITICAL(&myMutex);
int len = vsnprintf(log_buffer, LOG_BUFFER_SIZE, str, l);
soft_uart_transmit(log_uart, (uint8_t*)log_buffer, strlen(log_buffer));
portEXIT_CRITICAL(&myMutex);
return len;
}
void soft_uart_log_init(uint8_t pin, uint32_t baudrate) {
log_uart = soft_uart_init(baudrate, pin);
esp_log_set_vprintf(soft_uart_log_vprintf);
}

12
main/soft-uart-log.h Normal file
View File

@ -0,0 +1,12 @@
/**
* @file soft-uart-log.h
* @author Sergey Gavrilov (who.just.the.doctor@gmail.com)
* @version 1.0
* @date 2021-12-18
*
*
*/
#pragma once
#include <stdint.h>
void soft_uart_log_init(uint8_t pin, uint32_t baudrate);

View File

@ -11,141 +11,150 @@
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/stream_buffer.h>
#include <tinyusb.h>
#include <tusb_cdc_acm.h>
#include <sdkconfig.h>
#include <driver/gpio.h>
#include "usb-cdc.h"
#include "usb-uart.h"
#include "led.h"
#include "delay.h"
#include <gdb-glue.h>
#include <dual-cdc-driver.h>
#include <class/cdc/cdc_device.h>
#define USB_DN_PIN (19)
#define USB_DP_PIN (20)
#define CDC_USB_DEV (TINYUSB_USBDEV_0)
#define GDB_BUF_RX_SIZE 64
#define UART_BUF_RX_SIZE 64
static const char* TAG = "usb-cdc";
static uint8_t buffer_rx[CONFIG_USB_CDC_RX_BUFSIZE];
static uint8_t gdb_buffer_rx[GDB_BUF_RX_SIZE];
static uint8_t uart_buffer_rx[UART_BUF_RX_SIZE];
typedef struct {
volatile bool connected;
volatile bool dtr;
volatile bool rts;
} USBCDC;
static USBCDC usb_cdc;
void usb_cdc_tx_char(uint8_t c, bool flush) {
tinyusb_cdcacm_write_queue(CDC_USB_DEV, &c, 1);
typedef enum {
CDCTypeGDB = 0,
CDCTypeUART = 1,
} CDCType;
static void usb_cdc_tx_char(CDCType type, uint8_t c, bool flush) {
tud_cdc_n_write(type, &c, 1);
if(flush) {
// SOME GDB MAGIC
// We need to send an empty packet for some hosts to accept this as a complete transfer.
uint8_t zero_byte = 0;
tinyusb_cdcacm_write_queue(CDC_USB_DEV, &zero_byte, 1);
// TODO: timeout size
ESP_ERROR_CHECK_WITHOUT_ABORT(tinyusb_cdcacm_write_flush(CDC_USB_DEV, 1000));
tud_cdc_n_write_flush(type);
}
}
void usb_cdc_rx_callback(int itf, cdcacm_event_t* event) {
void usb_cdc_gdb_tx_char(uint8_t c, bool flush) {
usb_cdc_tx_char(CDCTypeGDB, c, flush);
}
void usb_cdc_uart_tx_char(uint8_t c, bool flush) {
usb_cdc_tx_char(CDCTypeUART, c, flush);
}
void usb_cdc_gdb_rx_callback(void) {
if(gdb_glue_can_receive()) {
size_t max_len = gdb_glue_get_free_size();
if(max_len > CONFIG_USB_CDC_RX_BUFSIZE) max_len = CONFIG_USB_CDC_RX_BUFSIZE;
size_t rx_size = 0;
esp_err_t err = tinyusb_cdcacm_read(itf, buffer_rx, max_len, &rx_size);
if(max_len > GDB_BUF_RX_SIZE) max_len = GDB_BUF_RX_SIZE;
uint32_t rx_size = tud_cdc_n_read(CDCTypeGDB, gdb_buffer_rx, max_len);
if(err == ESP_OK) {
if(rx_size > 0) {
gdb_glue_receive(buffer_rx, rx_size);
}
} else {
ESP_LOGE(TAG, "Read error");
if(rx_size > 0) {
gdb_glue_receive(gdb_buffer_rx, rx_size);
}
} else {
esp_system_abort("No free space in GDB buffer");
}
}
void usb_cdc_line_state_changed_callback(int itf, cdcacm_event_t* event) {
usb_cdc.dtr = event->line_state_changed_data.dtr;
usb_cdc.rts = event->line_state_changed_data.rts;
void usb_cdc_uart_rx_callback(void) {
size_t max_len = gdb_glue_get_free_size();
if(max_len > UART_BUF_RX_SIZE) max_len = UART_BUF_RX_SIZE;
uint32_t rx_size = tud_cdc_n_read(CDCTypeUART, uart_buffer_rx, max_len);
ESP_LOGI(TAG, "Line state changed! dtr:%d, rst:%d", usb_cdc.dtr, usb_cdc.rts);
if(rx_size > 0) {
usb_uart_write(uart_buffer_rx, rx_size);
}
}
void usb_cdc_line_coding_changed_callback(int itf, cdcacm_event_t* event) {
uint32_t bit_rate = event->line_coding_changed_data.p_line_coding->bit_rate;
uint8_t stop_bits = event->line_coding_changed_data.p_line_coding->stop_bits;
uint8_t parity = event->line_coding_changed_data.p_line_coding->parity;
uint8_t data_bits = event->line_coding_changed_data.p_line_coding->data_bits;
void tud_cdc_rx_cb(uint8_t interface) {
do {
if(interface == CDCTypeGDB) {
usb_cdc_gdb_rx_callback();
} else if(interface == CDCTypeUART) {
usb_cdc_uart_rx_callback();
} else {
tud_cdc_n_read_flush(interface);
}
} while(false);
}
ESP_LOGI(
TAG,
"Line coding changed! bit_rate:%d, stop_bits:%d, parity:%d, data_bits:%d",
bit_rate,
stop_bits,
parity,
data_bits);
void tud_cdc_line_state_cb(uint8_t interface, bool dtr, bool rts) {
if(interface == CDCTypeUART) {
usb_uart_set_line_state(dtr, rts);
}
}
void tud_cdc_line_coding_cb(uint8_t interface, cdc_line_coding_t const* p_line_coding) {
uint32_t bit_rate = p_line_coding->bit_rate;
uint8_t stop_bits = p_line_coding->stop_bits;
uint8_t parity = p_line_coding->parity;
uint8_t data_bits = p_line_coding->data_bits;
if(interface == CDCTypeUART) {
usb_uart_set_line_coding(bit_rate, stop_bits, parity, data_bits);
}
}
//--------------------------------------------------------------------+
// Device callbacks
//--------------------------------------------------------------------+
// It seems like a reliable way is to rely on tud_mount_cb on connect and tud_suspend_cb on disconnect
void tud_mount_cb(void) {
ESP_LOGI(TAG, "Mount");
static void usb_cdc_event_blink(void) {
led_set_blue(255);
delay(10);
led_set_blue(0);
}
static void usb_cdc_to_connected(void) {
if(!usb_cdc.connected) {
led_set_blue(255);
delay(10);
led_set_blue(0);
usb_cdc_event_blink();
}
usb_cdc.connected = true;
ESP_LOGI(TAG, "connect");
}
static void usb_cdc_from_connected(void) {
if(usb_cdc.connected) {
usb_cdc_event_blink();
}
usb_cdc.connected = true;
usb_cdc.connected = false;
ESP_LOGI(TAG, "disconnect");
}
void tud_mount_cb(void) {
usb_cdc_to_connected();
}
void tud_umount_cb(void) {
ESP_LOGI(TAG, "Unmount");
if(usb_cdc.connected) {
led_set_blue(255);
delay(10);
led_set_blue(0);
}
usb_cdc.connected = false;
usb_cdc_from_connected();
}
void tud_resume_cb(void) {
ESP_LOGI(TAG, "Resume");
if(usb_cdc.connected) {
led_set_blue(255);
delay(10);
led_set_blue(0);
}
usb_cdc.connected = true;
usb_cdc_to_connected();
}
void tud_suspend_cb(bool remote_wakeup_en) {
ESP_LOGI(TAG, "Suspend");
if(usb_cdc.connected) {
led_set_blue(255);
delay(10);
led_set_blue(0);
}
usb_cdc.connected = false;
usb_cdc_from_connected();
}
void usb_cdc_init(void) {
usb_cdc.connected = false;
ESP_LOGI(TAG, "init");
static void usb_cdc_bus_reset() {
gpio_config_t io_conf;
io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
io_conf.mode = GPIO_MODE_OUTPUT_OD;
@ -159,25 +168,15 @@ void usb_cdc_init(void) {
delay(100);
gpio_set_level(USB_DN_PIN, 1);
gpio_set_level(USB_DP_PIN, 1);
}
tinyusb_config_t tusb_cfg = {
.descriptor = NULL, //Uses default descriptor specified in Menuconfig
.string_descriptor = NULL, //Uses default string specified in Menuconfig
.external_phy = false,
};
ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
tinyusb_config_cdcacm_t amc_cfg = {
.usb_dev = CDC_USB_DEV,
.cdc_port = TINYUSB_CDC_ACM_0,
.rx_unread_buf_sz = 64,
.callback_rx = &usb_cdc_rx_callback,
.callback_rx_wanted_char = NULL,
.callback_line_state_changed = &usb_cdc_line_state_changed_callback,
.callback_line_coding_changed = &usb_cdc_line_coding_changed_callback};
ESP_ERROR_CHECK(tusb_cdc_acm_init(&amc_cfg));
void usb_cdc_init(void) {
ESP_LOGI(TAG, "init");
usb_cdc.connected = false;
usb_uart_init();
usb_cdc_bus_reset();
dual_cdc_driver_install();
ESP_LOGI(TAG, "init done");
}

View File

@ -5,10 +5,6 @@
*/
void usb_cdc_init(void);
/**
* Send data
* @param buffer data
* @param size data size
* @param flush
*/
void usb_cdc_send(uint8_t* buffer, size_t size, bool flush);
void usb_cdc_gdb_tx_char(uint8_t c, bool flush);
void usb_cdc_uart_tx_char(uint8_t c, bool flush);

168
main/usb-uart.c Normal file
View File

@ -0,0 +1,168 @@
#include <simple-uart.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/stream_buffer.h>
#include <esp_log.h>
#include "usb-cdc.h"
#include "usb-uart.h"
#define USB_UART_PORT_NUM UART_NUM_0
#define USB_UART_TXD_PIN (43)
#define USB_UART_RXD_PIN (44)
#define USB_UART_BAUD_RATE (115200)
#define USB_UART_BUF_SIZE (128)
#define USB_UART_TX_BUF_SIZE (64)
#define USB_UART_RX_BUF_SIZE (64)
static StreamBufferHandle_t uart_rx_stream;
static void usb_uart_rx_isr(void* context);
static void usb_uart_rx_task(void* pvParameters);
static const char* TAG = "usb-uart";
void usb_uart_init() {
ESP_LOGI(TAG, "init");
uart_rx_stream = xStreamBufferCreate(USB_UART_BUF_SIZE * 4, 1);
xTaskCreate(usb_uart_rx_task, "usb_uart_rx", 4096, NULL, 5, NULL);
// esp_log_level_set("*", ESP_LOG_NONE);
UartConfig config = {
.uart_num = USB_UART_PORT_NUM,
.baud_rate = USB_UART_BAUD_RATE,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.tx_pin_num = USB_UART_TXD_PIN,
.rx_pin_num = USB_UART_RXD_PIN,
.isr_context = uart_rx_stream,
.rx_isr = usb_uart_rx_isr,
};
simple_uart_init(&config);
usb_uart_write((const uint8_t*)"Go", 2);
ESP_LOGI(TAG, "init done");
}
void usb_uart_write(const uint8_t* data, size_t data_size) {
/*for(size_t i = 0; i < data_size; i++) {
uart_tx_buffer[uart_tx_index] = data[i];
uart_tx_index++;
if(uart_tx_index == USB_UART_TX_BUF_SIZE) {
//cli_uart_flush(NULL);
}
}*/
simple_uart_write(USB_UART_PORT_NUM, data, data_size);
}
void usb_uart_set_line_state(bool dtr, bool rts) {
// do nothing, we don't have rts and dtr pins
}
void usb_uart_set_line_coding(
uint32_t bit_rate,
uint8_t stop_bits,
uint8_t parity,
uint8_t data_bits) {
simple_uart_set_baud_rate(USB_UART_PORT_NUM, bit_rate);
// cdc.h
// 0: 1 stop bit
// 1: 1.5 stop bits
// 2: 2 stop bits
switch(stop_bits) {
case 0:
simple_uart_set_stop_bits(USB_UART_PORT_NUM, UART_STOP_BITS_1);
break;
case 1:
simple_uart_set_stop_bits(USB_UART_PORT_NUM, UART_STOP_BITS_1_5);
break;
case 2:
simple_uart_set_stop_bits(USB_UART_PORT_NUM, UART_STOP_BITS_2);
break;
default:
break;
}
// cdc.h
// 0: None
// 1: Odd
// 2: Even
// 3: Mark
// 4: Space
switch(parity) {
case 0:
simple_uart_set_parity(USB_UART_PORT_NUM, UART_PARITY_DISABLE);
break;
case 1:
simple_uart_set_parity(USB_UART_PORT_NUM, UART_PARITY_ODD);
break;
case 2:
simple_uart_set_parity(USB_UART_PORT_NUM, UART_PARITY_EVEN);
break;
default:
break;
}
// cdc.h
// 5, 6, 7, 8 or 16
switch(parity) {
case 5:
simple_uart_set_data_bits(USB_UART_PORT_NUM, UART_DATA_5_BITS);
break;
case 6:
simple_uart_set_data_bits(USB_UART_PORT_NUM, UART_DATA_6_BITS);
break;
case 7:
simple_uart_set_data_bits(USB_UART_PORT_NUM, UART_DATA_7_BITS);
break;
case 8:
simple_uart_set_data_bits(USB_UART_PORT_NUM, UART_DATA_8_BITS);
break;
default:
break;
}
}
static void usb_uart_rx_task(void* pvParameters) {
while(1) {
uint8_t data[USB_UART_RX_BUF_SIZE];
size_t length =
xStreamBufferReceive(uart_rx_stream, data, USB_UART_RX_BUF_SIZE, portMAX_DELAY);
if(length > 0) {
for(size_t i = 0; i < length; i++) {
if((i + 1) == length) {
usb_cdc_uart_tx_char(data[i], true);
} else {
usb_cdc_uart_tx_char(data[i], false);
}
}
}
}
}
static void usb_uart_rx_isr(void* context) {
StreamBufferHandle_t stream = context;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
uint8_t data;
while(simple_uart_available(USB_UART_PORT_NUM)) {
simple_uart_read(USB_UART_PORT_NUM, &data, 1);
size_t ret __attribute__((unused));
ret = xStreamBufferSendFromISR(stream, &data, 1, &xHigherPriorityTaskWoken);
// we will drop data if the stream overflows
// ESP_ERROR_CHECK(ret != 1);
}
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

21
main/usb-uart.h Normal file
View File

@ -0,0 +1,21 @@
/**
* @file usb-uart.h
* @author Sergey Gavrilov (who.just.the.doctor@gmail.com)
* @version 1.0
* @date 2021-12-17
*
*
*/
#pragma once
void usb_uart_init();
void usb_uart_write(const uint8_t* data, size_t data_size);
void usb_uart_set_line_state(bool dtr, bool rts);
void usb_uart_set_line_coding(
uint32_t bit_rate,
uint8_t stop_bits,
uint8_t parity,
uint8_t data_bits);

View File

@ -43,13 +43,13 @@ CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set
# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set
# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set
# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set
CONFIG_BOOTLOADER_LOG_LEVEL_NONE=y
# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set
# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set
CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y
# CONFIG_BOOTLOADER_LOG_LEVEL_INFO is not set
# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set
# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set
CONFIG_BOOTLOADER_LOG_LEVEL=3
CONFIG_BOOTLOADER_LOG_LEVEL=0
CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y
# CONFIG_BOOTLOADER_FACTORY_RESET is not set
# CONFIG_BOOTLOADER_APP_TEST is not set
@ -462,14 +462,12 @@ CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y
# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set
CONFIG_ESP_MAIN_TASK_AFFINITY=0x0
CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048
CONFIG_ESP_CONSOLE_UART_DEFAULT=y
# CONFIG_ESP_CONSOLE_UART_DEFAULT is not set
# CONFIG_ESP_CONSOLE_USB_CDC is not set
# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set
# CONFIG_ESP_CONSOLE_NONE is not set
CONFIG_ESP_CONSOLE_UART=y
CONFIG_ESP_CONSOLE_NONE=y
CONFIG_ESP_CONSOLE_MULTIPLE_UART=y
CONFIG_ESP_CONSOLE_UART_NUM=0
CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200
CONFIG_ESP_CONSOLE_UART_NUM=-1
# CONFIG_ESP_INT_WDT is not set
# CONFIG_ESP_TASK_WDT is not set
# CONFIG_ESP_PANIC_HANDLER_IRAM is not set
@ -1095,47 +1093,6 @@ CONFIG_WS_BUFFER_SIZE=1024
# end of Websocket
# end of TCP Transport
#
# TinyUSB Stack
#
CONFIG_TINYUSB=y
CONFIG_TINYUSB_DEBUG_LEVEL=0
#
# TinyUSB task configuration
#
# CONFIG_TINYUSB_NO_DEFAULT_TASK is not set
CONFIG_TINYUSB_TASK_PRIORITY=17
CONFIG_TINYUSB_TASK_STACK_SIZE=4096
# end of TinyUSB task configuration
#
# Descriptor configuration
#
CONFIG_TINYUSB_DESC_USE_ESPRESSIF_VID=y
CONFIG_TINYUSB_DESC_USE_DEFAULT_PID=y
CONFIG_TINYUSB_DESC_BCD_DEVICE=0x0100
CONFIG_TINYUSB_DESC_MANUFACTURER_STRING="Flipper Devices Inc."
CONFIG_TINYUSB_DESC_PRODUCT_STRING="Blackmagic ESP32"
CONFIG_TINYUSB_DESC_SERIAL_STRING="blackmagic"
CONFIG_TINYUSB_DESC_CDC_STRING="Blackmagic ESP32"
# end of Descriptor configuration
#
# Massive Storage Class (MSC)
#
# CONFIG_TINYUSB_MSC_ENABLED is not set
# end of Massive Storage Class (MSC)
#
# Communication Device Class (CDC)
#
CONFIG_TINYUSB_CDC_ENABLED=y
CONFIG_TINYUSB_CDC_RX_BUFSIZE=64
CONFIG_TINYUSB_CDC_TX_BUFSIZE=64
# end of Communication Device Class (CDC)
# end of TinyUSB Stack
#
# Unity unit testing library
#
@ -1211,13 +1168,13 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y
# Deprecated options for backward compatibility
CONFIG_TOOLPREFIX="xtensa-esp32s2-elf-"
# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set
CONFIG_LOG_BOOTLOADER_LEVEL_NONE=y
# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set
# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set
CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y
# CONFIG_LOG_BOOTLOADER_LEVEL_INFO is not set
# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set
# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set
CONFIG_LOG_BOOTLOADER_LEVEL=3
CONFIG_LOG_BOOTLOADER_LEVEL=0
# CONFIG_APP_ROLLBACK_ENABLE is not set
# CONFIG_FLASH_ENCRYPTION_ENABLED is not set
# CONFIG_FLASHMODE_QIO is not set
@ -1270,12 +1227,10 @@ CONFIG_ESP32H2_MEMPROT_FEATURE_LOCK=y
CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32
CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304
CONFIG_MAIN_TASK_STACK_SIZE=3584
CONFIG_CONSOLE_UART_DEFAULT=y
# CONFIG_CONSOLE_UART_DEFAULT is not set
# CONFIG_CONSOLE_UART_CUSTOM is not set
# CONFIG_ESP_CONSOLE_UART_NONE is not set
CONFIG_CONSOLE_UART=y
CONFIG_CONSOLE_UART_NUM=0
CONFIG_CONSOLE_UART_BAUDRATE=115200
CONFIG_ESP_CONSOLE_UART_NONE=y
CONFIG_CONSOLE_UART_NUM=-1
# CONFIG_INT_WDT is not set
# CONFIG_TASK_WDT is not set
CONFIG_TIMER_TASK_STACK_SIZE=3584
@ -1333,21 +1288,6 @@ CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread"
CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y
# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set
# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set
CONFIG_USB_ENABLED=y
CONFIG_USB_DEBUG_LEVEL=0
# CONFIG_USB_DO_NOT_CREATE_TASK is not set
CONFIG_USB_TASK_PRIORITY=17
CONFIG_USB_DESC_USE_ESPRESSIF_VID=y
CONFIG_USB_DESC_USE_DEFAULT_PID=y
CONFIG_USB_DESC_BCDDEVICE=0x0100
CONFIG_USB_DESC_MANUFACTURER_STRING="Flipper Devices Inc."
CONFIG_USB_DESC_PRODUCT_STRING="Blackmagic ESP32"
CONFIG_USB_DESC_SERIAL_STRING="blackmagic"
CONFIG_USB_DESC_CDC_STRING="Blackmagic ESP32"
# CONFIG_USB_MSC_ENABLED is not set
CONFIG_USB_CDC_ENABLED=y
CONFIG_USB_CDC_RX_BUFSIZE=64
CONFIG_USB_CDC_TX_BUFSIZE=64
CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y
CONFIG_SUPPORT_TERMIOS=y
CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1