#ifndef DRILL_MOTOR_FOC_H
#define DRILL_MOTOR_FOC_H

#include <stdbool.h>

/* This board candidate sets DRV8316 cycle-by-cycle current near 2 A. */
#define MFOC_BOARD_CURRENT_LIMIT_A 2.0f

typedef struct {
    float min_bus_voltage_v;
    float max_bus_voltage_v;
    float max_phase_current_a;
    float phase_sum_tolerance_a;
    float current_kp_v_per_a;
    float current_ki_v_per_a_s;
    float max_dt_s;
    float modulation_ceiling;
} mfoc_config;

typedef struct {
    float phase_a_current_a;
    float phase_b_current_a;
    float phase_c_current_a;
    float sin_electrical_angle;
    float cos_electrical_angle;
    float bus_voltage_v;
    float d_current_ref_a;
    float q_current_ref_a;
    float dt_s;
} mfoc_input;

typedef struct {
    bool valid;
    float d_current_a;
    float q_current_a;
    float d_voltage_v;
    float q_voltage_v;
    float alpha_voltage_v;
    float beta_voltage_v;
    float duty_a;
    float duty_b;
    float duty_c;
} mfoc_output;

typedef struct {
    mfoc_config cfg;
    float d_integral_v;
    float q_integral_v;
    bool initialized;
} mfoc_controller;

/*
 * Configure a host-testable FOC current-loop math candidate. The current limit
 * is intentionally capped at the present 2 A board candidate; it is not an
 * approved motor rating. Gains and voltage/current limits require bench tuning.
 */
bool mfoc_init(mfoc_controller *controller, const mfoc_config *config);

/*
 * Runs Clarke/Park, PI current control, inverse Park, and centered SVPWM.
 * sin/cos must come from a validated rotor observer or sensor. Samples must be
 * simultaneous and calibrated. A false output requires the caller to keep
 * DRV_RUN_REQ low and TIM1 MOE disabled; this module never grants run permission.
 */
mfoc_output mfoc_step(mfoc_controller *controller, const mfoc_input *input);

/* Clears both PI integrators. This is not a hardware gate-disable operation. */
void mfoc_reset(mfoc_controller *controller);

#endif
