Всякие тесты неинтересные

This commit is contained in:
2026-09-24 07:58:47 +03:00
parent ad33d0de79
commit 040853e7dc
14 changed files with 456 additions and 32 deletions

View File

@@ -19,7 +19,7 @@ constexpr uint8_t MENU_OPTICAL_CALIBRATION_ITEM = 7;
const char *uiFailName(FailReason reason);
const char *appStateName(AppState state) {
static const char *names[] = {"IDLE", "MENU", "BOARD_TEST", "SOLO_MEASURE", "SOLO_DRIVER", "MASTER_DISCOVER",
static const char *names[] = {"IDLE", "MENU", "BOARD_TEST", "PWM_OUTPUT", "SOLO_MEASURE", "SOLO_DRIVER", "MASTER_DISCOVER",
"MASTER_WAIT_READY", "MASTER_WAIT_RESULT", "MASTER_FINALIZE", "SLAVE_READY", "SLAVE_WAIT_START",
"SLAVE_MEASURE", "SLAVE_WAIT_ACK", "FINISHED"};
const uint8_t index = static_cast<uint8_t>(state);
@@ -250,9 +250,12 @@ uint8_t cycleIndex(uint8_t value, uint8_t first, uint8_t last, int direction) {
return value <= first ? last : static_cast<uint8_t>(value - 1U);
}
uint8_t nextMenuItem(uint8_t current, TestGroup group) {
uint8_t nextMenuItem(uint8_t current, TestGroup group, TestKind kind) {
if (group == TestGroup::BOARD)
return current == 0U ? MENU_OPTICAL_CALIBRATION_ITEM : 0U;
if (kind == TestKind::PWM_OUTPUT)
return current == 0U ? 1U : current == 1U ? 2U
: current == 2U ? MENU_OPTICAL_CALIBRATION_ITEM : 0U;
return current >= MENU_OPTICAL_CALIBRATION_ITEM ? 0U
: static_cast<uint8_t>(current + 1U);
}
@@ -356,6 +359,12 @@ void App::update() {
}
return;
}
if (state_ == AppState::PWM_OUTPUT) {
if (startEvent == ButtonEvent::LONG) stopPwmOutput();
else if (modeEvent != ButtonEvent::NONE)
Log::event("ACTION", "MODE ignored while PWM output is active");
return;
}
if (state_ != AppState::IDLE && state_ != AppState::MENU && state_ != AppState::FINISHED &&
startEvent == ButtonEvent::LONG) { abortTest(); return; }
if (state_ != AppState::IDLE && state_ != AppState::MENU && state_ != AppState::FINISHED &&
@@ -399,7 +408,8 @@ void App::update() {
if (modeEvent == ButtonEvent::SHORT) {
leaveOpticalCalibration();
menuItem_ = nextMenuItem(menuItem_,
static_cast<TestGroup>(settings_.testGroup));
static_cast<TestGroup>(settings_.testGroup),
static_cast<TestKind>(settings_.testKind));
Log::printf("ACTION", "menu item selected index=%u", menuItem_);
showMenu();
}
@@ -529,12 +539,12 @@ void App::printSerialHelp() {
Serial.println(" set group optics|board");
Serial.println(" set boardtest adc|pwm|rx");
Serial.println(" set role solo|master|slave");
Serial.println(" set test optical|driver");
Serial.println(" set frequency 500|1000|2000|5000|10000|25000");
Serial.println(" set max 2000|5000|10000|20000|50000|100000|200000|500000");
Serial.println(" set test optical|driver|pwm (driver/pwm: SOLO only)");
Serial.println(" set frequency 500|1000|2000|5000|10000");
Serial.println(" set max 2000|5000|10000|50000|100000|500000 (PWM pulse in SOLO PWM)");
Serial.println(" set min 250|500|1000|2000|5000|10000|50000");
Serial.println(" set accuracy 1|2|5|10");
Serial.println(" set time 100|250|500|1000|2000|5000 (ms)");
Serial.println(" set time 100|250|500|1000|2000|5000|60000 (ms)");
Serial.println(" set light HH|HL|LH|LL (DRIVER only)");
}
@@ -605,6 +615,9 @@ void App::handleSerialCommand(char *line) {
else if (state_ == AppState::BOARD_TEST) {
Serial.println("OK board test stopped");
stopBoardTest();
} else if (state_ == AppState::PWM_OUTPUT) {
Serial.println("OK PWM output stopped");
stopPwmOutput();
} else if (state_ == AppState::MENU) {
leaveOpticalCalibration();
state_ = AppState::IDLE; showIdle(); Serial.println("OK menu closed");
@@ -659,6 +672,9 @@ void App::handleSerialCommand(char *line) {
else if (!strcmp(value, "driver") && !TARGET_IS_C3 &&
static_cast<Role>(settings_.role) == Role::SOLO) {
settings_.testKind = static_cast<uint8_t>(TestKind::DRIVER); accepted = true;
} else if (!strcmp(value, "pwm") &&
static_cast<Role>(settings_.role) == Role::SOLO) {
settings_.testKind = static_cast<uint8_t>(TestKind::PWM_OUTPUT); accepted = true;
}
} else if ((!strcmp(name, "frequency") || !strcmp(name, "freq")) && parseUnsigned(value, numeric)) {
const int index = optionIndex(PWM_FREQUENCY_OPTIONS_HZ, numeric);
@@ -705,6 +721,8 @@ void App::cycleRunMode() {
const TestKind kind = static_cast<TestKind>(settings_.testKind);
if (role == Role::SOLO && kind == TestKind::OPTICAL && !TARGET_IS_C3) {
settings_.testKind = static_cast<uint8_t>(TestKind::DRIVER);
} else if (role == Role::SOLO && kind != TestKind::PWM_OUTPUT) {
settings_.testKind = static_cast<uint8_t>(TestKind::PWM_OUTPUT);
} else if (role == Role::SOLO) {
settings_.role = static_cast<uint8_t>(Role::MASTER);
settings_.testKind = static_cast<uint8_t>(TestKind::OPTICAL);
@@ -725,11 +743,12 @@ void App::sanitizeRange() {
settings_.boardTest = static_cast<uint8_t>(defaultBoardTest());
if (settings_.role > static_cast<uint8_t>(Role::SLAVE))
settings_.role = static_cast<uint8_t>(Role::SOLO);
if (settings_.testKind > static_cast<uint8_t>(TestKind::DRIVER))
if (settings_.testKind > static_cast<uint8_t>(TestKind::PWM_OUTPUT))
settings_.testKind = static_cast<uint8_t>(TestKind::OPTICAL);
if (settings_.lightCode > static_cast<uint8_t>(LightCode::LL))
settings_.lightCode = static_cast<uint8_t>(LightCode::HH);
if (settings_.role != static_cast<uint8_t>(Role::SOLO) ||
if ((settings_.role != static_cast<uint8_t>(Role::SOLO) &&
settings_.testKind != static_cast<uint8_t>(TestKind::OPTICAL)) ||
(TARGET_IS_C3 && settings_.testKind == static_cast<uint8_t>(TestKind::DRIVER)))
settings_.testKind = static_cast<uint8_t>(TestKind::OPTICAL);
settings_.frequencyIndex %= countOf(PWM_FREQUENCY_OPTIONS_HZ);
@@ -760,8 +779,8 @@ void App::changeMenu(int d) {
} else if (menuItem_ == 2) {
const uint8_t last = lastValidMaxPulseIndex(
PWM_FREQUENCY_OPTIONS_HZ[settings_.frequencyIndex]);
const uint8_t first = firstMaxPulseIndexAtLeast(
MIN_PULSE_OPTIONS_NS[settings_.minPulseIndex], last);
const uint8_t first = static_cast<TestKind>(settings_.testKind) == TestKind::PWM_OUTPUT
? 0U : firstMaxPulseIndexAtLeast(MIN_PULSE_OPTIONS_NS[settings_.minPulseIndex], last);
settings_.maxPulseIndex = cycleIndex(settings_.maxPulseIndex,
first, last, d);
} else if (menuItem_ == 3) {
@@ -811,7 +830,8 @@ void App::showMenu() {
break;
case 2:
Display::formatPulse(params_.maxPulseNs, value, sizeof(value));
label = UiText::MENU_MAX_PULSE;
label = static_cast<TestKind>(settings_.testKind) == TestKind::PWM_OUTPUT
? UiText::MENU_PWM_PULSE : UiText::MENU_MAX_PULSE;
break;
case 3:
Display::formatPulse(params_.minPulseNs, value, sizeof(value));
@@ -847,7 +867,8 @@ void App::showMenu() {
default: return;
}
formatMenuLine(label, value, one, sizeof(one));
if (static_cast<TestGroup>(settings_.testGroup) == TestGroup::BOARD)
if (static_cast<TestGroup>(settings_.testGroup) == TestGroup::BOARD ||
static_cast<TestKind>(settings_.testKind) == TestKind::PWM_OUTPUT)
snprintf(total, sizeof(total), "%s", UiText::BOARD_READY);
else
formatMenuLine(UiText::MENU_TOTAL_TIME, all, total, sizeof(total));
@@ -900,6 +921,10 @@ void App::startTest() {
startBoardTest();
return;
}
if (static_cast<TestKind>(settings_.testKind) == TestKind::PWM_OUTPUT) {
startPwmOutput();
return;
}
params_ = store_.params(settings_); stageCount_ = pulseWidthPointCount(params_.maxPulseNs, params_.minPulseNs);
stageIndex_ = 0; requestedHz_ = params_.frequencyHz; requestedPulseNs_ = 0; pendingReason_ = FailReason::NONE;
havePeer_ = false; lastHeartbeatMs_ = 0; lastPeerSeenMs_ = 0;
@@ -1019,6 +1044,37 @@ void App::stopBoardTest() {
showIdle();
}
void App::startPwmOutput() {
params_ = store_.params(settings_);
requestedHz_ = params_.frequencyHz;
requestedPulseNs_ = params_.maxPulseNs;
stageIndex_ = 0;
stageCount_ = 1;
pwm_.configureActiveLight(true);
if (!pwm_.start(requestedHz_, requestedPulseNs_, actual_)) {
Log::printf("PWM", "start failed: frequency=%luHz pulse=%luns",
requestedHz_, requestedPulseNs_);
finish(false, FailReason::RESOLUTION);
return;
}
state_ = AppState::PWM_OUTPUT;
char target[32], one[48];
formatTarget(actual_.actualHz, actual_.actualPulseNs, target, sizeof(target));
snprintf(one, sizeof(one), "%s: %s", uiTestName(TestKind::PWM_OUTPUT), target);
display_.show(one, UiText::BOARD_STOP);
Log::printf("PWM", "continuous output GPIO=%u requested=%luHz/%luns actual=%luHz/%luns duty=%.2f%%",
GPIO_PWM, requestedHz_, requestedPulseNs_, actual_.actualHz,
actual_.actualPulseNs, actual_.actualDutyPct);
}
void App::stopPwmOutput() {
Log::event("PWM", "continuous output stopped");
pwm_.stop();
state_ = AppState::IDLE;
setActivePerformance(false);
showIdle();
}
bool App::armSlave(bool preserveDisplay) {
setActivePerformance(false);
pwm_.stop();
@@ -1652,6 +1708,11 @@ void App::printConfiguration() {
Serial.printf("MAC=%02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
Serial.printf("GPIO PWM=%u RX=%u START=%u MODE=%u SDA=%u SCL=%u\n", GPIO_PWM, GPIO_RX,
GPIO_BUTTON_START, GPIO_BUTTON_MODE, GPIO_SDA, GPIO_SCL);
if (static_cast<TestKind>(settings_.testKind) == TestKind::PWM_OUTPUT) {
Serial.printf("Continuous PWM output %lu Hz, pulse %lu ns; RX unused\n",
params_.frequencyHz, params_.maxPulseNs);
return;
}
if (static_cast<TestKind>(settings_.testKind) == TestKind::DRIVER) {
const char *code = lightCodeName(static_cast<LightCode>(settings_.lightCode));
Serial.printf("Test %lu Hz, pulse %lu..%lu ns, accuracy %.2f%%, %lums, TX light=%c RX active light=%c\n",