[ld2420] Address review findings

Clear cmd_active_ when the blocking engine exhausts retries so loop()
does not stay skipped forever, send config mode exit blind before
abandoning a startup sequence so the module resumes streaming, and
repeat the first frame in the delayed boot fixture so the initial
state swallow cannot make the test flaky.
This commit is contained in:
J. Nick Koston
2026-08-16 21:12:58 -05:00
parent 15e1ac2500
commit 338e498960
3 changed files with 41 additions and 4 deletions
+17
View File
@@ -308,6 +308,7 @@ bool LD2420Component::startup_ack_check_() {
this->send_startup_cmd_();
return false;
}
this->abort_startup_cmd_();
if (this->startup_sequence_retries_ < STARTUP_SEQUENCE_MAX_RETRIES) {
this->startup_sequence_retries_++;
ESP_LOGW(TAG, "Module setup attempt %u failed; retrying", this->startup_sequence_retries_);
@@ -323,6 +324,19 @@ bool LD2420Component::startup_ack_check_() {
return false;
}
void LD2420Component::abort_startup_cmd_() {
// If the module already acknowledged config mode it stops streaming until
// config mode is exited, so send the exit command blind before abandoning
// the sequence; otherwise the stream never resumes and neither passive
// parsing nor the next listen phase would ever see data.
if (this->startup_state_ == StartupState::STARTUP_STATE_ENTER_CONFIG) {
return; // Config mode was never acknowledged; the module is still streaming
}
CmdFrameT frame;
this->build_config_mode_frame_(frame, false);
this->write_cmd_frame_(frame);
}
void LD2420Component::loop_startup_() {
switch (this->startup_state_) {
case StartupState::STARTUP_STATE_LISTEN: {
@@ -875,6 +889,9 @@ int LD2420Component::send_cmd_from_array(CmdFrameT frame) {
this->handle_cmd_error(this->cmd_reply_.error);
}
}
// On ack the reply parser already cleared this; clear it here as well so an
// exhausted retry loop cannot leave loop() skipping all processing forever.
this->cmd_active_ = false;
return error;
}
+1
View File
@@ -172,6 +172,7 @@ class LD2420Component final : public Component, public uart::UARTDevice {
void loop_startup_();
void start_startup_cmd_(StartupState state);
void send_startup_cmd_();
void abort_startup_cmd_();
bool startup_ack_check_();
void drain_rx_();
void write_cmd_frame_(const CmdFrameT &frame);
@@ -45,10 +45,29 @@ uart_mock:
0xF8, 0xF7, 0xF6, 0xF5,
]
# Post-setup frame (t=3300ms): distance=50 proves streaming still works
# after the setup handshake. Delay=1300ms keeps >1000ms publish throttle
# gap from the first frame.
- delay: 1300ms
# Repeat frame (t=3100ms): distance=100 again. If the API client happens
# to subscribe after the first frame, the first published state is
# swallowed as the entity's initial state; repeating the value makes the
# test's first collected state deterministic. Delay=1100ms keeps >1000ms
# publish throttle gap from the first frame.
- delay: 1100ms
inject_rx:
[
0xF4, 0xF3, 0xF2, 0xF1,
0x23, 0x00,
0x01,
0x64, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xF8, 0xF7, 0xF6, 0xF5,
]
# Post-setup frame (t=4200ms): distance=50 proves streaming still works
# after the setup handshake. Delay=1100ms keeps >1000ms publish throttle
# gap from the repeat frame.
- delay: 1100ms
inject_rx:
[
0xF4, 0xF3, 0xF2, 0xF1,