Глобальная переделка. тест сделан по длине импульса и заданной частоте шим, а не меандру

This commit is contained in:
2026-08-12 18:10:05 +03:00
parent 1db89fca79
commit a17e8962b4
19 changed files with 958 additions and 642 deletions

View File

@@ -17,8 +17,8 @@
constexpr uint32_t PWM_OUTPUT_TEST_FREQUENCY_HZ = 1000;
constexpr uint32_t PWM_OUTPUT_TEST_SWEEP_PERIOD_MS = 2000;
constexpr uint32_t PWM_OUTPUT_TEST_UPDATE_MS = 10;
constexpr uint8_t PWM_OUTPUT_TEST_MIN_DUTY_PCT = 5;
constexpr uint8_t PWM_OUTPUT_TEST_MAX_DUTY_PCT = 95;
constexpr uint32_t PWM_OUTPUT_TEST_MIN_PULSE_NS = 1000;
constexpr uint32_t PWM_OUTPUT_TEST_MAX_PULSE_NS = 10000;
#if CONFIG_IDF_TARGET_ESP32C3
constexpr bool TARGET_IS_C3 = true;
@@ -66,17 +66,21 @@ constexpr uint8_t OLED_ROTATION = 0;
constexpr uint8_t OLED_ADDRESS = 0x3C;
constexpr uint8_t ESPNOW_WIFI_CHANNEL = 6;
constexpr uint32_t SERIAL_BAUD = 115200;
// Native USB CDC may keep a stale "connected" state after light sleep. Keep
// logging non-blocking so a missing host can never delay button polling.
constexpr uint32_t SERIAL_TX_TIMEOUT_MS = 2;
constexpr bool SERIAL_ACTION_LOG = true;
constexpr bool SERIAL_LOG_TIMESTAMPS = true;
constexpr bool SERIAL_MINIMAL_LOG = true;
#define BUTTON_ACTIVE_LEVEL LOW
// Raw GPIO_RX level that means the optical receiver is active.
#define RX_ACTIVE_LEVEL LOW
// PWM_SAFE_LEVEL must switch the optical transmitter fully off and is used
// during tests whenever PWM is stopped, and while the controller sleeps.
// PWM_ACTIVE_LEVEL intentionally keeps the transmitter active while the
// controller is awake and no test is in progress.
#define RX_ACTIVE_LEVEL HIGH
// PWM_ACTIVE_LEVEL is the electrical level of the active test pulse and is
// also used for the constant active output while awake outside a test. During
// the remainder of a running PWM period the output is !PWM_ACTIVE_LEVEL.
// PWM_SAFE_LEVEL is used only while PWM is stopped and during sleep; it is
// independent of the PWM inactive level and may equal PWM_ACTIVE_LEVEL.
#define PWM_SAFE_LEVEL HIGH
#define PWM_ACTIVE_LEVEL LOW
#define PWM_SETTLE_CYCLES 5U
@@ -99,14 +103,10 @@ constexpr uint32_t LINK_HEARTBEAT_TIMEOUT_MS = 2500;
constexpr uint32_t FINAL_ACK_RETRY_INTERVAL_MS = 50;
constexpr uint8_t FINAL_ACK_RETRIES = 2;
constexpr uint8_t NO_SIGNAL_TIMEOUT_PERIODS = 8;
constexpr uint16_t RMT_MIN_RECEIVE_SYMBOLS = 48;
constexpr uint16_t RMT_MAX_RECEIVE_SYMBOLS = 512;
constexpr uint32_t RMT_TARGET_CHUNK_US = 5000;
constexpr uint8_t RMT_QUEUE_BLOCKS = 8;
constexpr uint16_t PERIOD_BATCH_SIZE = 128;
// Frequency and duty are validated only by their averages over this many
// complete periods. Individual tick variation is retained for diagnostics but
// is not itself a test failure.
// Retained as the minimum statistical depth used by the hardware-resolution
// calculation and diagnostics. PASS/FAIL is evaluated for every complete
// pulse independently; accumulated values are used only for display.
constexpr uint16_t MEASUREMENT_AVERAGING_PERIODS = 100;
static_assert(MEASUREMENT_AVERAGING_PERIODS > 0,
"Averaging window must contain at least one period");
@@ -123,38 +123,40 @@ constexpr uint32_t RX_PROCESSING_PERIODS_PER_SECOND = 300000;
constexpr uint32_t C3_STRICT_MAX_HZ = 1000000;
constexpr uint32_t S3_STRICT_MAX_HZ = 1000000;
// RMT stores each HIGH/LOW duration in 15 bits. Select the fastest clock that
// still fits both levels of the current PWM signal: 20, 40 or 80 MHz.
constexpr uint32_t CAPTURE_RESOLUTION_OPTIONS_HZ[] = {20000000, 40000000, 80000000};
constexpr uint32_t RMT_MAX_LEVEL_TICKS = 32766;
// S3 MCPWM Capture uses one 32-bit 80 MHz timer for both edges. Unlike RMT,
// its width does not constrain long LOW/HIGH intervals, so capture precision
// stays at 12.5 ns for every selectable PWM frequency and pulse length.
constexpr uint32_t MCPWM_CAPTURE_RESOLUTION_HZ = 80000000;
// C3 uses the 40 MHz crystal as the LEDC clock.
// Keep this explicit so the resolution calculation never asks LEDC for an
// impossible frequency/resolution combination.
constexpr uint32_t LEDC_SOURCE_CLOCK_HZ = 40000000;
constexpr uint8_t LEDC_CHANNEL = 0;
constexpr uint8_t LEDC_MAX_BITS = 14;
// S3 uses the dedicated MCPWM peripheral. A 40 MHz timer clock keeps the
// longest 1 kHz period within the S3's 16-bit MCPWM counter and makes every
// frequency in TEST_FREQUENCIES_HZ exact.
constexpr uint32_t MCPWM_RESOLUTION_HZ = 40000000;
// S3 uses the dedicated MCPWM peripheral. A 20 MHz timer clock keeps the
// selectable 500 Hz period within the S3's 16-bit counter while retaining
// 50 ns pulse resolution and exact periods for every menu frequency.
constexpr uint32_t MCPWM_RESOLUTION_HZ = 20000000;
constexpr uint32_t MCPWM_MAX_PERIOD_TICKS = 65535;
// -------------------------- Menu value arrays -----------------------------
// START and END deliberately have separate, independently cycling menu lists.
// Every value is exactly achievable from a 40 MHz timer clock. The test walks
// TEST_FREQUENCIES_HZ between the selected endpoints, so there is no
// separately configurable step.
constexpr uint32_t START_FREQ_OPTIONS_HZ[] = {1000, 10000, 100000};
constexpr uint32_t END_FREQ_OPTIONS_HZ[] = {100000, 500000, 1000000};
// All achievable whole-number frequencies in the supported 1 kHz..1 MHz
// range, used for adjacent test stages rather than direct menu selection.
constexpr uint32_t TEST_FREQUENCIES_HZ[] = {
1000, 2000, 5000, 10000, 25000, 50000,
100000, 200000, 312500, 400000, 500000, 625000, 800000, 1000000
// The test uses one selected PWM frequency and walks the pulse-width list from
// the selected maximum down to the selected minimum. Widths are stored in
// nanoseconds so sub-microsecond pulses remain representable without floats.
constexpr uint32_t PWM_FREQUENCY_OPTIONS_HZ[] = {
500, 1000, 2000, 5000, 10000, 25000,
};
constexpr uint32_t MAX_PULSE_OPTIONS_NS[] = {
20000, 50000, 100000, 200000, 500000
};
constexpr uint32_t MIN_PULSE_OPTIONS_NS[] = {
250, 500, 1000, 2000, 5000, 10000
};
constexpr uint32_t TEST_PULSE_WIDTHS_NS[] = {
250, 500, 1000, 2000, 5000, 10000, 20000, 50000,
100000, 200000, 500000, 1000000
};
constexpr float ACCURACY_OPTIONS_PCT[] = {1.0f, 2.0f, 5.0f, 10.0f};
constexpr uint32_t TEST_TIME_OPTIONS_MS[] = {100, 250, 500, 1000, 2000, 5000};
constexpr uint8_t TEST_DUTY_PCT = 50;
template <typename T, size_t N> constexpr size_t countOf(const T (&)[N]) { return N; }