- Renamed mamba_protocol.py → balance_protocol.py; updated all importers - can_bridge_node.py rewritten to use balance_protocol.py API (ESP32-S3 BALANCE) - test_can_bridge.py rewritten to test actual balance_protocol.py constants/functions - All STM32/Mamba references in Python, YAML, Markdown, shell scripts replaced: * Hardware: MAMBA F722S → ESP32-S3 BALANCE/IO * Device paths: /dev/stm32-bridge → /dev/esp32-io * Node names: stm32_serial_bridge → esp32_io_serial_bridge * hardware_id: stm32f722 → esp32s3-balance/esp32s3-io - C/C++ src/include/lib/test files: added DEPRECATED header comment - Covers: saltybot_bridge, saltybot_can_bridge, saltybot_can_e2e_test, saltybot_bringup, saltybot_diagnostics, saltybot_mode_switch, and all chassis, docs, scripts, and project files Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
119 lines
4.8 KiB
C
119 lines
4.8 KiB
C
/* DEPRECATED: STM32/Mamba firmware -- replaced by ESP32-S3. Do not modify. */
|
||
#ifndef VESC_CAN_H
|
||
#define VESC_CAN_H
|
||
|
||
#include <stdint.h>
|
||
#include <stdbool.h>
|
||
|
||
/*
|
||
* vesc_can — VESC CAN protocol driver for FSESC 6.7 Pro Mini Dual (Issue #674).
|
||
*
|
||
* VESC uses 29-bit extended CAN IDs:
|
||
* arbitration_id = (packet_type << 8) | vesc_node_id
|
||
*
|
||
* Wire format is big-endian throughout (matches VESC FW 6.x).
|
||
*
|
||
* Physical layer: CAN2 on PB12 (RX, AF9) / PB13 (TX, AF9) at 500 kbps.
|
||
*
|
||
* NOTE ON PA11/PA12 vs PB12/PB13:
|
||
* PA11/PA12 carry CAN1_RX/TX (AF9) BUT are also USB_OTG_FS DM/DP (AF10).
|
||
* USB CDC is active on this board, so PA11/PA12 are occupied.
|
||
* PB8/PB9 (CAN1 alternate) are occupied by I2C1 (barometer).
|
||
* CAN2 on PB12/PB13 is the only conflict-free choice.
|
||
* If the SN65HVD230 is wired to the pads labelled RX6/TX6 on the Mamba
|
||
* silkscreen, those pads connect to PB12/PB13 (SPI2/OSD, repurposed).
|
||
*
|
||
* VESC frames arrive in FIFO1 (extended-ID filter, bank 15).
|
||
* Orin standard frames arrive in FIFO0 (standard-ID filter, bank 14).
|
||
*/
|
||
|
||
/* ---- VESC packet type IDs (upper byte of 29-bit arb ID) ---- */
|
||
#define VESC_PKT_SET_DUTY 0u /* int32 duty × 100000 */
|
||
#define VESC_PKT_SET_CURRENT 1u /* int32 current (mA) */
|
||
#define VESC_PKT_SET_CURRENT_BRAKE 2u /* int32 brake current (mA) */
|
||
#define VESC_PKT_SET_RPM 3u /* int32 target RPM */
|
||
#define VESC_PKT_STATUS 9u /* int32 RPM, int16 I×10, int16 duty×1000 */
|
||
#define VESC_PKT_STATUS_4 16u /* int16 T_fet×10, T_mot×10, I_in×10 */
|
||
#define VESC_PKT_STATUS_5 27u /* int32 tacho, int16 V_in×10 */
|
||
|
||
/* ---- Default VESC node IDs (configurable via vesc_can_init) ---- */
|
||
#define VESC_CAN_ID_LEFT 56u
|
||
#define VESC_CAN_ID_RIGHT 68u
|
||
|
||
/* ---- Alive timeout ---- */
|
||
#define VESC_ALIVE_TIMEOUT_MS 1000u /* node offline if no STATUS for 1 s */
|
||
|
||
/* ---- JLink telemetry rate ---- */
|
||
#define VESC_TLM_HZ 1u
|
||
|
||
/* ---- Fault codes (VESC FW 6.6) ---- */
|
||
#define VESC_FAULT_NONE 0u
|
||
#define VESC_FAULT_OVER_VOLTAGE 1u
|
||
#define VESC_FAULT_UNDER_VOLTAGE 2u
|
||
#define VESC_FAULT_DRV 3u
|
||
#define VESC_FAULT_ABS_OVER_CURRENT 4u
|
||
#define VESC_FAULT_OVER_TEMP_FET 5u
|
||
#define VESC_FAULT_OVER_TEMP_MOTOR 6u
|
||
#define VESC_FAULT_GATE_DRIVER_OVER_VOLTAGE 7u
|
||
#define VESC_FAULT_GATE_DRIVER_UNDER_VOLTAGE 8u
|
||
#define VESC_FAULT_MCU_UNDER_VOLTAGE 9u
|
||
#define VESC_FAULT_WATCHDOG_RESET 10u
|
||
|
||
/* ---- Telemetry state per VESC node ---- */
|
||
typedef struct {
|
||
int32_t rpm; /* actual RPM (STATUS pkt, int32 BE) */
|
||
int16_t current_x10; /* phase current (A × 10; STATUS pkt) */
|
||
int16_t duty_x1000; /* duty cycle (× 1000; –1000..+1000) */
|
||
int16_t temp_fet_x10; /* FET temperature (°C × 10; STATUS_4) */
|
||
int16_t temp_motor_x10; /* motor temperature (°C × 10; STATUS_4) */
|
||
int16_t current_in_x10; /* input (battery) current (A × 10; STATUS_4) */
|
||
int16_t voltage_x10; /* input voltage (V × 10; STATUS_5) */
|
||
uint8_t fault_code; /* VESC fault code (0 = none) */
|
||
uint8_t _pad;
|
||
uint32_t last_rx_ms; /* HAL_GetTick() of last received STATUS frame */
|
||
} vesc_state_t;
|
||
|
||
/* ---- API ---- */
|
||
|
||
/*
|
||
* vesc_can_init(id_left, id_right) — store VESC node IDs and register the
|
||
* extended-frame callback with can_driver.
|
||
* Call after can_driver_init().
|
||
*/
|
||
void vesc_can_init(uint8_t id_left, uint8_t id_right);
|
||
|
||
/*
|
||
* vesc_can_send_rpm(vesc_id, rpm) — transmit VESC_PKT_SET_RPM (3) to the
|
||
* target VESC. arb_id = (3 << 8) | vesc_id. Payload: int32 big-endian.
|
||
*/
|
||
void vesc_can_send_rpm(uint8_t vesc_id, int32_t rpm);
|
||
|
||
/*
|
||
* vesc_can_on_frame(ext_id, data, len) — called by can_driver when an
|
||
* extended-ID frame arrives (registered via can_driver_set_ext_cb).
|
||
* Parses STATUS / STATUS_4 / STATUS_5 into the matching vesc_state_t.
|
||
*/
|
||
void vesc_can_on_frame(uint32_t ext_id, const uint8_t *data, uint8_t len);
|
||
|
||
/*
|
||
* vesc_can_get_state(vesc_id, out) — copy latest telemetry snapshot.
|
||
* vesc_id must match id_left or id_right passed to vesc_can_init.
|
||
* Returns false if vesc_id unknown or no frame has arrived yet.
|
||
*/
|
||
bool vesc_can_get_state(uint8_t vesc_id, vesc_state_t *out);
|
||
|
||
/*
|
||
* vesc_can_is_alive(vesc_id, now_ms) — true if a STATUS frame arrived
|
||
* within VESC_ALIVE_TIMEOUT_MS of now_ms.
|
||
*/
|
||
bool vesc_can_is_alive(uint8_t vesc_id, uint32_t now_ms);
|
||
|
||
/*
|
||
* vesc_can_send_tlm(now_ms) — rate-limited JLINK_TLM_VESC_STATE (0x8E)
|
||
* telemetry to Orin over JLink. Safe to call every ms; internally
|
||
* rate-limited to VESC_TLM_HZ (1 Hz).
|
||
*/
|
||
void vesc_can_send_tlm(uint32_t now_ms);
|
||
|
||
#endif /* VESC_CAN_H */
|