// =============================================================================
//  hal/knob_encoder.h -- Rotary encoder for heading knob (Sprint 7)
// =============================================================================
//
//  A quadrature rotary encoder connected to GPIO pins drives heading setpoint
//  changes. Clockwise rotation increases the setpoint by STEP_DEG per detent;
//  counter-clockwise decreases it.
//
//  The encoder is only active when the pilot is engaged (any mode other than
//  STANDBY). While disengaged, pulses are silently discarded.
//
//  The "knob arm" coil (COIL_CMD_KNOB_ARM via Modbus, addr 3) enables the
//  knob for one KNOB_ARM_TIMEOUT_MS window. If no edge arrives within that
//  window, the coil auto-clears.  This prevents unintended heading changes
//  from vibration noise.
//
//  GPIO assignment (not on AR-NMEA-IO v1.0 main header -- uses DO6/DO7 pads
//  repurposed as inputs in the commissioning firmware variant):
//    PIN_KNOB_A = PIN_DO6_RESERVED (GPIO 16)
//    PIN_KNOB_B = PIN_DO7_RESERVED (GPIO 17)
//
//  The interrupt handler uses a 4-state Gray-code decode table for noise
//  immunity.
// =============================================================================

#pragma once

#include <cstdint>

namespace arautopilot::hal {

constexpr float KNOB_STEP_DEG       = 1.0f;    ///< heading change per detent
constexpr uint32_t KNOB_ARM_TIMEOUT_MS = 5000; ///< arm window before auto-disarm

/// Initialise encoder GPIO and attach interrupts.
/// Must be called from setup() after do_init().
void knob_encoder_init();

/// Start the knob processing task (low priority, Core 0).
void knob_encoder_start_task();

/// Set the armed state.  While armed the knob updates the heading setpoint.
/// The coil write handler calls this.
void knob_encoder_set_armed(bool armed);

/// Return current armed state.
bool knob_encoder_is_armed();

}  // namespace arautopilot::hal
