Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/vedderb/bldc/llms.txt

Use this file to discover all available pages before exploring further.

The VESC firmware supports ten encoder driver families, each implemented as a standalone module under encoder/. All drivers expose at minimum an init, deinit, and angle-read function. The encoder core in encoder.c selects and wraps the active driver based on the motor configuration. The active driver is identified by the encoder_type_t enum defined in encoder_datatype.h:
typedef enum {
    ENCODER_TYPE_NONE = 0,
    ENCODER_TYPE_AS504x,
    ENCODER_TYPE_MT6816,
    ENCODER_TYPE_TLE5012,
    ENCODER_TYPE_AD2S1205_SPI,
    ENCODER_TYPE_SINCOS,
    ENCODER_TYPE_TS5700N8501,
    ENCODER_TYPE_ABI,
    ENCODER_TYPE_AS5x47U,
    ENCODER_TYPE_BISSC,
    ENCODER_TYPE_CUSTOM,
    ENCODER_TYPE_PWM,
    ENCODER_TYPE_PWM_ABI,
    ENCODER_TYPE_MA782,
} encoder_type_t;

ABI — enc_abi

ABI (A/B/Index) is the standard incremental quadrature encoder interface. Channels A and B produce 90°-offset square waves; counting transitions gives position. The optional Index (I) pulse fires once per revolution and is used to establish an absolute reference.
PropertyValue
InterfaceGPIO (hardware timer quadrature decode)
ResolutionConfigurable (counts per revolution)
AbsoluteNo — relative only until index pulse
encoder_type_tENCODER_TYPE_ABI, ENCODER_TYPE_PWM_ABI
Key state fields (ABI_state):
typedef struct {
    volatile bool     index_found;
    volatile uint32_t cnt_at_ind_last;
    volatile int      bad_pulses;
    volatile uint32_t index_pulse_cnt;
} ABI_state;
Call encoder_index_found() to check whether the firmware has seen the index pulse after power-on. FOC accuracy improves once the index is found.

AS504x — enc_as504x

The AS504x family (AS5040, AS5045, AS5047, AS5048) from ams-OSRAM are contactless magnetic rotary position sensors that communicate over SPI using a bit-bang software SPI (spi_bb).
PropertyValue
InterfaceSPI (software bit-bang)
ResolutionUp to 14-bit (AS5048)
AbsoluteYes — single-turn
encoder_type_tENCODER_TYPE_AS504x
Diagnostic fields (AS504x_diag):
typedef struct {
    uint8_t  is_connected;
    uint8_t  AGC_value;       // Automatic gain control
    uint16_t magnitude;       // Field magnitude
    uint8_t  is_OCF;          // Offset compensation finished
    uint8_t  is_COF;          // Cordic overflow — magnet too close/far
    uint8_t  is_Comp_low;     // AGC at maximum — magnet too far
    uint8_t  is_Comp_high;    // AGC at minimum — magnet too close
    ...
} AS504x_diag;
Monitor is_COF, is_Comp_low, and is_Comp_high to verify correct airgap between the sensor and the diametrically magnetised target magnet.

AS5x47U — enc_as5x47u

The AS5x47U family (e.g., AS5047U, AS5147U) are high-speed magnetic rotary encoders from ams-OSRAM with hardware SPI and an extended diagnostic register set.
PropertyValue
InterfaceSPI (hardware)
ResolutionUp to 14-bit
AbsoluteYes — single-turn
encoder_type_tENCODER_TYPE_AS5x47U
Diagnostic fields (AS5x47U_diag) include watchdog test status (is_wdtst), CRC error flag (is_crc_error), broken Hall flag (is_broken_hall), and field half-strength flag (is_mag_half), in addition to the same AGC and magnitude fields as the AS504x.

BiSS-C — enc_bissc

BiSS-C (Bidirectional Serial Synchronous Communication) is an open-standard serial interface for absolute encoders and other sensors. The firmware uses hardware SPI and a 6-bit CRC to validate each frame.
PropertyValue
InterfaceSPI (hardware)
ResolutionConfigurable (enc_res field)
AbsoluteYes — single or multi-turn depending on sensor
encoder_type_tENCODER_TYPE_BISSC
Key state fields (BISSC_state):
typedef struct {
    float    spi_data_error_rate;
    uint32_t spi_data_error_cnt;
    float    spi_comm_error_rate;
    uint32_t spi_comm_error_cnt;
    float    last_enc_angle;
    uint32_t spi_val;
    uint32_t last_update_time;
    uint8_t  decod_buf[8];
} BISSC_state;

MA782 — enc_ma782

The MagAlpha MA782 from Monolithic Power Systems is a high-speed contactless angle sensor with an SPI interface and an internal angle tracking register.
PropertyValue
InterfaceSPI (hardware)
Resolution8-bit to 16-bit depending on configuration
AbsoluteYes — single-turn
encoder_type_tENCODER_TYPE_MA782
The driver uses an asynchronous state machine (ma782_substate_t) with MA782_IDLE and MA782_READ_ANGLE_REQ states to pipeline SPI transfers with the FOC interrupt. Error flags (ma782_error_t):
typedef enum {
    MA782_CALLBACK_IN_IDLE   = 1 << 0,
    MA782_SPI_ERROR          = 1 << 1,
    MA782_READ_NOT_IDLE      = 1 << 2,
    MA782_SPI_NOT_READY      = 1 << 3,
    MA782_ANGLE_NOT_IDLE     = 1 << 4,
    MA782_UNKNOWN_STATE      = 1 << 5,
    MA782_WRITE_NOT_IDLE     = 1 << 6,
    MA782_WRITE_REG_FAIL     = 1 << 7,
    MA782_WRITE_READOUT_FAIL = 1 << 8,
} ma782_error_t;

MT6816 — enc_mt6816

The MT6816 from MagnTek is a 14-bit contactless magnetic angle sensor with hardware SPI and a no-magnet detection flag.
PropertyValue
InterfaceSPI (hardware)
Resolution14-bit
AbsoluteYes — single-turn
encoder_type_tENCODER_TYPE_MT6816
Key state fields (MT6816_state):
typedef struct {
    float    spi_error_rate;
    float    encoder_no_magnet_error_rate;
    uint32_t encoder_no_magnet_error_cnt;  // Magnet absent or too weak
    float    last_enc_angle;
    uint32_t spi_error_cnt;
    uint32_t spi_val;
    uint32_t last_update_time;
} MT6816_state;
Non-zero encoder_no_magnet_error_cnt indicates the target magnet is missing or the airgap is too large. Do not run FOC in this condition.

PWM — enc_pwm

Some encoder and position-sensor modules output angle as a PWM duty cycle (e.g., AS5600 in PWM mode). The enc_pwm driver captures the duty cycle using a timer input-capture peripheral and converts it to degrees.
PropertyValue
InterfacePWM input (hardware timer)
ResolutionDuty-cycle resolution of the source sensor
AbsoluteYes — single-turn (limited by PWM resolution)
encoder_type_tENCODER_TYPE_PWM, ENCODER_TYPE_PWM_ABI
The ENCODER_TYPE_PWM_ABI variant combines PWM absolute position with ABI quadrature for higher update rates.

SinCos — enc_sincos

Analogue sine/cosine encoders output two 90°-phase-shifted analogue signals. The firmware reads these on ADC channels, applies gain and offset calibration, and computes the angle with atan2.
PropertyValue
InterfaceAnalogue (ADC)
ResolutionDetermined by ADC resolution and signal quality
AbsoluteWithin one period — multi-pole pairs expand range
encoder_type_tENCODER_TYPE_SINCOS
Configuration (ENCSINCOS_config_t) exposes gain (s_gain, c_gain), offset (s_offset, c_offset), a low-pass filter_constant, and a phase_correction angle to compensate for mechanical misalignment between the sine and cosine tracks.

TLE5012 — enc_tle5012

The TLE5012B from Infineon is a magnetic angle sensor with a proprietary SSC (Synchronous Serial Communication) interface that is compatible with software SPI.
PropertyValue
InterfaceSSC / SPI (software bit-bang)
Resolution15-bit
AbsoluteYes — single-turn
encoder_type_tENCODER_TYPE_TLE5012
Error types (tle5012_errortypes):
typedef enum tle5012_errortypes {
    NO_ERROR               = 0x00,
    SYSTEM_ERROR           = 0x01,  // Over/under voltage, no magnet, ROM defect
    INTERFACE_ACCESS_ERROR = 0x02,  // Wrong address or lock
    INVALID_ANGLE_ERROR    = 0x04,  // GMR element failure
    ANGLE_SPEED_ERROR      = 0x08,  // Angular speed calculation error
    CRC_ERROR              = 0xFF,  // CRC mismatch
} tle5012_errortypes;

TS5700N8501 — enc_ts5700n8501

The TS5700N8501 from Tamagawa Seiki is a serial absolute encoder commonly found on industrial servo motors. It communicates over a UART-based serial interface and provides both single-turn and multi-turn (ABM) position.
PropertyValue
InterfaceUART (serial)
Resolution17-bit single-turn
AbsoluteYes — single-turn and multi-turn (ABM counter)
encoder_type_tENCODER_TYPE_TS5700N8501
The multi-turn counter is readable via enc_ts5700n8501_get_abm() and can be reset with enc_ts5700n8501_reset_multiturn().
// Read the 16-bit multi-turn (ABM) counter
int16_t abm = enc_ts5700n8501_get_abm(&cfg);

// Reset multi-turn counter
enc_ts5700n8501_reset_multiturn(&cfg);
The TS5700N8501 runs its communication in a dedicated ChibiOS thread due to the UART timing requirements. The raw 8-byte status frame is available at cfg.state.raw_status for advanced diagnostics.

Implementing a custom encoder

If none of the built-in drivers match your hardware, the encoder system supports a custom callback interface:
// encoder.h
void encoder_set_custom_callbacks(
    float  (*read_deg)(void),
    bool   (*has_fault)(void),
    char * (*print_info)(void)
);
Set encoder_type_t to ENCODER_TYPE_CUSTOM in the motor configuration and register your three callbacks. The FOC loop will call read_deg() on every current-control cycle.

Build docs developers (and LLMs) love