harden USB telemetry transport
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
#include "trikke_usb_transport.h"
|
||||
|
||||
#include "driver/usb_serial_jtag.h"
|
||||
#include "driver/usb_serial_jtag_vfs.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
#define TRIKKE_USB_TX_BUFFER_SIZE 512
|
||||
#define TRIKKE_USB_RX_BUFFER_SIZE 128
|
||||
#define TRIKKE_USB_OPERATION_TIMEOUT_MS 50
|
||||
|
||||
static trikke_transport_status_t usb_begin_packet(
|
||||
void *context,
|
||||
const uint8_t *packet,
|
||||
size_t packet_size)
|
||||
{
|
||||
const trikke_usb_transport_t *usb = context;
|
||||
if (usb == NULL || !usb->initialized || packet == NULL || packet_size == 0 ||
|
||||
packet_size > TRIKKE_USB_TX_BUFFER_SIZE) {
|
||||
return TRIKKE_TRANSPORT_FATAL;
|
||||
}
|
||||
|
||||
const int written = usb_serial_jtag_write_bytes(
|
||||
packet, packet_size,
|
||||
pdMS_TO_TICKS(TRIKKE_USB_OPERATION_TIMEOUT_MS));
|
||||
if (written == (int)packet_size) {
|
||||
return TRIKKE_TRANSPORT_PENDING;
|
||||
}
|
||||
if (written == 0) {
|
||||
return TRIKKE_TRANSPORT_RETRY;
|
||||
}
|
||||
return TRIKKE_TRANSPORT_FATAL;
|
||||
}
|
||||
|
||||
static trikke_transport_status_t usb_poll_packet(void *context)
|
||||
{
|
||||
const trikke_usb_transport_t *usb = context;
|
||||
if (usb == NULL || !usb->initialized) {
|
||||
return TRIKKE_TRANSPORT_FATAL;
|
||||
}
|
||||
|
||||
const esp_err_t err = usb_serial_jtag_wait_tx_done(
|
||||
pdMS_TO_TICKS(TRIKKE_USB_OPERATION_TIMEOUT_MS));
|
||||
if (err == ESP_OK) {
|
||||
return TRIKKE_TRANSPORT_COMPLETE;
|
||||
}
|
||||
if (err == ESP_ERR_TIMEOUT) {
|
||||
return TRIKKE_TRANSPORT_PENDING;
|
||||
}
|
||||
return TRIKKE_TRANSPORT_FATAL;
|
||||
}
|
||||
|
||||
esp_err_t trikke_usb_transport_init(
|
||||
trikke_usb_transport_t *usb,
|
||||
trikke_transport_t *transport)
|
||||
{
|
||||
if (usb == NULL || transport == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (usb->initialized) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
usb_serial_jtag_driver_config_t config = {
|
||||
.tx_buffer_size = TRIKKE_USB_TX_BUFFER_SIZE,
|
||||
.rx_buffer_size = TRIKKE_USB_RX_BUFFER_SIZE,
|
||||
};
|
||||
const esp_err_t err = usb_serial_jtag_driver_install(&config);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
usb->initialized = true;
|
||||
transport->context = usb;
|
||||
transport->begin = usb_begin_packet;
|
||||
transport->poll = usb_poll_packet;
|
||||
|
||||
// Route any unexpected VFS output through the installed driver as well, so
|
||||
// it cannot race the driver's ISR by touching the hardware FIFO directly.
|
||||
usb_serial_jtag_vfs_use_driver();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void trikke_usb_transport_deinit(trikke_usb_transport_t *usb)
|
||||
{
|
||||
if (usb == NULL || !usb->initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
usb_serial_jtag_vfs_use_nonblocking();
|
||||
usb_serial_jtag_driver_uninstall();
|
||||
usb->initialized = false;
|
||||
}
|
||||
Reference in New Issue
Block a user