1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// Pure Comp_E reference-ladder arithmetic.
//
// Like `baud.rs`, `ticks.rs`, and `adc_cal.rs`, this file is intentionally
// dependency-free (pure `core` integer arithmetic, no PAC/HAL types) so the
// exact same source can be `include!`d by the host-side test crate in
// `unit_tests/`. The `comp_e` threshold helpers are thin wrappers over these
// functions, so a regression in the math fails the host tests. Do not add
// external `use`s here.
// (Regular `//` comments, not `//!`, so the file can be `include!`d mid-crate.)
/// The number of taps on the Comp_E reference resistor string (`CEREF0`/
/// `CEREF1` are 5-bit fields).
pub const LADDER_TAPS: u8 = 32;
/// The voltage at ladder tap `tap` (0..=31), in millivolts, given the ladder's
/// source voltage in millivolts.
///
/// The resistor string divides its source into 32 equal steps and tap `n`
/// selects the **(n+1)/32** point (SLAU367 §26.2.3: `CEREF0 = 0` is 1/32, not
/// 0 V — a zero threshold would be useless, so the encoding starts one step
/// up; tap 31 is the full source voltage). Rounded to nearest (add half the
/// divisor before dividing). Widened to `u32`: the worst case,
/// `3700 mV × 32 ≈ 1.2e5`, is far inside `u32`.
/// The ladder tap (0..=31) whose voltage is closest to `target_mv`, given the
/// ladder's source voltage in millivolts.
///
/// Inverts [`ladder_millivolts`]: `tap + 1 = round(32 × target / source)`,
/// clamped to the real tap range — a target at or below half a step selects
/// tap 0 (1/32), a target at or above the source selects tap 31 (32/32).
/// Ties round up (toward the higher tap). `source_mv == 0` (meaningless — the
/// ladder has no source) degenerates to tap 0 rather than dividing by zero.