Add FSESC 4.20 Plus hardware reference wiki page

Complete documentation of Flipsky Dual FSESC 4.20 Plus:
- Full STM32F405 pin mapping from hw_410.h
- All connectors and headers identified
- ADC, voltage/current sensing, NTC formulas
- Operating limits (firmware-enforced)
- BMI160 IMU wiring problem documented (UART != I2C)
- Pin conflict/multiplexing reference table
- CAN bus setup (CANable 2.0, python-can)
- VESC Tool access (VNC, vesc-cli.py)
- Current config state and lessons learned
Salty 2026-03-13 17:20:09 -04:00
parent 571c5ec4a3
commit b9be8cbebc

314
FSESC-4.20-Plus.md Normal file

@ -0,0 +1,314 @@
# FSESC 4.20 Plus — Hardware Reference
## Overview
| Parameter | Value |
|-----------|-------|
| **Model** | Flipsky Dual FSESC 4.20 Plus |
| **Hardware Version** | HW 410 (VESC 4.20) |
| **Firmware** | VESC FW 6.6 (vedderb/bldc) |
| **MCU** | STM32F405RGT6 (×2, one per ESC) |
| **Voltage Range** | 8V60V (313S LiPo) |
| **Current (per ESC)** | 50A continuous, 150A burst |
| **Current (dual total)** | 100A continuous, 300A burst |
| **BEC Output** | 5V @ 1.5A |
| **CAN Bus** | Between both ESCs (internal), external header |
| **Our CAN IDs** | 61 (USB-connected ESC), 79 (secondary) |
| **USB** | STM32 Virtual COM Port → `/dev/ttyACM1` on Orin |
| **Firmware source** | `hwconf/other/vesc4/hw_410.h` in vedderb/bldc |
## Role in SaltyLab
As of 2026-03-12, the VESC replaced the MAMBA F722S flight controller + hoverboard ESC entirely. The VESC now handles:
- **Motor control** — FOC for both hub motors
- **Balance PID** — via VESC balance app (internal)
- **CAN communication** — with Orin via CANable 2.0
Architecture: `Orin ↔ CAN ↔ VESC (balance + motors)`
## STM32F405 Pin Mapping (from hw_410.h)
### UART (USART6)
| Pin | GPIO | Function |
|-----|------|----------|
| TX | PC6 | USART6 TX |
| RX | PC7 | USART6 RX |
**Header:** "UART" / "Header 6" on PCB — the JST header labeled TX/RX.
**⚠️ This is NOT I2C.** UART and I2C are on completely different pins.
### I2C (I2C2) — External IMU
| Pin | GPIO | Function |
|-----|------|----------|
| SCL | PB10 | I2C2 SCL |
| SDA | PB11 | I2C2 SDA |
**⚠️ CRITICAL:** PB10/PB11 are **NOT** on the UART header. They share GPIO port B with hall sensor pins but are DIFFERENT pins (PB10/PB11 vs PB6/PB7).
**Note:** PB10/PB11 are also USART3 TX/RX (alternate function). On the original VESC 4.12 design, these go to the "COMM" header. On the Flipsky 4.20 Plus, **their physical location needs to be traced on the PCB** — they may be on the COMM port, an unpopulated header, or not broken out at all.
### Hall Sensor / Encoder
| Pin | GPIO | Function |
|-----|------|----------|
| H1 | PB6 | Hall sensor 1 / Encoder A |
| H2 | PB7 | Hall sensor 2 / Encoder B |
| H3 | PC11 | Hall sensor 3 / Encoder Z |
**Header:** 6-pin JST "HALL" / "SENSOR" connector (H1, H2, H3, 5V, Temp, GND).
**Note:** These are NOT the I2C pins despite being in port B.
### SPI (SPI1)
| Pin | GPIO | Function |
|-----|------|----------|
| NSS | PA4 | SPI1 NSS (chip select) |
| SCK | PA5 | SPI1 SCK |
| MISO | PA6 | SPI1 MISO |
| MOSI | PA7 | SPI1 MOSI |
Used for DRV8302/DRV8301 gate driver communication (internal, not user-accessible).
### PPM / Servo Input (ICU)
| Pin | GPIO | Function |
|-----|------|----------|
| PPM | PB5 | TIM3_CH2 — servo/PPM input capture |
**Header:** Combined with UART header on "Header 6" (typically: VCC, GND, PPM, RX, TX).
### LEDs
| Pin | GPIO | Function |
|-----|------|----------|
| Green | PC4 | Status LED (active high) |
| Red | PC5 | Fault LED (active high) |
### Control Signals
| Pin | GPIO | Function |
|-----|------|----------|
| Gate Enable | PC10 | DRV gate driver enable (active high) |
| DC Cal | PB12 | DC offset calibration |
| DRV Fault | PC12 | DRV fault detect (active low) |
### ADC Channels
| ADC Index | Channel | GPIO | Function |
|-----------|---------|------|----------|
| 0 | IN0 | PA0 | Phase C sense (SENS3) |
| 1 | IN1 | PA1 | Phase B sense (SENS2) |
| 2 | IN2 | PA2 | Phase A sense (SENS1) |
| 3 | IN8 | PB0 | Motor current 2 |
| 4 | IN9 | PB1 | Motor current 1 |
| 5 | IN3 | PA3 | MOSFET temperature (NTC) |
| 7 | IN6 | PA6 | ADC_EXT2 |
| 8 | IN12 | PC2 | Input voltage (Vin) |
| 10 | IN5 | PA5 | ADC_EXT |
| 11 | IN3 | PA3 | Motor temperature (NTC) |
### Voltage / Current Sensing
| Parameter | Value |
|-----------|-------|
| Vref | 3.3V |
| Vin divider R1 | 39kΩ |
| Vin divider R2 | 2.2kΩ |
| Vin ratio | 18.73:1 |
| Current shunt | 0.001Ω |
| Current amp gain | 10× |
| Max measurable Vin | ~57V |
Formula: `Vin = (ADC_raw / 4095) × 3.3V × (39000 + 2200) / 2200`
### NTC Temperature Sensing
- **FET thermistor:** 10kΩ NTC, β=3434, pullup to 3.3V
- **Motor thermistor:** 10kΩ NTC (low-side), β configurable
- Formula: `R = (4095 × 10000) / ADC_val - 10000``T = 1 / (ln(R/10000)/3434 + 1/298.15) - 273.15`
### Operating Limits (firmware-enforced)
| Limit | Min | Max |
|-------|-----|-----|
| Motor current | -100A | 100A |
| Battery current | -100A | 100A |
| Absolute current | 0A | 150A |
| Input voltage | 6V | 57V |
| ERPM | -200,000 | 200,000 |
| Duty min | 0% | 10% |
| Duty max | 0% | 95% |
| FET temp | -40°C | 110°C |
## Physical Connectors (Flipsky FSESC 4.20 Plus)
```
┌─────────────────────────────────────────────┐
│ FSESC 4.20 Plus (Top View) │
│ │
│ ┌──────┐ ┌──────┐ │
│ │ ESC 1│ │ ESC 2│ (each has own STM32) │
│ │CAN 61│ │CAN 79│ │
│ └──┬───┘ └──┬───┘ │
│ │ CAN bus │ │
│ └────┬─────┘ │
│ │ │
│ Headers (edge of board): │
│ ┌─────┐ ┌─────┐ ┌──────┐ ┌─────┐ ┌──────┐ │
│ │MOTOR│ │MOTOR│ │HALL×2│ │UART │ │BATT │ │
│ │ 1 │ │ 2 │ │ │ │+PPM │ │ XT60 │ │
│ └─────┘ └─────┘ └──────┘ └─────┘ └──────┘ │
│ │
│ Also: USB-C, CAN header, anti-spark switch │
└─────────────────────────────────────────────┘
```
### Connector List
| Connector | Type | Pins | Notes |
|-----------|------|------|-------|
| **Motor 1** | 3-phase | A, B, C | Thick gauge wires to hub motor |
| **Motor 2** | 3-phase | A, B, C | Thick gauge wires to hub motor |
| **Battery** | XT60 | +, | Main power input (with anti-spark) |
| **USB** | USB-C or Micro-B | Data + 5V | Config via VESC Tool |
| **HALL 1** | 6-pin JST | H1(PB6), H2(PB7), H3(PC11), 5V, Temp, GND | Motor 1 hall/encoder |
| **HALL 2** | 6-pin JST | Same pinout | Motor 2 hall/encoder |
| **UART/PPM** | JST | PPM(PB5), TX(PC6), RX(PC7), 5V, GND | **NOT I2C!** |
| **CAN** | 2-pin JST | CANH, CANL | External CAN bus (to CANable 2.0) |
| **COMM** | 4-pin JST (if present) | **Possibly PB10/PB11** | Needs PCB tracing — see I2C section |
## BMI160 IMU Wiring
### ❌ What DOESN'T Work
Wiring BMI160 to the **UART header** (TX=PC6, RX=PC7). These are USART6 pins — completely different GPIOs from the I2C2 peripheral (PB10/PB11). No amount of firmware config will make UART pins do I2C on this chip.
### ✅ What's Needed
BMI160 must connect to **PB10 (SCL) and PB11 (SDA)** — the I2C2 bus. Options:
1. **COMM header** — On original VESC 4.12, PB10/PB11 are brought out to a COMM connector. Flipsky may or may not have this. We tried "Header 11" which might be COMM — got zeros, but BMI160 chip may be dead or wrong orientation.
2. **Solder directly to STM32** — PB10 = pin 69, PB11 = pin 70 on LQFP64 package. Tiny but doable with fine solder and a magnifier.
3. **Run IMU from Orin instead** — Wire BMI160 to Orin GPIO I2C (Pin 3=SDA, Pin 5=SCL on J12 header), read IMU data on Orin, feed orientation to VESC over CAN. VESC balance app can accept external IMU data over CAN.
### BMI160 I2C Wiring (once correct pins found)
| BMI160 Pin | VESC Pin | Notes |
|------------|----------|-------|
| VCC/VIN | 3.3V or 5V | Breakout has onboard 3.3V regulator |
| GND | GND | Common ground |
| SCL | PB10 (I2C2 SCL) | **NOT PC6!** |
| SDA | PB11 (I2C2 SDA) | **NOT PC7!** |
| SA0/AD0 | GND | Sets I2C address to 0x68 (VESC default) |
### Diagnostic: Test BMI160 on Orin First
Before fighting with VESC pins, verify the chip is alive:
```bash
# Wire BMI160 to Orin J12: Pin 3 (SDA), Pin 5 (SCL), Pin 1 (3.3V), Pin 6 (GND)
sudo i2cdetect -y -r 1
# Should show 0x68 (or 0x69 if SA0 is high)
```
## VESC Tool Access
| Method | Details |
|--------|---------|
| **Direct USB** | Plug USB into laptop, open VESC Tool |
| **VNC on Orin** | `ssh seb@192.168.86.158`, VNC at `:5901` (pw: `vesc`) |
| **vesc-cli.py** | `/home/seb/vesc-cli.py` — status, scan, spin, stop, term, imu, balance |
| **VESC Tool path** | `/usr/local/bin/vesc_tool` (built from source, arm64 Qt5) |
### vesc-cli.py Quick Reference
```bash
# Status of USB-connected VESC
python3 vesc-cli.py status
# Scan CAN bus for all VESCs
python3 vesc-cli.py scan
# Spin motor at 5% duty for 2 seconds
python3 vesc-cli.py spin 5 -t 2
# Spin CAN-connected motor (ID 79)
python3 vesc-cli.py -c 79 spin 5 -t 2
# Stop motor
python3 vesc-cli.py stop
# Send terminal command
python3 vesc-cli.py term faults
# IMU info
python3 vesc-cli.py imu
```
## CAN Bus Setup (Orin ↔ VESC)
| Component | Details |
|-----------|---------|
| **Adapter** | CANable 2.0 (USB-to-CAN) |
| **Orin device** | `/dev/ttyACM0` |
| **Mode** | slcan (via python-can — kernel lacks gs_usb/slcan modules on Tegra) |
| **Bitrate** | 500kbps (VESC default) |
| **CAN IDs** | ESC 1 = 61, ESC 2 = 79 |
### python-can Usage
```python
import can
bus = can.Bus(interface='slcan', channel='/dev/ttyACM0', bitrate=500000)
for msg in bus:
print(f"ID: {msg.arbitration_id:#x} Data: {msg.data.hex()}")
```
## VESC Configuration (Current State)
| Setting | Value | Notes |
|---------|-------|-------|
| app_to_use | 1 (PPM) | Changed from 3 (PPM_UART) to free UART pins |
| IMU type | 4 (BMI160) | Set but not working — wrong wiring (see above) |
| permanent_uart | 1 | Stubbornly stays enabled — GUI change doesn't persist |
| Motor detection | Done | Via VESC Tool GUI (2026-03-12) |
| Battery voltage | 32.8V | Measured 2026-03-12 |
## Pin Conflict / Multiplexing Reference
This table clarifies which STM32F405 pins serve which function — the #1 source of wiring confusion:
| GPIO | Primary (HW 410) | Alternate Functions | Header |
|------|-------------------|---------------------|--------|
| PA0 | Phase C sense (ADC) | USART2_CTS, TIM2_CH1 | Internal |
| PA1 | Phase B sense (ADC) | USART2_RTS, TIM2_CH2 | Internal |
| PA2 | Phase A sense (ADC) | USART2_TX, TIM2_CH3 | Internal |
| PA3 | FET temp (ADC) | USART2_RX, TIM2_CH4 | Internal |
| PA4 | SPI1 NSS (DRV) | — | Internal |
| PA5 | SPI1 SCK (DRV) | ADC_EXT | Internal |
| PA6 | SPI1 MISO (DRV) | ADC_EXT2 | Internal |
| PA7 | SPI1 MOSI (DRV) | — | Internal |
| PB0 | Motor current 2 (ADC) | — | Internal |
| PB1 | Motor current 1 (ADC) | — | Internal |
| PB5 | PPM input (TIM3_CH2) | — | UART/PPM header |
| **PB6** | **Hall 1** | USART1_TX, TIM4_CH1 | **HALL header** |
| **PB7** | **Hall 2** | USART1_RX, TIM4_CH2 | **HALL header** |
| **PB10** | **I2C2 SCL** | USART3_TX, TIM2_CH3 | **COMM header?** |
| **PB11** | **I2C2 SDA** | USART3_RX, TIM2_CH4 | **COMM header?** |
| PB12 | DC calibration | — | Internal |
| PC2 | Vin sense (ADC) | — | Internal |
| PC4 | LED green | — | On-board |
| PC5 | LED red | — | On-board |
| **PC6** | **USART6 TX** | TIM3_CH1 | **UART header** |
| **PC7** | **USART6 RX** | TIM3_CH2 | **UART header** |
| PC10 | Gate enable | — | Internal |
| PC11 | Hall 3 | EXTI | HALL header |
| PC12 | DRV fault | — | Internal |
**Key takeaway:** PB10/PB11 (I2C/COMM) and PC6/PC7 (UART) are on completely different pins and headers. Connecting an I2C device to the UART header will never work on HW 410.
## Lessons Learned
1. **UART ≠ I2C on HW 410.** The UART header (PC6/PC7) and I2C bus (PB10/PB11) use completely different GPIO pins. Always check `hw_xxx.h` before wiring.
2. **VESC 4.x vs VESC 6+ differences.** On VESC 6+ boards, the COMM header often multiplexes TX/SCL and RX/SDA on the same pins. On VESC 4.x (HW 410), UART and I2C are physically separate peripherals on separate pins.
3. **Verify pin accessibility before buying peripherals.** We ordered the BMI160 for VESC use without confirming that PB10/PB11 are broken out on the Flipsky board.
4. **`permanent_uart_enabled` is persistent.** Changing it in VESC Tool GUI doesn't stick — may need terminal command or direct config binary write.
5. **Each ESC has its own STM32.** The dual board is two independent VESCs connected by CAN. Config changes to one don't affect the other.
## References
- **VESC firmware source:** [vedderb/bldc](https://github.com/vedderb/bldc) — `hwconf/other/vesc4/hw_410.h`
- **External IMU wiring (VESC 6):** [pev.dev/t/external-imu-wiring/294](https://pev.dev/t/external-imu-wiring/294)
- **BMI160 for VESC balance:** [spintend.com](https://spintend.com/products/bmi-160-module-for-diy-balanced-board-with-vesc)
- **VESC project:** [vesc-project.com](https://vesc-project.com)