mirror of
https://github.com/MrUnknownDE/OpenIris-ESPIDF.git
synced 2026-04-15 20:43:45 +02:00
Initial CDC implementation
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#include "SerialManager.hpp"
|
||||
#include "esp_log.h"
|
||||
#include "main_globals.hpp"
|
||||
#include "tusb.h"
|
||||
|
||||
#define BUF_SIZE (1024)
|
||||
|
||||
@@ -65,10 +66,10 @@ void SerialManager::try_receive()
|
||||
// Notify main that a command was received during startup
|
||||
notify_startup_command_received();
|
||||
|
||||
const auto result = this->commandManager->executeFromJson(std::string_view(reinterpret_cast<const char *>(this->data)));
|
||||
const auto resultMessage = result.getResult();
|
||||
int written = usb_serial_jtag_write_bytes(resultMessage.c_str(), resultMessage.length(), 1000 / 20);
|
||||
(void)written; // ignore errors if driver already uninstalled
|
||||
const auto result = this->commandManager->executeFromJson(std::string_view(reinterpret_cast<const char *>(this->data)));
|
||||
const auto resultMessage = result.getResult();
|
||||
int written = usb_serial_jtag_write_bytes(resultMessage.c_str(), resultMessage.length(), 1000 / 20);
|
||||
(void)written; // ignore errors if driver already uninstalled
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,6 +128,22 @@ bool SerialManager::should_send_heartbeat()
|
||||
return wifiConfigs.empty();
|
||||
}
|
||||
|
||||
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
|
||||
void HandleSerialManagerTask(void *pvParameters)
|
||||
{
|
||||
auto const serialManager = static_cast<SerialManager *>(pvParameters);
|
||||
@@ -150,17 +167,71 @@ void HandleSerialManagerTask(void *pvParameters)
|
||||
}
|
||||
}
|
||||
|
||||
void SerialManager::shutdown()
|
||||
void HandleCDCSerialManagerTask(void *pvParameters)
|
||||
{
|
||||
// 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)
|
||||
auto const commandManager = static_cast<CommandManager *>(pvParameters);
|
||||
static char buffer[BUF_SIZE];
|
||||
auto idx = 0;
|
||||
|
||||
cdc_command_packet_t packet;
|
||||
while (true)
|
||||
{
|
||||
ESP_LOGI("[SERIAL]", "usb_serial_jtag driver uninstalled");
|
||||
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 auto result = commandManager->executeFromJson(std::string_view(reinterpret_cast<const char *>(buffer)));
|
||||
const auto resultMessage = result.getResult();
|
||||
tud_cdc_write(resultMessage.c_str(), resultMessage.length());
|
||||
tud_cdc_write_flush();
|
||||
idx = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (err != ESP_ERR_INVALID_STATE)
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
ESP_LOGW("[SERIAL]", "usb_serial_jtag_driver_uninstall returned %s", esp_err_to_name(err));
|
||||
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);
|
||||
}
|
||||
@@ -18,6 +18,17 @@
|
||||
#include "esp_vfs_dev.h"
|
||||
#include "esp_mac.h"
|
||||
|
||||
void tud_cdc_rx_cb(uint8_t itf);
|
||||
void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts);
|
||||
|
||||
extern QueueHandle_t cdcMessageQueue;
|
||||
|
||||
struct cdc_command_packet_t
|
||||
{
|
||||
uint8_t len;
|
||||
uint8_t data[64];
|
||||
};
|
||||
|
||||
class SerialManager
|
||||
{
|
||||
public:
|
||||
@@ -38,4 +49,5 @@ private:
|
||||
};
|
||||
|
||||
void HandleSerialManagerTask(void *pvParameters);
|
||||
void HandleCDCSerialManagerTask(void *pvParameters)
|
||||
#endif
|
||||
Reference in New Issue
Block a user