sl-firmware 1f88835fac diag: VESC PING/PONG + CAN bus activity flags in STATUS telemetry
Add active VESC probing so the Orin binary protocol reports CAN RX health:

- vesc_can_ping(): sends CAN_PACKET_PING (17) to each VESC at startup
- vesc_can_rx_task: handles CAN_PACKET_PONG (18) → sets g_vesc_alive[i]
- g_can_bus_active: set on any extended CAN frame received
- STATUS flags now include bit4=can_bus_active, bit5=vesc_a_alive, bit6=vesc_b_alive
- Test script decodes and reports twai_state, can_bus_active, vesc_a/b_alive
- Fix cosmetic: VESC IDs 56=LEFT 68=RIGHT (was wrong 61/79 in print line)

Confirmed diagnostic: can_bus_active=False — VESCs ACK SET_RPM commands
(TWAI stays RUNNING) but broadcast zero data frames. Root cause: VESC
CAN Status Message Mode is Disabled. Fix: set mode ≥ 1 in VESC Tool.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 13:21:57 -04:00

44 lines
1.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
/* vesc_can.h — VESC CAN TWAI driver for ESP32-S3 BALANCE (bd-66hx)
*
* VESC extended CAN ID: (packet_type << 8) | vesc_node_id
* Physical layer: TWAI peripheral → SN65HVD230 → 500 kbps shared bus
*/
#include <stdint.h>
#include <stdbool.h>
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
/* ── VESC packet types ── */
#define VESC_PKT_SET_RPM 3u
#define VESC_PKT_STATUS 9u /* int32 erpm, int16 I×10, int16 duty×1000 */
#define VESC_PKT_PING 17u /* CAN_PACKET_PING: data[0]=requester_id */
#define VESC_PKT_PONG 18u /* CAN_PACKET_PONG: data[0]=vesc_id, data[1]=hw */
#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 */
#define VESC_CAN_ID_SELF 1u /* our ESP32 CAN node ID (for PING replies) */
/* ── VESC telemetry snapshot ── */
typedef struct {
int32_t erpm; /* electrical RPM (STATUS) */
int16_t current_x10; /* phase current A×10 (STATUS) */
int16_t voltage_x10; /* bus voltage V×10 (STATUS_5) */
int16_t temp_mot_x10; /* motor temp °C×10 (STATUS_4) */
uint32_t last_rx_ms; /* esp_timer ms of last STATUS frame */
} vesc_state_t;
/* ── Globals ── */
extern vesc_state_t g_vesc[2]; /* index 0=VESC_ID_A, 1=VESC_ID_B */
extern volatile bool g_can_bus_active; /* true after any extended CAN frame received */
extern volatile bool g_vesc_alive[2]; /* true after PONG from each VESC */
/* ── API ── */
void vesc_can_init(void);
void vesc_can_send_rpm(uint8_t vesc_id, int32_t erpm);
void vesc_can_ping(uint8_t vesc_id);
/* RX task — pass tx_queue as arg; forwards STATUS frames to Orin over serial */
void vesc_can_rx_task(void *arg); /* arg = QueueHandle_t orin_tx_queue */