Add BLE host transport selectable via DIP8 alongside UART.
Master can speak the same framed protobuf protocol over NimBLE or UART; goTool gains -ble, ble-rtt, and ble-stream timing checks for ESP-NOW coexistence. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+12
-69
@@ -4,46 +4,28 @@
|
||||
#include "esp_log.h"
|
||||
#include "freertos/idf_additions.h"
|
||||
#include "hal/uart_types.h"
|
||||
#include "host_transport.h"
|
||||
#include "uart.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static const char *TAG = "[UART]";
|
||||
static QueueHandle_t uart_cmd_queue;
|
||||
|
||||
static bool uart_enqueue_packet(const uart_packet_t *packet) {
|
||||
if (packet->len == 0) {
|
||||
return false;
|
||||
static esp_err_t uart_host_tx(const uint8_t *frame, size_t frame_len) {
|
||||
int written = uart_write_bytes(UART_NUM, frame, frame_len);
|
||||
if (written < 0 || (size_t)written != frame_len) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
generic_msg_t msg = {
|
||||
.msg_id = packet->payload[0],
|
||||
.len = packet->len > 1 ? packet->len - 1 : 0,
|
||||
.payload = NULL,
|
||||
};
|
||||
|
||||
if (msg.len > 0) {
|
||||
msg.payload = malloc(msg.len);
|
||||
if (msg.payload == NULL) {
|
||||
ESP_LOGE(TAG, "failed to allocate command payload");
|
||||
return false;
|
||||
}
|
||||
memcpy(msg.payload, &packet->payload[1], msg.len);
|
||||
}
|
||||
|
||||
if (xQueueSend(uart_cmd_queue, &msg, pdMS_TO_TICKS(500)) != pdPASS) {
|
||||
free(msg.payload);
|
||||
ESP_LOGW(TAG, "command queue full (cmd 0x%02x)", (unsigned)msg.msg_id);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void init_uart(QueueHandle_t cmd_queue) {
|
||||
esp_err_t err;
|
||||
|
||||
uart_cmd_queue = cmd_queue;
|
||||
host_transport_set_cmd_queue(cmd_queue);
|
||||
host_transport_set_tx(uart_host_tx);
|
||||
|
||||
uart_config_t uart_config = {
|
||||
.baud_rate = UART_BAUD_RATE,
|
||||
.data_bits = UART_DATA_8_BITS,
|
||||
@@ -85,27 +67,10 @@ void uart_read_task(void *param) {
|
||||
return;
|
||||
}
|
||||
|
||||
int len = 0;
|
||||
uart_packet_t packet = {.state = STATE_START};
|
||||
TickType_t last_byte_time = xTaskGetTickCount();
|
||||
const TickType_t timeout_ticks = pdMS_TO_TICKS(50);
|
||||
|
||||
while (1) {
|
||||
len = uart_read_bytes(UART_NUM, data, UART_BUF_SIZE, pdMS_TO_TICKS(20));
|
||||
int len = uart_read_bytes(UART_NUM, data, UART_BUF_SIZE, pdMS_TO_TICKS(20));
|
||||
if (len > 0) {
|
||||
for (int i = 0; i < len; ++i) {
|
||||
if (parse_uart_byte(data[i], &packet)) {
|
||||
ESP_LOGI(TAG, "received message cmd=0x%02x len=%u",
|
||||
packet.len > 0 ? packet.payload[0] : 0, (unsigned)packet.len);
|
||||
uart_enqueue_packet(&packet);
|
||||
}
|
||||
}
|
||||
last_byte_time = xTaskGetTickCount();
|
||||
} else if (packet.state != STATE_START) {
|
||||
TickType_t now = xTaskGetTickCount();
|
||||
if ((now - last_byte_time) > timeout_ticks) {
|
||||
packet.state = STATE_START;
|
||||
}
|
||||
host_rx_bytes(data, (size_t)len);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -156,27 +121,5 @@ bool parse_uart_byte(uint8_t byte, uart_packet_t *p) {
|
||||
}
|
||||
|
||||
esp_err_t uart_send_framed(const uint8_t *payload, size_t len) {
|
||||
if (payload == NULL || len == 0 || len > MAX_PAYLOAD_SIZE) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
uint8_t checksum = 0;
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
checksum ^= payload[i];
|
||||
}
|
||||
|
||||
uint8_t frame[4 + MAX_PAYLOAD_SIZE];
|
||||
size_t pos = 0;
|
||||
frame[pos++] = START_MARKER;
|
||||
frame[pos++] = (uint8_t)len;
|
||||
memcpy(&frame[pos], payload, len);
|
||||
pos += len;
|
||||
frame[pos++] = checksum;
|
||||
frame[pos++] = STOP_MARKER;
|
||||
|
||||
int written = uart_write_bytes(UART_NUM, frame, pos);
|
||||
if (written < 0 || (size_t)written != pos) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return ESP_OK;
|
||||
return host_send_framed(payload, len);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user