#ifndef SERVO_BUS_H #define SERVO_BUS_H #include #include /* * servo_bus.h — Feetech/ST3215 serial bus servo driver (Issue #547) * * Half-duplex single-wire UART protocol at 1 Mbps. * Hardware: USART3 half-duplex on PB10 (USART3_TX, AF7). * No separate RX pin — the TX line is bidirectional with HDSEL. * * Packet format (host to servo): * [0xFF][0xFF][ID][LEN][INSTR][PARAMS...][CKSUM] * CKSUM = ~(ID + LEN + INSTR + PARAMS) & 0xFF * * Response (servo to host): * [0xFF][0xFF][ID][LEN][ERROR][DATA...][CKSUM] * * Key ST3215 registers: * 0x28 Torque Enable (1=on, 0=off) * 0x2A Goal Position L (0-4095) * 0x2B Goal Position H * 0x2E Moving Speed L (0=max, 1-4095) * 0x2F Moving Speed H * 0x38 Present Position L (0-4095) * 0x39 Present Position H * 0x3A Present Speed L (sign+magnitude: bit15=dir) * 0x3B Present Speed H * * Position encoding: 0-4095 maps to 0-360 degrees. * Center (180 deg) = 2048 raw. */ /* ST3215 register addresses */ #define SB_REG_TORQUE_EN 0x28u #define SB_REG_GOAL_POS_L 0x2Au #define SB_REG_MOVING_SPD_L 0x2Eu #define SB_REG_PRES_POS_L 0x38u #define SB_REG_PRES_SPD_L 0x3Au /* ST3215 instructions */ #define SB_INSTR_PING 0x01u #define SB_INSTR_READ 0x02u #define SB_INSTR_WRITE 0x03u /* Position encoding */ #define SB_POS_CENTER 2048u /* 180 deg */ #define SB_POS_MAX 4095u /* 360 deg */ #define SB_SPEED_MAX 4095u /* counts/sec (0 = max speed) */ /* Timeout for servo response (ms) */ #define SB_RX_TIMEOUT_MS 5u /* * servo_bus_init() - configure USART3 in half-duplex mode (PB10, AF7) at * SB_BAUD (1 Mbps, 8N1). Call once at startup before gimbal_init(). */ void servo_bus_init(void); /* * servo_bus_write_pos(id, raw_pos, speed) - write goal position and moving * speed in a single WRITE DATA packet. raw_pos: 0-4095. speed: 0=max, 1-4095. * Returns true on successful TX (no response expected on write). */ bool servo_bus_write_pos(uint8_t id, uint16_t raw_pos, uint16_t speed); /* * servo_bus_write_torque(id, enable) - enable or disable servo torque. */ bool servo_bus_write_torque(uint8_t id, bool enable); /* * servo_bus_read_pos(id, raw_pos) - read present position. * Returns true on success; raw_pos is 0-4095. */ bool servo_bus_read_pos(uint8_t id, uint16_t *raw_pos); /* * servo_bus_read_speed(id, speed) - read present speed. * speed bit 15 is direction. Returns magnitude in lower 15 bits. */ bool servo_bus_read_speed(uint8_t id, uint16_t *speed); /* * servo_bus_deg_to_raw(deg) - convert degree (-180..+180) to raw position. * Center (0 deg) = 2048. Clamps to 0-4095. */ uint16_t servo_bus_deg_to_raw(float deg); /* * servo_bus_raw_to_deg(raw) - convert raw position (0-4095) to degree (-180..+180). */ float servo_bus_raw_to_deg(uint16_t raw); #endif /* SERVO_BUS_H */