sl-firmware 36643dd652 feat: Pan/tilt gimbal servo driver for ST3215 bus servos (Issue #547)
- servo_bus.c/h: half-duplex USART3 driver for Feetech ST3215 servos at
  1 Mbps; blocking TX/RX with CRC checksum; read/write position, torque
  enable, speed; deg<->raw conversion (center=2048, 4096 counts/360°)
- gimbal.c/h: gimbal_t controller; 50 Hz feedback poll alternating pan/tilt
  at 25 Hz each; clamps to ±GIMBAL_PAN/TILT_LIMIT_DEG soft limits
- jlink.c: dispatch JLINK_CMD_GIMBAL_POS (0x0B, 6-byte payload int16+int16+
  uint16); jlink_send_gimbal_state() for JLINK_TLM_GIMBAL_STATE (0x84)
- main.c: servo_bus_init() + gimbal_init() on boot; gimbal_tick() in main
  loop; gimbal_updated flag handler; GIMBAL_STATE telemetry at 50 Hz
- config.h: SERVO_BUS_UART/PORT/PIN/BAUD, GIMBAL_PAN/TILT_ID, GIMBAL_TLM_HZ,
  GIMBAL_PAN/TILT_LIMIT_DEG
- jlink.h: CMD_GIMBAL_POS, TLM_GIMBAL_STATE, jlink_tlm_gimbal_state_t (10 B),
  gimbal_updated/pan_x10/tilt_x10/speed volatile fields in JLinkState

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 10:38:06 -04:00

73 lines
2.4 KiB
C
Raw Permalink 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.

#ifndef GIMBAL_H
#define GIMBAL_H
#include <stdint.h>
#include <stdbool.h>
/*
* gimbal.h — Pan/tilt gimbal controller for ST3215 bus servos (Issue #547)
*
* Manages dual ST3215 serial bus servos:
* Pan servo: ID GIMBAL_PAN_ID (config.h, default 1)
* Tilt servo: ID GIMBAL_TILT_ID (config.h, default 2)
*
* Position units: degrees x10 (int16), matching JLink protocol convention.
* e.g. 900 = 90.0°, -450 = -45.0°
*
* Limits:
* Pan: -1800..+1800 (x10 deg) = -180..+180 deg
* Tilt: -900..+900 (x10 deg) = -90..+90 deg
*
* The gimbal_tick() function polls servo feedback at GIMBAL_TLM_HZ (50 Hz).
* Alternates reading pan position on even ticks, tilt on odd ticks — each
* servo polled at 25 Hz to keep bus utilization low.
*/
typedef struct {
/* Command state */
int16_t cmd_pan_x10; /* Commanded pan (deg x10) */
int16_t cmd_tilt_x10; /* Commanded tilt (deg x10) */
uint16_t cmd_speed; /* Servo bus speed (0=max, 1-4095) */
bool torque_enabled; /* True when torques are enabled */
/* Feedback state (updated at ~25 Hz per axis) */
int16_t fb_pan_x10; /* Measured pan (deg x10) */
int16_t fb_tilt_x10; /* Measured tilt (deg x10) */
uint16_t fb_pan_speed; /* Raw speed register, pan servo */
uint16_t fb_tilt_speed; /* Raw speed register, tilt servo */
/* Diagnostics */
uint32_t rx_ok; /* Successful position reads */
uint32_t rx_err; /* Failed position reads */
uint32_t _last_tick_ms; /* Internal: last tick timestamp */
uint8_t _poll_phase; /* Internal: alternates 0=pan 1=tilt */
} gimbal_t;
/*
* gimbal_init(g) — enable torque on both servos, center them.
* servo_bus_init() must be called first.
*/
void gimbal_init(gimbal_t *g);
/*
* gimbal_set_pos(g, pan_x10, tilt_x10, speed) — command a new pan/tilt
* position. pan_x10 and tilt_x10 are degrees×10, clamped to servo limits.
* speed: 0=max servo speed, 1-4095 = scaled.
*/
void gimbal_set_pos(gimbal_t *g, int16_t pan_x10, int16_t tilt_x10,
uint16_t speed);
/*
* gimbal_torque(g, enable) — enable or disable torque on both servos.
*/
void gimbal_torque(gimbal_t *g, bool enable);
/*
* gimbal_tick(g, now_ms) — poll servo feedback at GIMBAL_TLM_HZ.
* Call every 1 ms from the main loop; function self-throttles.
*/
void gimbal_tick(gimbal_t *g, uint32_t now_ms);
#endif /* GIMBAL_H */