diff --git a/src/relay_chn_core.c b/src/relay_chn_core.c index be24eb0..a8c7d08 100644 --- a/src/relay_chn_core.c +++ b/src/relay_chn_core.c @@ -275,6 +275,22 @@ static void relay_chn_start_timer_or_idle(relay_chn_ctl_t *chn_ctl, esp_timer_ha } } +static void relay_chn_stop_prv(relay_chn_ctl_t *chn_ctl) +{ + if (relay_chn_output_stop(chn_ctl->output) != ESP_OK) { + ESP_LOGE(TAG, "relay_chn_execute_stop: Failed to output stop for relay channel #%d!", chn_ctl->id); + } + relay_chn_state_t previous_state = chn_ctl->state; + relay_chn_update_state(chn_ctl, RELAY_CHN_STATE_STOPPED); + + // Save the last run time only if the previous state was either STATE FORWARD + // or STATE_REVERSE. Then schedule a free command. + if (previous_state == RELAY_CHN_STATE_FORWARD || previous_state == RELAY_CHN_STATE_REVERSE) { + // Record the command's last run time + relay_chn_run_info_set_last_run_cmd_time_ms(chn_ctl->run_info, (uint32_t)(esp_timer_get_time() / 1000)); + } +} + /** * @brief The command issuer function. * @@ -368,7 +384,7 @@ void relay_chn_issue_cmd(relay_chn_ctl_t* chn_ctl, relay_chn_cmd_t cmd) case RELAY_CHN_STATE_REVERSE: if (cmd == RELAY_CHN_CMD_FLIP) { // If the command is FLIP, stop the running channel first, then issue the FLIP command - relay_chn_dispatch_cmd(chn_ctl, RELAY_CHN_CMD_STOP); + relay_chn_stop_prv(chn_ctl); relay_chn_dispatch_cmd(chn_ctl, cmd); return; } @@ -379,7 +395,7 @@ void relay_chn_issue_cmd(relay_chn_ctl_t* chn_ctl, relay_chn_cmd_t cmd) } // Stop the channel first before the schedule - relay_chn_dispatch_cmd(chn_ctl, RELAY_CHN_CMD_STOP); + relay_chn_stop_prv(chn_ctl); // If the last run command is different from the current command, wait for the opposite inertia time chn_ctl->pending_cmd = cmd; @@ -446,34 +462,21 @@ static void relay_chn_execute_idle(relay_chn_ctl_t *chn_ctl) static void relay_chn_execute_stop(relay_chn_ctl_t *chn_ctl) { - if (relay_chn_output_stop(chn_ctl->output) != ESP_OK) { - ESP_LOGE(TAG, "relay_chn_execute_stop: Failed to output stop for relay channel #%d!", chn_ctl->id); - } - relay_chn_state_t previous_state = chn_ctl->state; - relay_chn_update_state(chn_ctl, RELAY_CHN_STATE_STOPPED); + relay_chn_stop_prv(chn_ctl); // If there is any pending command, cancel it since the STOP command is issued right after it - chn_ctl->pending_cmd = RELAY_CHN_CMD_NONE; + // chn_ctl->pending_cmd = RELAY_CHN_CMD_NONE; #if CONFIG_RELAY_CHN_ENABLE_RUN_LIMIT esp_timer_stop(chn_ctl->run_limit_timer); #endif - if (previous_state == RELAY_CHN_STATE_FORWARD_PENDING || previous_state == RELAY_CHN_STATE_REVERSE_PENDING) { - chn_ctl->pending_cmd = RELAY_CHN_CMD_IDLE; - // Do nothing more and let the timer set channel idle when it expires - return; - } - // Invalidate the channel's timer if it is active esp_timer_stop(chn_ctl->inertia_timer); - // Save the last run time only if the previous state was either STATE FORWARD - // or STATE_REVERSE. Then schedule a free command. - if (previous_state == RELAY_CHN_STATE_FORWARD || previous_state == RELAY_CHN_STATE_REVERSE) { - // Record the command's last run time - relay_chn_run_info_set_last_run_cmd_time_ms(chn_ctl->run_info, (uint32_t)(esp_timer_get_time() / 1000)); - // Schedule a free command for the channel + relay_chn_cmd_t last_run_cmd = relay_chn_run_info_get_last_run_cmd(chn_ctl->run_info); + if (last_run_cmd == RELAY_CHN_CMD_FORWARD || last_run_cmd == RELAY_CHN_CMD_REVERSE ) { + // Schedule IDLE chn_ctl->pending_cmd = RELAY_CHN_CMD_IDLE; relay_chn_start_timer_or_idle(chn_ctl, chn_ctl->inertia_timer, CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS, "idle"); } else { @@ -483,6 +486,7 @@ static void relay_chn_execute_stop(relay_chn_ctl_t *chn_ctl) } } + static void relay_chn_execute_forward(relay_chn_ctl_t *chn_ctl) { if (relay_chn_output_forward(chn_ctl->output) != ESP_OK) {