mirror of
https://github.com/MrUnknownDE/OpenIris-ESPIDF.git
synced 2026-05-05 21:36:05 +02:00
Initial refactors to support esp32 boards
This commit is contained in:
+4
-2
@@ -1,8 +1,10 @@
|
|||||||
# The following five lines of boilerplate have to be in your project's
|
|
||||||
# CMakeLists in this exact order for cmake to work correctly
|
|
||||||
cmake_minimum_required(VERSION 3.16)
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
set(EXTRA_COMPONENT_DIRS ${CMAKE_CURRENT_LIST_DIR}/components)
|
set(EXTRA_COMPONENT_DIRS ${CMAKE_CURRENT_LIST_DIR}/components)
|
||||||
|
|
||||||
|
if(IDF_TARGET STREQUAL "esp32s3" or IDF_TARGET STREQUAL "esp32s2")
|
||||||
|
list(APPEND EXTRA_COMPONENT_DIRS ${CMAKE_CURRENT_LIST_DIR}/extra_components)
|
||||||
|
endif()
|
||||||
|
|
||||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
project(blink)
|
project(blink)
|
||||||
|
|||||||
@@ -51,3 +51,9 @@ CONFIG_SPIRAM_CS_IO=26
|
|||||||
# CONFIG_SPIRAM_SPEED_120M is not set
|
# CONFIG_SPIRAM_SPEED_120M is not set
|
||||||
CONFIG_SPIRAM_SPEED_80M=y
|
CONFIG_SPIRAM_SPEED_80M=y
|
||||||
# CONFIG_SUPPORTS_EXTERNAL_LED_CONTROL is not set
|
# CONFIG_SUPPORTS_EXTERNAL_LED_CONTROL is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# OpenIris: Serial Communication Settings
|
||||||
|
#
|
||||||
|
CONFIG_UART_PORT_NUMER=1
|
||||||
|
# end of OpenIris: Serial Communication Settings
|
||||||
|
|||||||
@@ -51,3 +51,9 @@ CONFIG_SPIRAM_CS_IO=26
|
|||||||
# CONFIG_SPIRAM_SPEED_120M is not set
|
# CONFIG_SPIRAM_SPEED_120M is not set
|
||||||
CONFIG_SPIRAM_SPEED_80M=y
|
CONFIG_SPIRAM_SPEED_80M=y
|
||||||
# CONFIG_SUPPORTS_EXTERNAL_LED_CONTROL is not set
|
# CONFIG_SUPPORTS_EXTERNAL_LED_CONTROL is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# OpenIris: Serial Communication Settings
|
||||||
|
#
|
||||||
|
CONFIG_UART_PORT_NUMER=1
|
||||||
|
# end of OpenIris: Serial Communication Settings
|
||||||
|
|||||||
@@ -51,3 +51,9 @@ CONFIG_SPIRAM_CS_IO=26
|
|||||||
# CONFIG_SPIRAM_SPEED_120M is not set
|
# CONFIG_SPIRAM_SPEED_120M is not set
|
||||||
CONFIG_SPIRAM_SPEED_80M=y
|
CONFIG_SPIRAM_SPEED_80M=y
|
||||||
# CONFIG_SUPPORTS_EXTERNAL_LED_CONTROL is not set
|
# CONFIG_SUPPORTS_EXTERNAL_LED_CONTROL is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# OpenIris: Serial Communication Settings
|
||||||
|
#
|
||||||
|
CONFIG_UART_PORT_NUMER=1
|
||||||
|
# end of OpenIris: Serial Communication Settings
|
||||||
|
|||||||
@@ -69,3 +69,9 @@ CONFIG_GENERAL_BOARD="facefocusvr_eye_l"
|
|||||||
# CONFIG_LED_DEBUG_ENABLE is not set
|
# CONFIG_LED_DEBUG_ENABLE is not set
|
||||||
CONFIG_LED_EXTERNAL_AS_DEBUG=y
|
CONFIG_LED_EXTERNAL_AS_DEBUG=y
|
||||||
CONFIG_GENERAL_ADVERTISED_NAME="FFVR Eye L"
|
CONFIG_GENERAL_ADVERTISED_NAME="FFVR Eye L"
|
||||||
|
|
||||||
|
#
|
||||||
|
# OpenIris: Serial Communication Settings
|
||||||
|
#
|
||||||
|
CONFIG_UART_PORT_NUMER=1
|
||||||
|
# end of OpenIris: Serial Communication Settings
|
||||||
|
|||||||
@@ -69,3 +69,8 @@ CONFIG_GENERAL_BOARD="facefocusvr_eye_r"
|
|||||||
# CONFIG_LED_DEBUG_ENABLE is not set
|
# CONFIG_LED_DEBUG_ENABLE is not set
|
||||||
CONFIG_LED_EXTERNAL_AS_DEBUG=y
|
CONFIG_LED_EXTERNAL_AS_DEBUG=y
|
||||||
CONFIG_GENERAL_ADVERTISED_NAME="FFVR Eye R"
|
CONFIG_GENERAL_ADVERTISED_NAME="FFVR Eye R"
|
||||||
|
#
|
||||||
|
# OpenIris: Serial Communication Settings
|
||||||
|
#
|
||||||
|
CONFIG_UART_PORT_NUMER=1
|
||||||
|
# end of OpenIris: Serial Communication Settings
|
||||||
|
|||||||
@@ -69,3 +69,8 @@ CONFIG_GENERAL_BOARD="facefocusvr_face"
|
|||||||
# CONFIG_LED_DEBUG_ENABLE is not set
|
# CONFIG_LED_DEBUG_ENABLE is not set
|
||||||
CONFIG_LED_EXTERNAL_AS_DEBUG=y
|
CONFIG_LED_EXTERNAL_AS_DEBUG=y
|
||||||
CONFIG_GENERAL_ADVERTISED_NAME="FFVR Face"
|
CONFIG_GENERAL_ADVERTISED_NAME="FFVR Face"
|
||||||
|
#
|
||||||
|
# OpenIris: Serial Communication Settings
|
||||||
|
#
|
||||||
|
CONFIG_UART_PORT_NUMER=1
|
||||||
|
# end of OpenIris: Serial Communication Settings
|
||||||
|
|||||||
@@ -58,3 +58,8 @@ CONFIG_GENERAL_INCLUDE_UVC_MODE=y
|
|||||||
# CONFIG_MONITORING_LED_CURRENT is not set
|
# CONFIG_MONITORING_LED_CURRENT is not set
|
||||||
CONFIG_GENERAL_BOARD="project_babble"
|
CONFIG_GENERAL_BOARD="project_babble"
|
||||||
CONFIG_GENERAL_ENABLE_WIRELESS=y
|
CONFIG_GENERAL_ENABLE_WIRELESS=y
|
||||||
|
#
|
||||||
|
# OpenIris: Serial Communication Settings
|
||||||
|
#
|
||||||
|
CONFIG_UART_PORT_NUMER=1
|
||||||
|
# end of OpenIris: Serial Communication Settings
|
||||||
|
|||||||
@@ -2228,7 +2228,6 @@ CONFIG_TUSB_PID=0x8000
|
|||||||
CONFIG_TUSB_MANUFACTURER="ETVR"
|
CONFIG_TUSB_MANUFACTURER="ETVR"
|
||||||
CONFIG_TUSB_PRODUCT="OpenIris Camera"
|
CONFIG_TUSB_PRODUCT="OpenIris Camera"
|
||||||
CONFIG_TUSB_SERIAL_NUM="12345678"
|
CONFIG_TUSB_SERIAL_NUM="12345678"
|
||||||
# CONFIG_UVC_SUPPORT_TWO_CAM is not set
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# USB Cam1 Config
|
# USB Cam1 Config
|
||||||
@@ -2568,3 +2567,8 @@ CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y
|
|||||||
CONFIG_SUPPORT_TERMIOS=y
|
CONFIG_SUPPORT_TERMIOS=y
|
||||||
CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1
|
CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1
|
||||||
# End of deprecated options
|
# End of deprecated options
|
||||||
|
#
|
||||||
|
# OpenIris: Serial Communication Settings
|
||||||
|
#
|
||||||
|
CONFIG_UART_PORT_NUMER=1
|
||||||
|
# end of OpenIris: Serial Communication Settings
|
||||||
@@ -62,3 +62,8 @@ CONFIG_GENERAL_INCLUDE_UVC_MODE=y
|
|||||||
# CONFIG_MONITORING_LED_CURRENT is not set
|
# CONFIG_MONITORING_LED_CURRENT is not set
|
||||||
CONFIG_GENERAL_BOARD="xiao_esp32s3"
|
CONFIG_GENERAL_BOARD="xiao_esp32s3"
|
||||||
CONFIG_GENERAL_ENABLE_WIRELESS=y
|
CONFIG_GENERAL_ENABLE_WIRELESS=y
|
||||||
|
#
|
||||||
|
# OpenIris: Serial Communication Settings
|
||||||
|
#
|
||||||
|
CONFIG_UART_PORT_NUMER=1
|
||||||
|
# end of OpenIris: Serial Communication Settings
|
||||||
|
|||||||
@@ -50,3 +50,8 @@ CONFIG_SPIRAM_CS_IO=26
|
|||||||
# CONFIG_SPIRAM_SPEED_120M is not set
|
# CONFIG_SPIRAM_SPEED_120M is not set
|
||||||
CONFIG_SPIRAM_SPEED_80M=y
|
CONFIG_SPIRAM_SPEED_80M=y
|
||||||
# CONFIG_SUPPORTS_EXTERNAL_LED_CONTROL is not set
|
# CONFIG_SUPPORTS_EXTERNAL_LED_CONTROL is not set
|
||||||
|
#
|
||||||
|
# OpenIris: Serial Communication Settings
|
||||||
|
#
|
||||||
|
CONFIG_UART_PORT_NUMER=1
|
||||||
|
# end of OpenIris: Serial Communication Settings
|
||||||
@@ -50,3 +50,8 @@ CONFIG_SPIRAM_CS_IO=26
|
|||||||
# CONFIG_SPIRAM_SPEED_120M is not set
|
# CONFIG_SPIRAM_SPEED_120M is not set
|
||||||
CONFIG_SPIRAM_SPEED_80M=y
|
CONFIG_SPIRAM_SPEED_80M=y
|
||||||
# CONFIG_SUPPORTS_EXTERNAL_LED_CONTROL is not set
|
# CONFIG_SUPPORTS_EXTERNAL_LED_CONTROL is not set
|
||||||
|
#
|
||||||
|
# OpenIris: Serial Communication Settings
|
||||||
|
#
|
||||||
|
CONFIG_UART_PORT_NUMER=1
|
||||||
|
# end of OpenIris: Serial Communication Settings
|
||||||
@@ -50,3 +50,8 @@ CONFIG_SPIRAM_CS_IO=26
|
|||||||
# CONFIG_SPIRAM_SPEED_120M is not set
|
# CONFIG_SPIRAM_SPEED_120M is not set
|
||||||
CONFIG_SPIRAM_SPEED_80M=y
|
CONFIG_SPIRAM_SPEED_80M=y
|
||||||
# CONFIG_SUPPORTS_EXTERNAL_LED_CONTROL is not set
|
# CONFIG_SUPPORTS_EXTERNAL_LED_CONTROL is not set
|
||||||
|
#
|
||||||
|
# OpenIris: Serial Communication Settings
|
||||||
|
#
|
||||||
|
CONFIG_UART_PORT_NUMER=1
|
||||||
|
# end of OpenIris: Serial Communication Settings
|
||||||
@@ -1,4 +1,32 @@
|
|||||||
idf_component_register(SRCS "SerialManager/SerialManager.cpp"
|
set (
|
||||||
INCLUDE_DIRS "SerialManager"
|
requires
|
||||||
REQUIRES esp_driver_uart CommandManager ProjectConfig tinyusb
|
esp_driver_uart
|
||||||
|
CommandManager
|
||||||
|
ProjectConfig
|
||||||
|
)
|
||||||
|
|
||||||
|
if ("$ENV{IDF_ETARGET}" STREQUAL "esp32s3")
|
||||||
|
list(APPEND requires
|
||||||
|
tinyusb
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set (
|
||||||
|
source_files
|
||||||
|
"SerialManager/SerialManager.cpp"
|
||||||
|
)
|
||||||
|
|
||||||
|
if ("$ENV{IDF_ETARGET}" STREQUAL "esp32s3" OR "$ENV{IDF_ETARGET}" STREQUAL "esp32s2" )
|
||||||
|
list(APPEND source_files
|
||||||
|
"SerialManager/SerialManager_esp32s3.cpp"
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
list(APPEND source_files
|
||||||
|
"SerialManager/SerialManager_esp32.cpp"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
idf_component_register(SRCS ${source_files}
|
||||||
|
INCLUDE_DIRS "SerialManager"
|
||||||
|
REQUIRES ${requires}
|
||||||
)
|
)
|
||||||
@@ -1,9 +1,6 @@
|
|||||||
#include "SerialManager.hpp"
|
#include "SerialManager.hpp"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "main_globals.hpp"
|
#include "main_globals.hpp"
|
||||||
#include "tusb.h"
|
|
||||||
|
|
||||||
#define BUF_SIZE (1024)
|
|
||||||
|
|
||||||
SerialManager::SerialManager(std::shared_ptr<CommandManager> commandManager, esp_timer_handle_t *timerHandle)
|
SerialManager::SerialManager(std::shared_ptr<CommandManager> commandManager, esp_timer_handle_t *timerHandle)
|
||||||
: commandManager(commandManager), timerHandle(timerHandle)
|
: commandManager(commandManager), timerHandle(timerHandle)
|
||||||
@@ -12,62 +9,6 @@ SerialManager::SerialManager(std::shared_ptr<CommandManager> commandManager, esp
|
|||||||
this->temp_data = static_cast<uint8_t *>(malloc(256));
|
this->temp_data = static_cast<uint8_t *>(malloc(256));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerialManager::setup()
|
|
||||||
{
|
|
||||||
usb_serial_jtag_driver_config_t usb_serial_jtag_config;
|
|
||||||
usb_serial_jtag_config.rx_buffer_size = BUF_SIZE;
|
|
||||||
usb_serial_jtag_config.tx_buffer_size = BUF_SIZE;
|
|
||||||
usb_serial_jtag_driver_install(&usb_serial_jtag_config);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SerialManager::try_receive()
|
|
||||||
{
|
|
||||||
static auto current_position = 0;
|
|
||||||
int len = usb_serial_jtag_read_bytes(this->temp_data, 256, 1000 / 20);
|
|
||||||
|
|
||||||
// If driver is uninstalled or an error occurs, abort read gracefully
|
|
||||||
if (len < 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len > 0)
|
|
||||||
{
|
|
||||||
// Notify main that a command was received during startup
|
|
||||||
notify_startup_command_received();
|
|
||||||
}
|
|
||||||
|
|
||||||
// since we've got something on the serial port
|
|
||||||
// we gotta keep reading until we've got the whole message
|
|
||||||
// we will submit the command once we get a newline, a return or the buffer is full
|
|
||||||
for (auto i = 0; i < len; i++)
|
|
||||||
{
|
|
||||||
this->data[current_position++] = this->temp_data[i];
|
|
||||||
// if we're at the end of the buffer, try to process the command anyway
|
|
||||||
// if we've got a new line, we've finished sending the commands, process them
|
|
||||||
if (current_position >= BUF_SIZE || this->data[current_position - 1] == '\n' || this->data[current_position - 1] == '\r')
|
|
||||||
{
|
|
||||||
data[current_position] = '\0';
|
|
||||||
current_position = 0;
|
|
||||||
|
|
||||||
const nlohmann::json result = this->commandManager->executeFromJson(std::string_view(reinterpret_cast<const char *>(this->data)));
|
|
||||||
const auto resultMessage = result.dump();
|
|
||||||
usb_serial_jtag_write_bytes_chunked(resultMessage.c_str(), resultMessage.length(), 1000 / 20);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SerialManager::usb_serial_jtag_write_bytes_chunked(const char *data, size_t len, size_t timeout)
|
|
||||||
{
|
|
||||||
while (len > 0)
|
|
||||||
{
|
|
||||||
auto to_write = len > BUF_SIZE ? BUF_SIZE : len;
|
|
||||||
auto written = usb_serial_jtag_write_bytes(data, to_write, timeout);
|
|
||||||
data += written;
|
|
||||||
len -= written;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to notify that a command was received during startup
|
// Function to notify that a command was received during startup
|
||||||
void SerialManager::notify_startup_command_received()
|
void SerialManager::notify_startup_command_received()
|
||||||
{
|
{
|
||||||
@@ -83,21 +24,6 @@ void SerialManager::notify_startup_command_received()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerialManager::shutdown()
|
|
||||||
{
|
|
||||||
// Stop heartbeats; timer will be deleted by main if needed.
|
|
||||||
// Uninstall the USB Serial JTAG driver to free the internal USB for TinyUSB.
|
|
||||||
esp_err_t err = usb_serial_jtag_driver_uninstall();
|
|
||||||
if (err == ESP_OK)
|
|
||||||
{
|
|
||||||
ESP_LOGI("[SERIAL]", "usb_serial_jtag driver uninstalled");
|
|
||||||
}
|
|
||||||
else if (err != ESP_ERR_INVALID_STATE)
|
|
||||||
{
|
|
||||||
ESP_LOGW("[SERIAL]", "usb_serial_jtag_driver_uninstall returned %s", esp_err_to_name(err));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// we can cancel this task once we're in cdc
|
// we can cancel this task once we're in cdc
|
||||||
void HandleSerialManagerTask(void *pvParameters)
|
void HandleSerialManagerTask(void *pvParameters)
|
||||||
{
|
{
|
||||||
@@ -107,72 +33,3 @@ void HandleSerialManagerTask(void *pvParameters)
|
|||||||
serialManager->try_receive();
|
serialManager->try_receive();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleCDCSerialManagerTask(void *pvParameters)
|
|
||||||
{
|
|
||||||
auto const commandManager = static_cast<CommandManager *>(pvParameters);
|
|
||||||
static char buffer[BUF_SIZE];
|
|
||||||
auto idx = 0;
|
|
||||||
|
|
||||||
cdc_command_packet_t packet;
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
if (xQueueReceive(cdcMessageQueue, &packet, portMAX_DELAY) == pdTRUE)
|
|
||||||
{
|
|
||||||
for (auto i = 0; i < packet.len; i++)
|
|
||||||
{
|
|
||||||
buffer[idx++] = packet.data[i];
|
|
||||||
// if we're at the end of the buffer, try to process the command anyway
|
|
||||||
// if we've got a new line, we've finished sending the commands, process them
|
|
||||||
if (idx >= BUF_SIZE || buffer[idx - 1] == '\n' || buffer[idx - 1] == '\r')
|
|
||||||
{
|
|
||||||
buffer[idx - 1] = '\0';
|
|
||||||
const nlohmann::json result = commandManager->executeFromJson(std::string_view(reinterpret_cast<const char *>(buffer)));
|
|
||||||
const auto resultMessage = result.dump();
|
|
||||||
tud_cdc_write(resultMessage.c_str(), resultMessage.length());
|
|
||||||
tud_cdc_write_flush();
|
|
||||||
idx = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// tud_cdc_rx_cb is defined as TU_ATTR_WEAK so we can override it, we will be called back if we get some data
|
|
||||||
// but we don't want to do any processing here since we don't want to risk blocking
|
|
||||||
// grab the data and send it to a queue, a special task will process it and handle with the command manager
|
|
||||||
extern "C" void tud_cdc_rx_cb(uint8_t itf)
|
|
||||||
{
|
|
||||||
// we can void the interface number
|
|
||||||
(void)itf;
|
|
||||||
cdc_command_packet_t packet;
|
|
||||||
auto len = tud_cdc_available();
|
|
||||||
|
|
||||||
if (len > 0)
|
|
||||||
{
|
|
||||||
auto read = tud_cdc_read(packet.data, sizeof(packet.data));
|
|
||||||
if (read > 0)
|
|
||||||
{
|
|
||||||
// we should be safe here, given that the max buffer size is 64
|
|
||||||
packet.len = static_cast<uint8_t>(read);
|
|
||||||
xQueueSend(cdcMessageQueue, &packet, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts)
|
|
||||||
{
|
|
||||||
(void)itf;
|
|
||||||
(void)dtr;
|
|
||||||
(void)rts;
|
|
||||||
|
|
||||||
ESP_LOGI("[SERIAL]", "CDC line state changed: DTR=%d, RTS=%d", dtr, rts);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const *p_line_coding)
|
|
||||||
{
|
|
||||||
(void)itf;
|
|
||||||
ESP_LOGI("[SERIAL]", "CDC line coding: %" PRIu32 " bps, %d stop bits, %d parity, %d data bits",
|
|
||||||
p_line_coding->bit_rate, p_line_coding->stop_bits,
|
|
||||||
p_line_coding->parity, p_line_coding->data_bits);
|
|
||||||
}
|
|
||||||
@@ -10,14 +10,15 @@
|
|||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
#include "freertos/queue.h"
|
#include "freertos/queue.h"
|
||||||
#include "driver/uart.h"
|
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "driver/usb_serial_jtag.h"
|
|
||||||
#include "esp_vfs_usb_serial_jtag.h"
|
|
||||||
#include "esp_vfs_dev.h"
|
#include "esp_vfs_dev.h"
|
||||||
#include "esp_mac.h"
|
#include "esp_mac.h"
|
||||||
|
|
||||||
|
#ifndef BUF_SIZE
|
||||||
|
#define BUF_SIZE (1024)
|
||||||
|
#endif
|
||||||
|
|
||||||
extern "C" void tud_cdc_rx_cb(uint8_t itf);
|
extern "C" void tud_cdc_rx_cb(uint8_t itf);
|
||||||
extern "C" void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts);
|
extern "C" void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts);
|
||||||
|
|
||||||
@@ -39,8 +40,6 @@ public:
|
|||||||
void shutdown();
|
void shutdown();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void usb_serial_jtag_write_bytes_chunked(const char *data, size_t len, size_t timeout);
|
|
||||||
|
|
||||||
std::shared_ptr<CommandManager> commandManager;
|
std::shared_ptr<CommandManager> commandManager;
|
||||||
esp_timer_handle_t *timerHandle;
|
esp_timer_handle_t *timerHandle;
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#include "SerialManager.hpp"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "main_globals.hpp"
|
||||||
|
#include "driver/uart.h"
|
||||||
|
|
||||||
|
void SerialManager::setup()
|
||||||
|
{
|
||||||
|
// usb_serial_jtag_driver_config_t usb_serial_jtag_config;
|
||||||
|
// usb_serial_jtag_config.rx_buffer_size = BUF_SIZE;
|
||||||
|
// usb_serial_jtag_config.tx_buffer_size = BUF_SIZE;
|
||||||
|
// usb_serial_jtag_driver_install(&usb_serial_jtag_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialManager::try_receive()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialManager::shutdown()
|
||||||
|
{
|
||||||
|
// Stop heartbeats; timer will be deleted by main if needed.
|
||||||
|
// Uninstall the USB Serial JTAG driver to free the internal USB for TinyUSB.
|
||||||
|
// esp_err_t err = usb_serial_jtag_driver_uninstall();
|
||||||
|
// if (err == ESP_OK)
|
||||||
|
// {
|
||||||
|
// ESP_LOGI("[SERIAL]", "usb_serial_jtag driver uninstalled");
|
||||||
|
// }
|
||||||
|
// else if (err != ESP_ERR_INVALID_STATE)
|
||||||
|
// {
|
||||||
|
// ESP_LOGW("[SERIAL]", "usb_serial_jtag_driver_uninstall returned %s", esp_err_to_name(err));
|
||||||
|
// }
|
||||||
|
}
|
||||||
@@ -0,0 +1,152 @@
|
|||||||
|
#include "SerialManager.hpp"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "main_globals.hpp"
|
||||||
|
#include "driver/usb_serial_jtag.h"
|
||||||
|
#include "esp_vfs_usb_serial_jtag.h"
|
||||||
|
|
||||||
|
#include "tusb.h"
|
||||||
|
|
||||||
|
void SerialManager::setup()
|
||||||
|
{
|
||||||
|
#ifndef CONFIG_USE_UART_FOR_COMMUNICATION
|
||||||
|
usb_serial_jtag_driver_config_t usb_serial_jtag_config;
|
||||||
|
usb_serial_jtag_config.rx_buffer_size = BUF_SIZE;
|
||||||
|
usb_serial_jtag_config.tx_buffer_size = BUF_SIZE;
|
||||||
|
usb_serial_jtag_driver_install(&usb_serial_jtag_config);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
usb_serial_jtag_write_bytes_chunked(const char *data, size_t len, size_t timeout)
|
||||||
|
{
|
||||||
|
#ifndef CONFIG_USE_UART_FOR_COMMUNICATION
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
auto to_write = len > BUF_SIZE ? BUF_SIZE : len;
|
||||||
|
auto written = usb_serial_jtag_write_bytes(data, to_write, timeout);
|
||||||
|
data += written;
|
||||||
|
len -= written;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialManager::try_receive()
|
||||||
|
{
|
||||||
|
static auto current_position = 0;
|
||||||
|
int len = usb_serial_jtag_read_bytes(this->temp_data, 256, 1000 / 20);
|
||||||
|
|
||||||
|
// If driver is uninstalled or an error occurs, abort read gracefully
|
||||||
|
if (len < 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len > 0)
|
||||||
|
{
|
||||||
|
// Notify main that a command was received during startup
|
||||||
|
notify_startup_command_received();
|
||||||
|
}
|
||||||
|
|
||||||
|
// since we've got something on the serial port
|
||||||
|
// we gotta keep reading until we've got the whole message
|
||||||
|
// we will submit the command once we get a newline, a return or the buffer is full
|
||||||
|
for (auto i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
this->data[current_position++] = this->temp_data[i];
|
||||||
|
// if we're at the end of the buffer, try to process the command anyway
|
||||||
|
// if we've got a new line, we've finished sending the commands, process them
|
||||||
|
if (current_position >= BUF_SIZE || this->data[current_position - 1] == '\n' || this->data[current_position - 1] == '\r')
|
||||||
|
{
|
||||||
|
data[current_position] = '\0';
|
||||||
|
current_position = 0;
|
||||||
|
|
||||||
|
const nlohmann::json result = this->commandManager->executeFromJson(std::string_view(reinterpret_cast<const char *>(this->data)));
|
||||||
|
const auto resultMessage = result.dump();
|
||||||
|
usb_serial_jtag_write_bytes_chunked(resultMessage.c_str(), resultMessage.length(), 1000 / 20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialManager::shutdown()
|
||||||
|
{
|
||||||
|
// Uninstall the USB Serial JTAG driver to free the internal USB for TinyUSB.
|
||||||
|
esp_err_t err = usb_serial_jtag_driver_uninstall();
|
||||||
|
if (err == ESP_OK)
|
||||||
|
{
|
||||||
|
ESP_LOGI("[SERIAL]", "usb_serial_jtag driver uninstalled");
|
||||||
|
}
|
||||||
|
else if (err != ESP_ERR_INVALID_STATE)
|
||||||
|
{
|
||||||
|
ESP_LOGW("[SERIAL]", "usb_serial_jtag_driver_uninstall returned %s", esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleCDCSerialManagerTask(void *pvParameters)
|
||||||
|
{
|
||||||
|
#ifndef CONFIG_USE_UART_FOR_COMMUNICATION
|
||||||
|
auto const commandManager = static_cast<CommandManager *>(pvParameters);
|
||||||
|
static char buffer[BUF_SIZE];
|
||||||
|
auto idx = 0;
|
||||||
|
|
||||||
|
cdc_command_packet_t packet;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (xQueueReceive(cdcMessageQueue, &packet, portMAX_DELAY) == pdTRUE)
|
||||||
|
{
|
||||||
|
for (auto i = 0; i < packet.len; i++)
|
||||||
|
{
|
||||||
|
buffer[idx++] = packet.data[i];
|
||||||
|
// if we're at the end of the buffer, try to process the command anyway
|
||||||
|
// if we've got a new line, we've finished sending the commands, process them
|
||||||
|
if (idx >= BUF_SIZE || buffer[idx - 1] == '\n' || buffer[idx - 1] == '\r')
|
||||||
|
{
|
||||||
|
buffer[idx - 1] = '\0';
|
||||||
|
const nlohmann::json result = commandManager->executeFromJson(std::string_view(reinterpret_cast<const char *>(buffer)));
|
||||||
|
const auto resultMessage = result.dump();
|
||||||
|
tud_cdc_write(resultMessage.c_str(), resultMessage.length());
|
||||||
|
tud_cdc_write_flush();
|
||||||
|
idx = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// tud_cdc_rx_cb is defined as TU_ATTR_WEAK so we can override it, we will be called back if we get some data
|
||||||
|
// but we don't want to do any processing here since we don't want to risk blocking
|
||||||
|
// grab the data and send it to a queue, a special task will process it and handle with the command manager
|
||||||
|
extern "C" void tud_cdc_rx_cb(uint8_t itf)
|
||||||
|
{
|
||||||
|
// we can void the interface number
|
||||||
|
(void)itf;
|
||||||
|
cdc_command_packet_t packet;
|
||||||
|
auto len = tud_cdc_available();
|
||||||
|
|
||||||
|
if (len > 0)
|
||||||
|
{
|
||||||
|
auto read = tud_cdc_read(packet.data, sizeof(packet.data));
|
||||||
|
if (read > 0)
|
||||||
|
{
|
||||||
|
// we should be safe here, given that the max buffer size is 64
|
||||||
|
packet.len = static_cast<uint8_t>(read);
|
||||||
|
xQueueSend(cdcMessageQueue, &packet, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts)
|
||||||
|
{
|
||||||
|
(void)itf;
|
||||||
|
(void)dtr;
|
||||||
|
(void)rts;
|
||||||
|
|
||||||
|
ESP_LOGI("[SERIAL]", "CDC line state changed: DTR=%d, RTS=%d", dtr, rts);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const *p_line_coding)
|
||||||
|
{
|
||||||
|
(void)itf;
|
||||||
|
ESP_LOGI("[SERIAL]", "CDC line coding: %" PRIu32 " bps, %d stop bits, %d parity, %d data bits",
|
||||||
|
p_line_coding->bit_rate, p_line_coding->stop_bits,
|
||||||
|
p_line_coding->parity, p_line_coding->data_bits);
|
||||||
|
}
|
||||||
@@ -1,4 +1,19 @@
|
|||||||
|
set (
|
||||||
|
requires
|
||||||
|
esp_timer
|
||||||
|
esp32-camera
|
||||||
|
StateManager
|
||||||
|
CameraManager
|
||||||
|
Helpers
|
||||||
|
)
|
||||||
|
|
||||||
|
if ("$ENV{IDF_ETARGET}" STREQUAL "esp32s3")
|
||||||
|
list(APPEND required
|
||||||
|
usb_device_uvc
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
idf_component_register(SRCS "UVCStream/UVCStream.cpp"
|
idf_component_register(SRCS "UVCStream/UVCStream.cpp"
|
||||||
INCLUDE_DIRS "UVCStream"
|
INCLUDE_DIRS "UVCStream"
|
||||||
REQUIRES esp_timer esp32-camera StateManager usb_device_uvc CameraManager Helpers
|
REQUIRES ${requires}
|
||||||
)
|
)
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
|
#ifdef CONFIG_GENERAL_INCLUDE_UVC_MODE
|
||||||
|
|
||||||
#include "UVCStream.hpp"
|
#include "UVCStream.hpp"
|
||||||
#include <cstdio> // for snprintf
|
#include <cstdio> // for snprintf
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
// no deps on main globals here; handover is performed in main before calling setup when needed
|
|
||||||
|
|
||||||
static const char *UVC_STREAM_TAG = "[UVC DEVICE]";
|
static const char *UVC_STREAM_TAG = "[UVC DEVICE]";
|
||||||
|
|
||||||
@@ -167,12 +168,6 @@ static void UVCStreamHelpers::camera_fb_return_cb(uvc_fb_t *fb, void *cb_ctx)
|
|||||||
|
|
||||||
esp_err_t UVCStreamManager::setup()
|
esp_err_t UVCStreamManager::setup()
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifndef CONFIG_GENERAL_INCLUDE_UVC_MODE
|
|
||||||
ESP_LOGE(UVC_STREAM_TAG, "The board does not support UVC, please, setup WiFi connection.");
|
|
||||||
return ESP_FAIL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ESP_LOGI(UVC_STREAM_TAG, "Setting up UVC Stream");
|
ESP_LOGI(UVC_STREAM_TAG, "Setting up UVC Stream");
|
||||||
// Allocate a fixed-size transfer buffer (compile-time constant)
|
// Allocate a fixed-size transfer buffer (compile-time constant)
|
||||||
uvc_buffer_size = UVCStreamManager::UVC_MAX_FRAMESIZE_SIZE;
|
uvc_buffer_size = UVCStreamManager::UVC_MAX_FRAMESIZE_SIZE;
|
||||||
@@ -219,3 +214,5 @@ esp_err_t UVCStreamManager::start()
|
|||||||
// UVC device is already initialized in setup(), just log that we're starting
|
// UVC device is already initialized in setup(), just log that we're starting
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#ifdef CONFIG_GENERAL_INCLUDE_UVC_MODE
|
||||||
#pragma once
|
#pragma once
|
||||||
#ifndef UVCSTREAM_HPP
|
#ifndef UVCSTREAM_HPP
|
||||||
#define UVCSTREAM_HPP
|
#define UVCSTREAM_HPP
|
||||||
@@ -33,8 +34,6 @@ extern QueueHandle_t eventQueue;
|
|||||||
|
|
||||||
namespace UVCStreamHelpers
|
namespace UVCStreamHelpers
|
||||||
{
|
{
|
||||||
// TODO move the camera handling code to the camera manager and have the uvc manager initialize it in wired mode
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
camera_fb_t *cam_fb_p;
|
camera_fb_t *cam_fb_p;
|
||||||
@@ -64,3 +63,4 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
#endif // UVCSTREAM_HPP
|
#endif // UVCSTREAM_HPP
|
||||||
|
#endif
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "sdkconfig.h"
|
|
||||||
|
|
||||||
#ifdef CONFIG_FORMAT_MJPEG_CAM1
|
|
||||||
#define FORMAT_MJPEG_CAM1 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_UVC_CAM1_MULTI_FRAMESIZE
|
|
||||||
//If enable, add VGA and HVGA to list
|
|
||||||
#define UVC_CAM1_FRAME_MULTI 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define UVC_CAM1_FRAME_WIDTH CONFIG_UVC_CAM1_FRAMESIZE_WIDTH
|
|
||||||
#define UVC_CAM1_FRAME_HEIGHT CONFIG_UVC_CAM1_FRAMESIZE_HEIGT
|
|
||||||
#define UVC_CAM1_FRAME_RATE CONFIG_UVC_CAM1_FRAMERATE
|
|
||||||
|
|
||||||
#ifdef CONFIG_UVC_MODE_BULK_CAM1
|
|
||||||
#define UVC_CAM1_BULK_MODE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CONFIG_UVC_SUPPORT_TWO_CAM
|
|
||||||
#ifdef CONFIG_FORMAT_MJPEG_CAM2
|
|
||||||
#define FORMAT_MJPEG_CAM2 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_UVC_CAM2_MULTI_FRAMESIZE
|
|
||||||
//If enable, add VGA and HVGA to list
|
|
||||||
#define UVC_CAM2_FRAME_MULTI 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define UVC_CAM2_FRAME_WIDTH CONFIG_UVC_CAM2_FRAMESIZE_WIDTH
|
|
||||||
#define UVC_CAM2_FRAME_HEIGHT CONFIG_UVC_CAM2_FRAMESIZE_HEIGT
|
|
||||||
#define UVC_CAM2_FRAME_RATE CONFIG_UVC_CAM2_FRAMERATE
|
|
||||||
|
|
||||||
#ifdef CONFIG_UVC_MODE_BULK_CAM2
|
|
||||||
#define UVC_CAM2_BULK_MODE
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef UVC_CAM2_FRAME_WIDTH
|
|
||||||
#define UVC_CAM2_FRAME_WIDTH UVC_CAM1_FRAME_WIDTH
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef UVC_CAM2_FRAME_HEIGHT
|
|
||||||
#define UVC_CAM2_FRAME_HEIGHT UVC_CAM1_FRAME_HEIGHT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef UVC_CAM2_FRAME_RATE
|
|
||||||
#define UVC_CAM2_FRAME_RATE UVC_CAM1_FRAME_RATE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const struct {
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
int rate;
|
|
||||||
} UVC_FRAMES_INFO[][4] = {{
|
|
||||||
{UVC_CAM1_FRAME_WIDTH, UVC_CAM1_FRAME_HEIGHT, UVC_CAM1_FRAME_RATE},
|
|
||||||
{CONFIG_UVC_MULTI_FRAME_WIDTH_1, CONFIG_UVC_MULTI_FRAME_HEIGHT_1, CONFIG_UVC_MULTI_FRAME_FPS_1},
|
|
||||||
{CONFIG_UVC_MULTI_FRAME_WIDTH_2, CONFIG_UVC_MULTI_FRAME_HEIGHT_2, CONFIG_UVC_MULTI_FRAME_FPS_2},
|
|
||||||
{CONFIG_UVC_MULTI_FRAME_WIDTH_3, CONFIG_UVC_MULTI_FRAME_HEIGHT_3, CONFIG_UVC_MULTI_FRAME_FPS_3},
|
|
||||||
}, {
|
|
||||||
{UVC_CAM2_FRAME_WIDTH, UVC_CAM2_FRAME_HEIGHT, UVC_CAM2_FRAME_RATE},
|
|
||||||
{CONFIG_UVC_MULTI_FRAME_WIDTH_1, CONFIG_UVC_MULTI_FRAME_HEIGHT_1, CONFIG_UVC_MULTI_FRAME_FPS_1},
|
|
||||||
{CONFIG_UVC_MULTI_FRAME_WIDTH_2, CONFIG_UVC_MULTI_FRAME_HEIGHT_2, CONFIG_UVC_MULTI_FRAME_FPS_2},
|
|
||||||
{CONFIG_UVC_MULTI_FRAME_WIDTH_3, CONFIG_UVC_MULTI_FRAME_HEIGHT_3, CONFIG_UVC_MULTI_FRAME_FPS_3},
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#define UVC_FRAME_NUM (sizeof(UVC_FRAMES_INFO[0]) / sizeof(UVC_FRAMES_INFO[0][0]))
|
|
||||||
_Static_assert(UVC_FRAME_NUM == 4, "UVC_FRAME_NUM must be 4");
|
|
||||||
+2
-28
@@ -1,14 +1,4 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
espressif/cmake_utilities:
|
|
||||||
component_hash: 05165f30922b422b4b90c08845e6d449329b97370fbd06309803d8cb539d79e3
|
|
||||||
dependencies:
|
|
||||||
- name: idf
|
|
||||||
require: private
|
|
||||||
version: '>=4.1'
|
|
||||||
source:
|
|
||||||
registry_url: https://components.espressif.com/
|
|
||||||
type: service
|
|
||||||
version: 1.1.1
|
|
||||||
espressif/esp32-camera:
|
espressif/esp32-camera:
|
||||||
component_hash: c3eb05fbeeae884a23bed9b17d48d5f0da8872beadae0c0e747d2fbea6094f06
|
component_hash: c3eb05fbeeae884a23bed9b17d48d5f0da8872beadae0c0e747d2fbea6094f06
|
||||||
dependencies: []
|
dependencies: []
|
||||||
@@ -36,31 +26,15 @@ dependencies:
|
|||||||
registry_url: https://components.espressif.com/
|
registry_url: https://components.espressif.com/
|
||||||
type: service
|
type: service
|
||||||
version: 1.8.2
|
version: 1.8.2
|
||||||
espressif/tinyusb:
|
|
||||||
component_hash: 214989d502fc168241a4a4f83b097d8ac44a93cd6f1787b4ac10069a8b3bebd3
|
|
||||||
dependencies:
|
|
||||||
- name: idf
|
|
||||||
require: private
|
|
||||||
version: '>=5.0'
|
|
||||||
source:
|
|
||||||
registry_url: https://components.espressif.com/
|
|
||||||
type: service
|
|
||||||
targets:
|
|
||||||
- esp32s2
|
|
||||||
- esp32s3
|
|
||||||
- esp32p4
|
|
||||||
version: 0.15.0~10
|
|
||||||
idf:
|
idf:
|
||||||
source:
|
source:
|
||||||
type: idf
|
type: idf
|
||||||
version: 5.4.2
|
version: 5.4.2
|
||||||
direct_dependencies:
|
direct_dependencies:
|
||||||
- espressif/cmake_utilities
|
|
||||||
- espressif/esp32-camera
|
- espressif/esp32-camera
|
||||||
- espressif/led_strip
|
- espressif/led_strip
|
||||||
- espressif/mdns
|
- espressif/mdns
|
||||||
- espressif/tinyusb
|
|
||||||
- idf
|
- idf
|
||||||
manifest_hash: b8a462b847225cdc561c820962ae0cb021d5ff7d688964bd6786f78b99dfa205
|
manifest_hash: 84f1cf4d6bb76708581c603abbe49d3a107be6979a3546c1948ed5ac48316a9b
|
||||||
target: esp32s3
|
target: esp32
|
||||||
version: 2.0.0
|
version: 2.0.0
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
#ifdef CONFIG_FORMAT_MJPEG_CAM1
|
||||||
|
#define FORMAT_MJPEG_CAM1 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_UVC_CAM1_MULTI_FRAMESIZE
|
||||||
|
// If enable, add VGA and HVGA to list
|
||||||
|
#define UVC_CAM1_FRAME_MULTI 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define UVC_CAM1_FRAME_WIDTH CONFIG_UVC_CAM1_FRAMESIZE_WIDTH
|
||||||
|
#define UVC_CAM1_FRAME_HEIGHT CONFIG_UVC_CAM1_FRAMESIZE_HEIGT
|
||||||
|
#define UVC_CAM1_FRAME_RATE CONFIG_UVC_CAM1_FRAMERATE
|
||||||
|
|
||||||
|
#ifdef CONFIG_UVC_MODE_BULK_CAM1
|
||||||
|
#define UVC_CAM1_BULK_MODE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef UVC_CAM2_FRAME_WIDTH
|
||||||
|
#define UVC_CAM2_FRAME_WIDTH UVC_CAM1_FRAME_WIDTH
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef UVC_CAM2_FRAME_HEIGHT
|
||||||
|
#define UVC_CAM2_FRAME_HEIGHT UVC_CAM1_FRAME_HEIGHT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef UVC_CAM2_FRAME_RATE
|
||||||
|
#define UVC_CAM2_FRAME_RATE UVC_CAM1_FRAME_RATE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const struct
|
||||||
|
{
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int rate;
|
||||||
|
} UVC_FRAMES_INFO[][4] = {{
|
||||||
|
{UVC_CAM1_FRAME_WIDTH, UVC_CAM1_FRAME_HEIGHT, UVC_CAM1_FRAME_RATE},
|
||||||
|
{CONFIG_UVC_MULTI_FRAME_WIDTH_1, CONFIG_UVC_MULTI_FRAME_HEIGHT_1, CONFIG_UVC_MULTI_FRAME_FPS_1},
|
||||||
|
{CONFIG_UVC_MULTI_FRAME_WIDTH_2, CONFIG_UVC_MULTI_FRAME_HEIGHT_2, CONFIG_UVC_MULTI_FRAME_FPS_2},
|
||||||
|
{CONFIG_UVC_MULTI_FRAME_WIDTH_3, CONFIG_UVC_MULTI_FRAME_HEIGHT_3, CONFIG_UVC_MULTI_FRAME_FPS_3},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{UVC_CAM2_FRAME_WIDTH, UVC_CAM2_FRAME_HEIGHT, UVC_CAM2_FRAME_RATE},
|
||||||
|
{CONFIG_UVC_MULTI_FRAME_WIDTH_1, CONFIG_UVC_MULTI_FRAME_HEIGHT_1, CONFIG_UVC_MULTI_FRAME_FPS_1},
|
||||||
|
{CONFIG_UVC_MULTI_FRAME_WIDTH_2, CONFIG_UVC_MULTI_FRAME_HEIGHT_2, CONFIG_UVC_MULTI_FRAME_FPS_2},
|
||||||
|
{CONFIG_UVC_MULTI_FRAME_WIDTH_3, CONFIG_UVC_MULTI_FRAME_HEIGHT_3, CONFIG_UVC_MULTI_FRAME_FPS_3},
|
||||||
|
}};
|
||||||
|
|
||||||
|
#define UVC_FRAME_NUM (sizeof(UVC_FRAMES_INFO[0]) / sizeof(UVC_FRAMES_INFO[0][0]))
|
||||||
|
_Static_assert(UVC_FRAME_NUM == 4, "UVC_FRAME_NUM must be 4");
|
||||||
-99
@@ -20,11 +20,7 @@
|
|||||||
|
|
||||||
static const char *TAG = "usbd_uvc";
|
static const char *TAG = "usbd_uvc";
|
||||||
|
|
||||||
#if CONFIG_UVC_SUPPORT_TWO_CAM
|
|
||||||
#define UVC_CAM_NUM 2
|
|
||||||
#else
|
|
||||||
#define UVC_CAM_NUM 1
|
#define UVC_CAM_NUM 1
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -85,12 +81,6 @@ void tud_suspend_cb(bool remote_wakeup_en)
|
|||||||
{
|
{
|
||||||
s_uvc_device.user_config[0].stop_cb(s_uvc_device.user_config[0].cb_ctx);
|
s_uvc_device.user_config[0].stop_cb(s_uvc_device.user_config[0].cb_ctx);
|
||||||
}
|
}
|
||||||
#if CONFIG_UVC_SUPPORT_TWO_CAM
|
|
||||||
if (s_uvc_device.user_config[1].stop_cb)
|
|
||||||
{
|
|
||||||
s_uvc_device.user_config[1].stop_cb(s_uvc_device.user_config[1].cb_ctx);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
ESP_LOGI(TAG, "Suspend");
|
ESP_LOGI(TAG, "Suspend");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,82 +168,6 @@ static void video_task(void *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_UVC_SUPPORT_TWO_CAM
|
|
||||||
static void video_task2(void *arg)
|
|
||||||
{
|
|
||||||
uint32_t start_ms = 0;
|
|
||||||
uint32_t frame_num = 0;
|
|
||||||
uint32_t frame_len = 0;
|
|
||||||
uint32_t already_start = 0;
|
|
||||||
uint32_t tx_busy = 0;
|
|
||||||
uint8_t *uvc_buffer = s_uvc_device.user_config[1].uvc_buffer;
|
|
||||||
uint32_t uvc_buffer_size = s_uvc_device.user_config[1].uvc_buffer_size;
|
|
||||||
uvc_fb_t *pic = NULL;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
if (!tud_video_n_streaming(1, 0))
|
|
||||||
{
|
|
||||||
already_start = 0;
|
|
||||||
frame_num = 0;
|
|
||||||
tx_busy = 0;
|
|
||||||
vTaskDelay(1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!already_start)
|
|
||||||
{
|
|
||||||
already_start = 1;
|
|
||||||
start_ms = get_time_millis();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t cur = get_time_millis();
|
|
||||||
if (cur - start_ms < s_uvc_device.interval_ms[1])
|
|
||||||
{
|
|
||||||
vTaskDelay(1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tx_busy)
|
|
||||||
{
|
|
||||||
uint32_t xfer_done = ulTaskNotifyTake(pdTRUE, 1);
|
|
||||||
if (xfer_done == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
++frame_num;
|
|
||||||
tx_busy = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
start_ms += s_uvc_device.interval_ms[1];
|
|
||||||
ESP_LOGD(TAG, "frame %" PRIu32 " taking picture...", frame_num);
|
|
||||||
pic = s_uvc_device.user_config[1].fb_get_cb(s_uvc_device.user_config[1].cb_ctx);
|
|
||||||
if (pic)
|
|
||||||
{
|
|
||||||
ESP_LOGD(TAG, "Picture taken! Its size was: %zu bytes", pic->len);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ESP_LOGE(TAG, "Failed to capture picture");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pic->len > uvc_buffer_size)
|
|
||||||
{
|
|
||||||
ESP_LOGW(TAG, "frame size is too big, dropping frame");
|
|
||||||
s_uvc_device.user_config[1].fb_return_cb(pic, s_uvc_device.user_config[1].cb_ctx);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
frame_len = pic->len;
|
|
||||||
memcpy(uvc_buffer, pic->buf, frame_len);
|
|
||||||
s_uvc_device.user_config[1].fb_return_cb(pic, s_uvc_device.user_config[1].cb_ctx);
|
|
||||||
tx_busy = 1;
|
|
||||||
tud_video_n_frame_xfer(1, 0, (void *)uvc_buffer, frame_len);
|
|
||||||
ESP_LOGD(TAG, "frame %" PRIu32 " transfer start, size %" PRIu32, frame_num, frame_len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void tud_video_frame_xfer_complete_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx)
|
void tud_video_frame_xfer_complete_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx)
|
||||||
{
|
{
|
||||||
(void)ctl_idx;
|
(void)ctl_idx;
|
||||||
@@ -307,20 +221,11 @@ esp_err_t uvc_device_config(int index, uvc_device_config_t *config)
|
|||||||
esp_err_t uvc_device_init(void)
|
esp_err_t uvc_device_init(void)
|
||||||
{
|
{
|
||||||
ESP_RETURN_ON_FALSE(s_uvc_device.uvc_init[0], ESP_ERR_INVALID_STATE, TAG, "uvc device 0 not init");
|
ESP_RETURN_ON_FALSE(s_uvc_device.uvc_init[0], ESP_ERR_INVALID_STATE, TAG, "uvc device 0 not init");
|
||||||
#if CONFIG_UVC_SUPPORT_TWO_CAM
|
|
||||||
ESP_RETURN_ON_FALSE(s_uvc_device.uvc_init[1], ESP_ERR_INVALID_STATE, TAG, "uvc device 1 not init, if not use, please disable CONFIG_UVC_SUPPORT_TWO_CAM");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_FORMAT_MJPEG_CAM1
|
#ifdef CONFIG_FORMAT_MJPEG_CAM1
|
||||||
s_uvc_device.format[0] = UVC_FORMAT_JPEG;
|
s_uvc_device.format[0] = UVC_FORMAT_JPEG;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_UVC_SUPPORT_TWO_CAM
|
|
||||||
#ifdef CONFIG_FORMAT_MJPEG_CAM2
|
|
||||||
s_uvc_device.format[1] = UVC_FORMAT_JPEG;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// init device stack on configured roothub port
|
// init device stack on configured roothub port
|
||||||
usb_phy_init();
|
usb_phy_init();
|
||||||
bool usb_init = tusb_init();
|
bool usb_init = tusb_init();
|
||||||
@@ -335,10 +240,6 @@ esp_err_t uvc_device_init(void)
|
|||||||
#if (CFG_TUD_VIDEO)
|
#if (CFG_TUD_VIDEO)
|
||||||
core_id = (CONFIG_UVC_CAM1_TASK_CORE < 0) ? tskNO_AFFINITY : CONFIG_UVC_CAM1_TASK_CORE;
|
core_id = (CONFIG_UVC_CAM1_TASK_CORE < 0) ? tskNO_AFFINITY : CONFIG_UVC_CAM1_TASK_CORE;
|
||||||
xTaskCreatePinnedToCore(video_task, "UVC", 4096, NULL, CONFIG_UVC_CAM1_TASK_PRIORITY, &s_uvc_device.uvc_task_hdl[0], core_id);
|
xTaskCreatePinnedToCore(video_task, "UVC", 4096, NULL, CONFIG_UVC_CAM1_TASK_PRIORITY, &s_uvc_device.uvc_task_hdl[0], core_id);
|
||||||
#if CONFIG_UVC_SUPPORT_TWO_CAM
|
|
||||||
core_id = (CONFIG_UVC_CAM2_TASK_CORE < 0) ? tskNO_AFFINITY : CONFIG_UVC_CAM2_TASK_CORE;
|
|
||||||
xTaskCreatePinnedToCore(video_task2, "UVC2", 4096, NULL, CONFIG_UVC_CAM2_TASK_PRIORITY, &s_uvc_device.uvc_task_hdl[1], core_id);
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
ESP_LOGI(TAG, "UVC Device Start, Version: %d.%d.%d", USB_DEVICE_UVC_VER_MAJOR, USB_DEVICE_UVC_VER_MINOR, USB_DEVICE_UVC_VER_PATCH);
|
ESP_LOGI(TAG, "UVC Device Start, Version: %d.%d.%d", USB_DEVICE_UVC_VER_MAJOR, USB_DEVICE_UVC_VER_MINOR, USB_DEVICE_UVC_VER_PATCH);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
@@ -107,6 +107,16 @@ menu "OpenIris: WiFi Configuration"
|
|||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
|
menu "OpenIris: Serial Communication Settings"
|
||||||
|
config UART_PORT_NUMER
|
||||||
|
int "UART Port number"
|
||||||
|
default 1
|
||||||
|
range 1 4
|
||||||
|
help
|
||||||
|
The UART port to use for communication
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
|
||||||
menu "OpenIris: LED Configuration"
|
menu "OpenIris: LED Configuration"
|
||||||
|
|
||||||
config LED_DEBUG_ENABLE
|
config LED_DEBUG_ENABLE
|
||||||
|
|||||||
@@ -165,7 +165,6 @@ void startWiredMode(bool shouldCloseSerialManager)
|
|||||||
#ifndef CONFIG_GENERAL_INCLUDE_UVC_MODE
|
#ifndef CONFIG_GENERAL_INCLUDE_UVC_MODE
|
||||||
ESP_LOGE("[MAIN]", "UVC mode selected but the board likely does not support it.");
|
ESP_LOGE("[MAIN]", "UVC mode selected but the board likely does not support it.");
|
||||||
ESP_LOGI("[MAIN]", "Falling back to WiFi mode if credentials available");
|
ESP_LOGI("[MAIN]", "Falling back to WiFi mode if credentials available");
|
||||||
deviceMode = StreamingMode::WIFI;
|
|
||||||
startWiFiMode();
|
startWiFiMode();
|
||||||
#else
|
#else
|
||||||
ESP_LOGI("[MAIN]", "Starting UVC streaming mode.");
|
ESP_LOGI("[MAIN]", "Starting UVC streaming mode.");
|
||||||
|
|||||||
+2157
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user