--- A96/drill_smo.c
+++ A97/drill_smo.c
@@ -140,6 +140,9 @@
         !finite_value(c->lock_phase_error_rad) || c->lock_phase_error_rad <= 0.0f ||
         c->lock_phase_error_rad >= DS_HALF_PI || c->pole_pairs == 0u ||
         c->pole_pairs > 32u || c->lock_samples < 4u) return false;
+    /* A full declared speed range must remain below the angle alias limit.
+     * This necessary condition does not establish practical tracking margin. */
+    if (c->max_mechanical_rpm*(float)c->pole_pairs*c->max_dt_s >= 30.0f) return false;
     return true;
 }
 
@@ -161,6 +164,9 @@
     s->estimated_bemf_beta_v = 0.0f;
     s->electrical_angle_rad = 0.0f;
     s->electrical_speed_rad_s = 0.0f;
+    s->previous_raw_angle_rad = 0.0f;
+    s->acquisition_speed_rad_s = 0.0f;
+    s->acquisition_samples = 0u;
     s->lock_count = 0u;
     s->unlock_count = 0u;
     s->initialized = false;
@@ -219,21 +225,26 @@
         return false;
     }
     const drill_smo_config *c = &s->config;
-    const float inj_a = sliding_injection(s->estimated_current_alpha_a -
-                                         i->current_alpha_a,
-                                         c->current_error_sat_a,
-                                         c->sliding_gain_v);
-    const float inj_b = sliding_injection(s->estimated_current_beta_a -
-                                         i->current_beta_a,
-                                         c->current_error_sat_a,
-                                         c->sliding_gain_v);
-    const float inv_l = 1.0f / c->phase_inductance_h;
-    s->estimated_current_alpha_a += i->dt_s * inv_l *
-        (i->voltage_alpha_v - c->phase_resistance_ohm *
-         s->estimated_current_alpha_a - inj_a);
-    s->estimated_current_beta_a += i->dt_s * inv_l *
-        (i->voltage_beta_v - c->phase_resistance_ohm *
-         s->estimated_current_beta_a - inj_b);
+    /* Solve backward Euler with piecewise-linear sliding injection exactly.
+     * This consumes one real input pair; no synthetic sub-samples. */
+    const float h = i->dt_s / c->phase_inductance_h;
+    const float gain_slope = c->sliding_gain_v / c->current_error_sat_a;
+    const float denominator = 1.0f + h*c->phase_resistance_ohm;
+    const float linear_denominator = denominator + h*gain_slope;
+    float next_a = (s->estimated_current_alpha_a + h*(i->voltage_alpha_v + gain_slope*i->current_alpha_a))/linear_denominator;
+    float next_b = (s->estimated_current_beta_a + h*(i->voltage_beta_v + gain_slope*i->current_beta_a))/linear_denominator;
+    if (next_a-i->current_alpha_a > c->current_error_sat_a)
+        next_a = (s->estimated_current_alpha_a + h*(i->voltage_alpha_v-c->sliding_gain_v))/denominator;
+    else if (next_a-i->current_alpha_a < -c->current_error_sat_a)
+        next_a = (s->estimated_current_alpha_a + h*(i->voltage_alpha_v+c->sliding_gain_v))/denominator;
+    if (next_b-i->current_beta_a > c->current_error_sat_a)
+        next_b = (s->estimated_current_beta_a + h*(i->voltage_beta_v-c->sliding_gain_v))/denominator;
+    else if (next_b-i->current_beta_a < -c->current_error_sat_a)
+        next_b = (s->estimated_current_beta_a + h*(i->voltage_beta_v+c->sliding_gain_v))/denominator;
+    const float inj_a = sliding_injection(next_a-i->current_alpha_a,c->current_error_sat_a,c->sliding_gain_v);
+    const float inj_b = sliding_injection(next_b-i->current_beta_a,c->current_error_sat_a,c->sliding_gain_v);
+    s->estimated_current_alpha_a = next_a;
+    s->estimated_current_beta_a = next_b;
     if (!finite_value(s->estimated_current_alpha_a) ||
         !finite_value(s->estimated_current_beta_a) ||
         absf_local(s->estimated_current_alpha_a) > 2.0f*c->max_phase_current_a ||
@@ -257,6 +268,8 @@
         s->unlock_count = 0u;
         s->observer_locked = false;
         s->angle_valid = false;
+        s->acquisition_samples=0u;
+        s->acquisition_speed_rad_s=0.0f;
         o->bemf_alpha_v = s->estimated_bemf_alpha_v;
         o->bemf_beta_v = s->estimated_bemf_beta_v;
         o->valid = true;
@@ -266,6 +279,18 @@
     const float direction = (float)i->commanded_direction;
     const float raw_angle = atan2_cordic(-direction*s->estimated_bemf_alpha_v,
                                          direction*s->estimated_bemf_beta_v);
+    /* Frequency acquisition uses successive measured BEMF angles, not a
+     * synthetic higher-rate stream. It is ambiguous above Nyquist. */
+    const float max_speed = c->max_mechanical_rpm*((DS_TWO_PI/60.0f)*(float)c->pole_pairs);
+    if (!s->observer_locked) {
+        if (s->acquisition_samples != 0u) {
+            const float measured_speed = wrap_pi(raw_angle-s->previous_raw_angle_rad)/i->dt_s;
+            s->acquisition_speed_rad_s += 0.125f*(measured_speed-s->acquisition_speed_rad_s);
+            s->electrical_speed_rad_s = clamp(s->acquisition_speed_rad_s,-max_speed,max_speed);
+        }
+        if (s->acquisition_samples < 255u) ++s->acquisition_samples;
+    }
+    s->previous_raw_angle_rad=raw_angle;
     /* The current observer and BEMF smoother each contribute phase delay. */
     const float phase_lead = direction *
         clamp(2.0f*absf_local(s->electrical_speed_rad_s)*
@@ -274,7 +299,6 @@
     float phase_error = 0.0f;
     if (!s->angle_valid) {
         s->electrical_angle_rad = measured_angle;
-        s->electrical_speed_rad_s = 0.0f;
         s->angle_valid = true;
     } else {
         phase_error = wrap_pi(measured_angle - s->electrical_angle_rad);
@@ -288,7 +312,8 @@
     }
     if (!s->observer_locked) {
         if (absf_local(phase_error) <= c->lock_phase_error_rad &&
-            absf_local(s->electrical_speed_rad_s) > 0.0f) {
+            direction*s->electrical_speed_rad_s > 0.0f &&
+            s->acquisition_samples >= 16u) {
             if (s->lock_count < c->lock_samples) ++s->lock_count;
             if (s->lock_count >= c->lock_samples) s->observer_locked = true;
         } else {
