Extends the bd-66hx serial protocol with two new Orin→ESP32 commands:
CMD_OTA_CHECK (0x10): triggers gitea_ota_check_now(), responds with
TELEM_VERSION_INFO (0x84) for Balance and IO (current + available ver).
CMD_OTA_UPDATE (0x11): uint8 target (0=balance, 1=io, 2=both) — triggers
uart_ota_trigger() for IO or ota_self_trigger() for Balance.
NACK with ERR_OTA_BUSY or ERR_OTA_NO_UPDATE on failure.
New telemetry: TELEM_OTA_STATUS (0x83, target+state+progress+err),
TELEM_VERSION_INFO (0x84, target+current[16]+available[16]).
Wires OTA stack into app_main: ota_self_health_check on boot,
gitea_ota_init + ota_display_init after peripherals ready.
CMakeLists updated with all OTA component dependencies.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
114 lines
4.1 KiB
C
114 lines
4.1 KiB
C
#pragma once
|
||
/* orin_serial.h — Orin↔ESP32-S3 BALANCE USB/UART serial protocol (bd-66hx)
|
||
*
|
||
* Frame layout (matches bd-wim1 esp32_balance_protocol.py exactly):
|
||
* [0xAA][LEN][TYPE][PAYLOAD × LEN bytes][CRC8-SMBUS]
|
||
* CRC covers LEN + TYPE + PAYLOAD bytes.
|
||
* All multi-byte payload fields are big-endian.
|
||
*
|
||
* Physical: UART0 → CH343 USB-serial → Orin /dev/esp32-balance @ 460800 baud
|
||
*/
|
||
|
||
#include <stdint.h>
|
||
#include <stdbool.h>
|
||
#include "freertos/FreeRTOS.h"
|
||
#include "freertos/queue.h"
|
||
|
||
/* ── Frame constants ── */
|
||
#define ORIN_SYNC 0xAAu
|
||
#define ORIN_MAX_PAYLOAD 62u
|
||
|
||
/* ── Command types: Orin → ESP32 ── */
|
||
#define CMD_HEARTBEAT 0x01u
|
||
#define CMD_DRIVE 0x02u /* int16 speed + int16 steer, BE */
|
||
#define CMD_ESTOP 0x03u /* uint8: 1=assert, 0=clear */
|
||
#define CMD_ARM 0x04u /* uint8: 1=arm, 0=disarm */
|
||
#define CMD_PID 0x05u /* float32 kp, ki, kd, BE */
|
||
|
||
/* ── Telemetry types: ESP32 → Orin ── */
|
||
#define TELEM_STATUS 0x80u /* status @ 10 Hz */
|
||
#define TELEM_VESC_LEFT 0x81u /* VESC ID 56 telemetry @ 10 Hz */
|
||
#define TELEM_VESC_RIGHT 0x82u /* VESC ID 68 telemetry @ 10 Hz */
|
||
#define TELEM_OTA_STATUS 0x83u /* OTA state + progress (bd-1s1s) */
|
||
#define TELEM_VERSION_INFO 0x84u /* firmware version report (bd-1s1s) */
|
||
#define RESP_ACK 0xA0u
|
||
#define RESP_NACK 0xA1u
|
||
|
||
/* ── OTA commands (Orin → ESP32, bd-1s1s) ── */
|
||
#define CMD_OTA_CHECK 0x10u /* no payload: trigger Gitea version check */
|
||
#define CMD_OTA_UPDATE 0x11u /* uint8 target: 0=balance, 1=io, 2=both */
|
||
|
||
/* ── OTA target constants ── */
|
||
#define OTA_TARGET_BALANCE 0x00u
|
||
#define OTA_TARGET_IO 0x01u
|
||
#define OTA_TARGET_BOTH 0x02u
|
||
|
||
/* ── NACK error codes ── */
|
||
#define ERR_BAD_CRC 0x01u
|
||
#define ERR_BAD_LEN 0x02u
|
||
#define ERR_ESTOP_ACTIVE 0x03u
|
||
#define ERR_DISARMED 0x04u
|
||
#define ERR_OTA_BUSY 0x05u
|
||
#define ERR_OTA_NO_UPDATE 0x06u
|
||
|
||
/* ── Balance state (mirrored from TELEM_STATUS.balance_state) ── */
|
||
typedef enum {
|
||
BAL_DISARMED = 0,
|
||
BAL_ARMED = 1,
|
||
BAL_TILT_FAULT = 2,
|
||
BAL_ESTOP = 3,
|
||
} bal_state_t;
|
||
|
||
/* ── Shared state written by RX task, consumed by main/vesc tasks ── */
|
||
typedef struct {
|
||
volatile int16_t speed; /* -1000..+1000 */
|
||
volatile int16_t steer; /* -1000..+1000 */
|
||
volatile uint32_t updated_ms; /* esp_timer tick at last CMD_DRIVE */
|
||
} orin_drive_t;
|
||
|
||
typedef struct {
|
||
volatile float kp, ki, kd;
|
||
volatile bool updated;
|
||
} orin_pid_t;
|
||
|
||
typedef struct {
|
||
volatile bool armed;
|
||
volatile bool estop;
|
||
volatile uint32_t hb_last_ms; /* esp_timer tick at last CMD_HEARTBEAT/CMD_DRIVE */
|
||
} orin_control_t;
|
||
|
||
/* ── TX frame queue item ── */
|
||
typedef struct {
|
||
uint8_t type;
|
||
uint8_t len;
|
||
uint8_t payload[ORIN_MAX_PAYLOAD];
|
||
} orin_tx_frame_t;
|
||
|
||
/* ── Globals (defined in orin_serial.c, extern here) ── */
|
||
extern orin_drive_t g_orin_drive;
|
||
extern orin_pid_t g_orin_pid;
|
||
extern orin_control_t g_orin_ctrl;
|
||
|
||
/* ── API ── */
|
||
void orin_serial_init(void);
|
||
|
||
/* Tasks — pass tx_queue as arg to both */
|
||
void orin_serial_rx_task(void *arg); /* arg = QueueHandle_t tx_queue */
|
||
void orin_serial_tx_task(void *arg); /* arg = QueueHandle_t tx_queue */
|
||
|
||
/* Enqueue outbound frames */
|
||
void orin_send_status(QueueHandle_t q,
|
||
int16_t pitch_x10, int16_t motor_cmd,
|
||
uint16_t vbat_mv, bal_state_t state, uint8_t flags);
|
||
void orin_send_vesc(QueueHandle_t q, uint8_t telem_type,
|
||
int32_t erpm, uint16_t voltage_mv,
|
||
int16_t current_ma, uint16_t temp_c_x10);
|
||
void orin_send_ack(QueueHandle_t q, uint8_t cmd_type);
|
||
void orin_send_nack(QueueHandle_t q, uint8_t cmd_type, uint8_t err);
|
||
|
||
/* OTA telemetry helpers (bd-1s1s) */
|
||
void orin_send_ota_status(QueueHandle_t q, uint8_t target,
|
||
uint8_t state, uint8_t progress, uint8_t err);
|
||
void orin_send_version_info(QueueHandle_t q, uint8_t target,
|
||
const char *current, const char *available);
|