// =============================================================================
//  rudder_sensor.h -- AI1 rudder-angle sensor with median filter
// =============================================================================
//
//  Reads the raw ADC value of the rudder position sensor (pot, Hall, or
//  4-20 mA loop conditioned to 0-3.3 V) on PIN_AI1_RUDDER_ANGLE, applies a
//  5-sample median filter to suppress single-sample spikes, and converts the
//  result to degrees via a linear calibration.
//
//  Calibration in Sprint 1 is a hard-coded placeholder (-35 deg @ 0 raw,
//  +35 deg @ 4095 raw). In Sprint 7 (commissioning), the calibration values
//  will come from the persistent NVS store written during sea trial.
//
//  The sensor task runs at 100 Hz on Core 1 (real-time core).
// =============================================================================

#pragma once

#include <cstdint>

namespace arautopilot::hal {

struct RudderReading {
    int16_t raw_adc;          ///< 0..4095, raw ADC after median filter
    float angle_deg;          ///< -35.0 .. +35.0 typical, after calibration
    uint32_t timestamp_ms;    ///< millis() at which the sample was taken
    bool valid;               ///< false until the filter has filled
};

/// Configure ADC1 channel for AI1, init the median filter.
void rudder_sensor_init();

/// Start the FreeRTOS sampling task (100 Hz, Core 1).
void rudder_sensor_start_task();

/// Get the latest filtered reading. Thread-safe (single critical section).
RudderReading rudder_sensor_latest();

/// Override the linear calibration. Called by the commissioning code
/// (Sprint 7); the placeholder is fine for Sprint 1 bench work.
///
///     raw_at_min_deg, raw_at_max_deg : ADC counts (0..4095)
///     min_deg, max_deg               : physical angle in degrees
void rudder_sensor_set_calibration(int16_t raw_at_min_deg, int16_t raw_at_max_deg,
                                   float min_deg, float max_deg);

}  // namespace arautopilot::hal
