Author SHA1 Message Date
gronod ce9d729027 Tick A04 DoD checkbox after CI green
ci / test (push) Successful in 1m11s
ci / firmware (jc4827w543, sdkconfig.s3, esp32s3) (push) Successful in 3m51s
ci / firmware (wroom, sdkconfig.wroom, esp32) (push) Successful in 3m53s
2026-09-17 10:08:33 +01:00
gronod 06acd84928 Add esp_timer to hal_temp requires
ci / test (push) Successful in 2m6s
ci / firmware (jc4827w543, sdkconfig.s3, esp32s3) (push) Successful in 3m42s
ci / firmware (wroom, sdkconfig.wroom, esp32) (push) Successful in 3m44s
2026-09-17 09:58:29 +01:00
gronod cfd047a0ac Mark A04 status DONE
ci / test (push) Successful in 1m24s
ci / firmware (wroom, sdkconfig.wroom, esp32) (push) Failing after 7m23s
ci / firmware (jc4827w543, sdkconfig.s3, esp32s3) (push) Failing after 7m24s
2026-09-17 09:47:01 +01:00
gronod a3830a58cb Make DS18B20 conversion non-blocking in hal_temp 2026-09-17 09:46:32 +01:00
gronod 3785f07189 Mark A03 status DONE
ci / test (push) Successful in 1m6s
ci / firmware (jc4827w543, sdkconfig.s3, esp32s3) (push) Successful in 3m55s
ci / firmware (wroom, sdkconfig.wroom, esp32) (push) Successful in 4m0s
2026-09-17 07:58:32 +01:00
gronod 37b772218b Make task watchdog setup explicit in app_main
ci / test (push) Successful in 1m5s
ci / firmware (jc4827w543, sdkconfig.s3, esp32s3) (push) Successful in 4m36s
ci / firmware (wroom, sdkconfig.wroom, esp32) (push) Successful in 4m40s
2026-09-17 07:49:20 +01:00
gronod 8f7db974fa Mark A02 status DONE
ci / test (push) Successful in 1m10s
ci / firmware (wroom, sdkconfig.wroom, esp32) (push) Successful in 3m32s
ci / firmware (jc4827w543, sdkconfig.s3, esp32s3) (push) Successful in 3m42s
2026-09-17 07:30:48 +01:00
gronod 02d226b949 Update machine tests for auto-advance 2026-09-17 07:30:19 +01:00
gronod d71e28c85d Restore auto-advance to arm next step after step complete 2026-09-17 07:30:19 +01:00
10 changed files with 134 additions and 60 deletions
+1 -1
View File
@@ -194,7 +194,7 @@ void app_machine_init(void)
s_deadline_ms = 0; s_deadline_ms = 0;
s_have_deadline = false; s_have_deadline = false;
s_resume_pending = false; s_resume_pending = false;
s_auto_advance = false; s_auto_advance = true;
if (s_evtq == NULL) { if (s_evtq == NULL) {
s_evtq = xQueueCreate(UI_EVT_QUEUE_LEN, sizeof(ui_evt_t)); s_evtq = xQueueCreate(UI_EVT_QUEUE_LEN, sizeof(ui_evt_t));
+1 -1
View File
@@ -1,6 +1,6 @@
set(srcs) set(srcs)
set(priv_inc) set(priv_inc)
set(priv_req driver) set(priv_req driver esp_timer)
if(IDF_TARGET STREQUAL "esp32") if(IDF_TARGET STREQUAL "esp32")
list(APPEND srcs hal_temp.c) list(APPEND srcs hal_temp.c)
+45 -15
View File
@@ -4,8 +4,7 @@
#include "esp_err.h" #include "esp_err.h"
#include "esp_log.h" #include "esp_log.h"
#include "freertos/FreeRTOS.h" #include "esp_timer.h"
#include "freertos/task.h"
#include "onewire_bus.h" #include "onewire_bus.h"
#include "board.h" #include "board.h"
@@ -18,10 +17,24 @@
static const char *TAG = "temp"; static const char *TAG = "temp";
#define TEMP_CONV_MS 750
typedef enum {
T_START,
T_WAIT,
} temp_state_t;
static onewire_bus_handle_t s_bus; static onewire_bus_handle_t s_bus;
static bool s_inited; static bool s_inited;
static float s_last_c; static float s_last_c;
static bool s_last_ok; static bool s_last_ok;
static temp_state_t s_state = T_START;
static uint32_t s_deadline_ms;
static uint32_t now_ms(void)
{
return (uint32_t)(esp_timer_get_time() / 1000ULL);
}
static bool scratch_valid(const uint8_t *sp) static bool scratch_valid(const uint8_t *sp)
{ {
@@ -45,38 +58,55 @@ void hal_temp_tick(void)
{ {
if (s_bus == NULL) { if (s_bus == NULL) {
s_last_ok = false; s_last_ok = false;
vTaskDelay(pdMS_TO_TICKS(750));
return; return;
} }
uint32_t now = now_ms();
if (s_state == T_START) {
if (now < s_deadline_ms) {
return;
}
if (onewire_bus_reset(s_bus) != ESP_OK) {
s_last_ok = false;
s_deadline_ms = now + TEMP_CONV_MS;
return;
}
uint8_t conv[2] = {CMD_SKIP_ROM, CMD_CONVERT_T};
if (onewire_bus_write_bytes(s_bus, conv, 2) != ESP_OK) {
s_last_ok = false;
s_deadline_ms = now + TEMP_CONV_MS;
return;
}
s_deadline_ms = now + TEMP_CONV_MS;
s_state = T_WAIT;
return;
}
/* T_WAIT */
if (now < s_deadline_ms) {
return;
}
s_state = T_START;
s_deadline_ms = now;
if (onewire_bus_reset(s_bus) != ESP_OK) { if (onewire_bus_reset(s_bus) != ESP_OK) {
s_last_ok = false; s_last_ok = false;
vTaskDelay(pdMS_TO_TICKS(750)); s_deadline_ms = now + TEMP_CONV_MS;
return;
}
uint8_t conv[2] = {CMD_SKIP_ROM, CMD_CONVERT_T};
if (onewire_bus_write_bytes(s_bus, conv, 2) != ESP_OK) {
s_last_ok = false;
vTaskDelay(pdMS_TO_TICKS(750));
return;
}
vTaskDelay(pdMS_TO_TICKS(750));
if (onewire_bus_reset(s_bus) != ESP_OK) {
s_last_ok = false;
return; return;
} }
uint8_t rd[2] = {CMD_SKIP_ROM, CMD_READ_SCRATCH}; uint8_t rd[2] = {CMD_SKIP_ROM, CMD_READ_SCRATCH};
if (onewire_bus_write_bytes(s_bus, rd, 2) != ESP_OK) { if (onewire_bus_write_bytes(s_bus, rd, 2) != ESP_OK) {
s_last_ok = false; s_last_ok = false;
s_deadline_ms = now + TEMP_CONV_MS;
return; return;
} }
uint8_t sp[9]; uint8_t sp[9];
memset(sp, 0, sizeof(sp)); memset(sp, 0, sizeof(sp));
if (onewire_bus_read_bytes(s_bus, sp, sizeof(sp)) != ESP_OK) { if (onewire_bus_read_bytes(s_bus, sp, sizeof(sp)) != ESP_OK) {
s_last_ok = false; s_last_ok = false;
s_deadline_ms = now + TEMP_CONV_MS;
return; return;
} }
if (!scratch_valid(sp)) { if (!scratch_valid(sp)) {
s_last_ok = false; s_last_ok = false;
s_deadline_ms = now + TEMP_CONV_MS;
return; return;
} }
int16_t raw = (int16_t)((uint16_t)sp[0] | ((uint16_t)sp[1] << 8)); int16_t raw = (int16_t)((uint16_t)sp[0] | ((uint16_t)sp[1] << 8));
+3 -3
View File
@@ -43,9 +43,9 @@ The branch was cut with uncommitted `components/app_machine/app_machine.c` chang
| --- | --- | --- | --- | | --- | --- | --- | --- |
| A00 | `audit/A00-docs.md` | Land audit doc + megaplan + phase files | DONE | | A00 | `audit/A00-docs.md` | Land audit doc + megaplan + phase files | DONE |
| A01 | `audit/A01-machine-timing-queue.md` | Deadline fix + FreeRTOS event queue + host queue shim | DONE | | A01 | `audit/A01-machine-timing-queue.md` | Deadline fix + FreeRTOS event queue + host queue shim | DONE |
| A02 | `audit/A02-auto-advance.md` | Restore auto-arm after step complete + test rework | TODO | | A02 | `audit/A02-auto-advance.md` | Restore auto-arm after step complete + test rework | DONE |
| A03 | `audit/A03-task-wdt.md` | Explicit TWDT init/reconfigure + `add()` failure logging | TODO | | A03 | `audit/A03-task-wdt.md` | Explicit TWDT init/reconfigure + `add()` failure logging | DONE |
| A04 | `audit/A04-temp-nonblocking.md` | OPTIONAL: non-blocking DS18B20 conversion | TODO | | A04 | `audit/A04-temp-nonblocking.md` | OPTIONAL: non-blocking DS18B20 conversion | DONE |
## Dependency ## Dependency
+2
View File
@@ -52,6 +52,8 @@ P07 Notes: custom NV3041A QSPI + GT911; shared app_ui text grid + colour softkey
P08 Notes: LEDC audio; RMT STEP + GPIO DIR/EN; onewire_bus DS18B20 +0.4; GPIO keypad; IDF I2C 2004. Arduino-as-component removed. third_party trees unlinked. host ctest green. idf.py not run here (no IDF_PATH). hw unflashed. P08 Notes: LEDC audio; RMT STEP + GPIO DIR/EN; onewire_bus DS18B20 +0.4; GPIO keypad; IDF I2C 2004. Arduino-as-component removed. third_party trees unlinked. host ctest green. idf.py not run here (no IDF_PATH). hw unflashed.
AUDIT A02 Notes: supersedes the frozen `auto_advance` default-false constraint — `s_auto_advance = true` restores the legacy auto-ARM chain (audit item 3, owner-approved); auto-ARM only, never auto-run.
## Dependency ## Dependency
``` ```
+8 -7
View File
@@ -1,7 +1,8 @@
# A02 — restore auto-advance (auto-arm next step after complete) # A02 — restore auto-advance (auto-arm next step after complete)
STATUS: TODO STATUS: DONE
DEPENDS: A01 DEPENDS: A01
Notes: `stop_disables_motor_and_resume` final assertion updated to `ST_ARMED` — the "unchanged" list cannot hold once auto-advance is on (resume-to-complete auto-arms step 1).
**READ:** this file, `docs/megaplans/AUDIT-MEGAPLAN.md`, `docs/audit_remediation_plan.md` item 3, `docs/CURRENT_STATE.md` §Runtime behaviour, `components/app_machine/app_machine.c`, `tests/host/test_machine.c` **READ:** this file, `docs/megaplans/AUDIT-MEGAPLAN.md`, `docs/audit_remediation_plan.md` item 3, `docs/CURRENT_STATE.md` §Runtime behaviour, `components/app_machine/app_machine.c`, `tests/host/test_machine.c`
@@ -34,9 +35,9 @@ All green, including the new `auto_advance_last_step_goes_idle`. Firmware builds
2. `Update machine tests for auto-advance` 2. `Update machine tests for auto-advance`
**DoD checkboxes:** **DoD checkboxes:**
- [ ] `s_auto_advance = true`; auto-ARM only, never auto-run. - [x] `s_auto_advance = true`; auto-ARM only, never auto-run.
- [ ] Last step completes → `ST_IDLE` + `EVT_PROCESS_IDLE`. - [x] Last step completes → `ST_IDLE` + `EVT_PROCESS_IDLE`.
- [ ] `ST_COMPLETE` + `CMD_STOP` branch retained. - [x] `ST_COMPLETE` + `CMD_STOP` branch retained.
- [ ] REFACTOR-MEGAPLAN supersede note added. - [x] REFACTOR-MEGAPLAN supersede note added.
- [ ] Host ctest green. - [x] Host ctest green.
- [ ] STATUS → DONE here and in the megaplan table. - [x] STATUS → DONE here and in the megaplan table.
+6 -6
View File
@@ -1,6 +1,6 @@
# A03 — explicit task watchdog setup in app_main # A03 — explicit task watchdog setup in app_main
STATUS: TODO STATUS: DONE
DEPENDS: A00 (independent of A01/A02 — `main/main.c` only) DEPENDS: A00 (independent of A01/A02 — `main/main.c` only)
**READ:** this file, `docs/megaplans/AUDIT-MEGAPLAN.md`, `docs/audit_remediation_plan.md` item 4, `main/main.c`, `sdkconfig.defaults` **READ:** this file, `docs/megaplans/AUDIT-MEGAPLAN.md`, `docs/audit_remediation_plan.md` item 4, `main/main.c`, `sdkconfig.defaults`
@@ -53,8 +53,8 @@ cmake -S tests/host -B build/host && cmake --build build/host && ctest --test-di
1. `Make task watchdog setup explicit in app_main` 1. `Make task watchdog setup explicit in app_main`
**DoD checkboxes:** **DoD checkboxes:**
- [ ] init-or-reconfigure runs before task creation. - [x] init-or-reconfigure runs before task creation.
- [ ] `esp_task_wdt_add` failures are logged in all four tasks. - [x] `esp_task_wdt_add` failures are logged in all four tasks.
- [ ] Effective config unchanged: 10 s timeout, CPU0 idle watched, no panic. - [x] Effective config unchanged: 10 s timeout, CPU0 idle watched, no panic.
- [ ] Both CI firmware builds green. - [x] Both CI firmware builds green.
- [ ] STATUS → DONE here and in the megaplan table. - [x] STATUS → DONE here and in the megaplan table.
+6 -6
View File
@@ -1,6 +1,6 @@
# A04 — (OPTIONAL) non-blocking DS18B20 conversion in hal_temp # A04 — (OPTIONAL) non-blocking DS18B20 conversion in hal_temp
STATUS: TODO (OPTIONAL — may be deferred indefinitely; if skipped, A03's explicit WDT setup already covers the constraint) STATUS: DONE
DEPENDS: A03 (shares `temp_task` in `main/main.c`) DEPENDS: A03 (shares `temp_task` in `main/main.c`)
**READ:** this file, `docs/megaplans/AUDIT-MEGAPLAN.md`, `docs/audit_remediation_plan.md` item 5, `components/hal_temp/hal_temp.c`, `main/main.c` **READ:** this file, `docs/megaplans/AUDIT-MEGAPLAN.md`, `docs/audit_remediation_plan.md` item 5, `components/hal_temp/hal_temp.c`, `main/main.c`
@@ -30,8 +30,8 @@ plus CI firmware builds for both targets.
1. `Make DS18B20 conversion non-blocking in hal_temp` 1. `Make DS18B20 conversion non-blocking in hal_temp`
**DoD checkboxes:** **DoD checkboxes:**
- [ ] No `vTaskDelay(750)` inside `hal_temp_tick`; conversion waits via deadline. - [x] No `vTaskDelay(750)` inside `hal_temp_tick`; conversion waits via deadline.
- [ ] `temp_task` always blocks (explicit 100 ms delay). - [x] `temp_task` always blocks (explicit 100 ms delay).
- [ ] `TEMP_OFFSET`, CRC, and read semantics unchanged. - [x] `TEMP_OFFSET`, CRC, and read semantics unchanged.
- [ ] Host ctest green; both CI firmware builds green. - [x] Host ctest green; both CI firmware builds green.
- [ ] STATUS → DONE here and in the megaplan table (or noted `SKIPPED` with reason). - [x] STATUS → DONE here and in the megaplan table (or noted `SKIPPED` with reason).
+45 -4
View File
@@ -97,7 +97,10 @@ static void map_and_post_key(char key)
static void input_task(void *arg) static void input_task(void *arg)
{ {
(void)arg; (void)arg;
esp_task_wdt_add(NULL); esp_err_t werr = esp_task_wdt_add(NULL);
if (werr != ESP_OK) {
ESP_LOGW(TAG, "input wdt add failed: %s", esp_err_to_name(werr));
}
const TickType_t period = pdMS_TO_TICKS(40); /* 25 Hz */ const TickType_t period = pdMS_TO_TICKS(40); /* 25 Hz */
for (;;) { for (;;) {
ui_raw_key_t raw; ui_raw_key_t raw;
@@ -119,7 +122,10 @@ static void input_task(void *arg)
static void machine_task(void *arg) static void machine_task(void *arg)
{ {
(void)arg; (void)arg;
esp_task_wdt_add(NULL); esp_err_t werr = esp_task_wdt_add(NULL);
if (werr != ESP_OK) {
ESP_LOGW(TAG, "machine wdt add failed: %s", esp_err_to_name(werr));
}
const TickType_t period = pdMS_TO_TICKS(20); /* 50 Hz */ const TickType_t period = pdMS_TO_TICKS(20); /* 50 Hz */
for (;;) { for (;;) {
ui_cmd_t cmd; ui_cmd_t cmd;
@@ -136,7 +142,10 @@ static void machine_task(void *arg)
static void ui_task(void *arg) static void ui_task(void *arg)
{ {
(void)arg; (void)arg;
esp_task_wdt_add(NULL); esp_err_t werr = esp_task_wdt_add(NULL);
if (werr != ESP_OK) {
ESP_LOGW(TAG, "ui wdt add failed: %s", esp_err_to_name(werr));
}
hal_display_clear(); hal_display_clear();
hal_display_text(0, 0, "AUTOFILM"); hal_display_text(0, 0, "AUTOFILM");
@@ -164,13 +173,17 @@ static void ui_task(void *arg)
static void temp_task(void *arg) static void temp_task(void *arg)
{ {
(void)arg; (void)arg;
esp_task_wdt_add(NULL); esp_err_t werr = esp_task_wdt_add(NULL);
if (werr != ESP_OK) {
ESP_LOGW(TAG, "temp wdt add failed: %s", esp_err_to_name(werr));
}
for (;;) { for (;;) {
hal_temp_tick(); hal_temp_tick();
float c = 0.0f; float c = 0.0f;
bool ok = (hal_temp_read_c(&c) == ESP_OK); bool ok = (hal_temp_read_c(&c) == ESP_OK);
app_machine_on_temp(ok ? c : 0.0f, ok); app_machine_on_temp(ok ? c : 0.0f, ok);
esp_task_wdt_reset(); esp_task_wdt_reset();
vTaskDelay(pdMS_TO_TICKS(100));
} }
} }
#endif #endif
@@ -205,6 +218,34 @@ void app_main(void)
s_cmdq = xQueueCreate(UI_CMD_QUEUE_LEN, sizeof(ui_cmd_t)); s_cmdq = xQueueCreate(UI_CMD_QUEUE_LEN, sizeof(ui_cmd_t));
#if CONFIG_ESP_TASK_WDT_EN
esp_task_wdt_config_t wdt_cfg = {
.timeout_ms = CONFIG_ESP_TASK_WDT_TIMEOUT_S * 1000,
.idle_core_mask =
#if CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0
(1u << 0)
#else
0
#endif
#if CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1
| (1u << 1)
#endif
,
#if CONFIG_ESP_TASK_WDT_PANIC
.trigger_panic = true,
#else
.trigger_panic = false,
#endif
};
esp_err_t wdt_err = esp_task_wdt_init(&wdt_cfg);
if (wdt_err == ESP_ERR_INVALID_STATE) {
wdt_err = esp_task_wdt_reconfigure(&wdt_cfg); /* already auto-initialised */
}
if (wdt_err != ESP_OK) {
ESP_LOGW(TAG, "task wdt setup: %s", esp_err_to_name(wdt_err));
}
#endif
xTaskCreate(temp_task, "temp", 4096, NULL, 2, NULL); xTaskCreate(temp_task, "temp", 4096, NULL, 2, NULL);
xTaskCreate(input_task, "input", 3072, NULL, 8, NULL); xTaskCreate(input_task, "input", 3072, NULL, 8, NULL);
xTaskCreate(machine_task, "machine", 4096, NULL, 6, NULL); xTaskCreate(machine_task, "machine", 4096, NULL, 6, NULL);
+17 -17
View File
@@ -145,12 +145,10 @@ static void arm_start_complete_custom_10s(void)
app_machine_tick(9999); app_machine_tick(9999);
expect_int((int)app_machine_state(), ST_RUNNING, "custom tick9999"); expect_int((int)app_machine_state(), ST_RUNNING, "custom tick9999");
app_machine_tick(10000); app_machine_tick(10000);
expect_int((int)app_machine_state(), ST_COMPLETE, "custom complete"); expect_int((int)app_machine_state(), ST_ARMED, "custom auto-armed next");
expect_int((int)app_machine_step_index(), 1, "custom auto-advance step");
expect_int(stub_motor_enabled ? 1 : 0, 0, "custom motor off complete"); expect_int(stub_motor_enabled ? 1 : 0, 0, "custom motor off complete");
expect_int(stub_alarm_count >= 1 ? 1 : 0, 1, "custom alarm"); expect_int(stub_alarm_count >= 1 ? 1 : 0, 1, "custom alarm");
/* default auto_advance false */
app_machine_tick(10001);
expect_int((int)app_machine_state(), ST_COMPLETE, "auto_advance stays complete");
} }
static void stop_disables_motor_and_resume(void) static void stop_disables_motor_and_resume(void)
@@ -182,7 +180,7 @@ static void stop_disables_motor_and_resume(void)
expect_int(stub_beep_count >= beeps + 1 ? 1 : 0, 1, "resume beep"); expect_int(stub_beep_count >= beeps + 1 ? 1 : 0, 1, "resume beep");
app_machine_tick(1000); app_machine_tick(1000);
app_machine_tick(1000 + rem); app_machine_tick(1000 + rem);
expect_int((int)app_machine_state(), ST_COMPLETE, "resume then complete"); expect_int((int)app_machine_state(), ST_ARMED, "resume then auto-armed");
} }
static void return_from_stopped(void) static void return_from_stopped(void)
@@ -208,23 +206,23 @@ static void return_from_stopped(void)
expect_int((int)app_process_get(PROC_CUSTOM)->steps[0].time_s, 10, "const still 10"); expect_int((int)app_process_get(PROC_CUSTOM)->steps[0].time_s, 10, "const still 10");
} }
static void stop_during_complete_cancels_alarm(void) static void auto_advance_last_step_goes_idle(void)
{ {
app_machine_init(); app_machine_init();
ui_cmd_t c = cmd_select(PROC_CUSTOM); ui_cmd_t c = cmd_select(PROC_CUSTOM);
app_machine_handle_cmd(&c); app_machine_handle_cmd(&c);
ui_cmd_t arm = cmd_arm(0); ui_cmd_t arm = cmd_arm(3);
app_machine_handle_cmd(&arm); app_machine_handle_cmd(&arm);
ui_cmd_t start = cmd_start(0); ui_cmd_t start = cmd_start(3);
app_machine_handle_cmd(&start); app_machine_handle_cmd(&start);
app_machine_tick(0); app_machine_tick(0);
app_machine_tick(10000); app_machine_tick(10000);
expect_int((int)app_machine_state(), ST_COMPLETE, "complete before stop"); expect_int((int)app_machine_state(), ST_IDLE, "last step goes idle");
int cancels = stub_alarm_cancel_count; ui_evt_id_t ids[8];
ui_cmd_t stop = cmd_id(CMD_STOP); int n = pop_ids(ids, 8);
app_machine_handle_cmd(&stop); if (!has_id(ids, n, EVT_PROCESS_IDLE)) {
expect_int((int)app_machine_state(), ST_STEP_SELECT, "stop from complete"); fail("last step idle event");
expect_int(stub_alarm_cancel_count >= cancels + 1 ? 1 : 0, 1, "alarm cancel"); }
} }
static void ecn2_remjet_zero_time(void) static void ecn2_remjet_zero_time(void)
@@ -246,7 +244,8 @@ static void ecn2_remjet_zero_time(void)
expect_int(stub_motor_enabled ? 1 : 0, 0, "remjet no enable"); expect_int(stub_motor_enabled ? 1 : 0, 0, "remjet no enable");
expect_int(stub_agitate_start_count, starts, "remjet no agitate"); expect_int(stub_agitate_start_count, starts, "remjet no agitate");
app_machine_tick(0); app_machine_tick(0);
expect_int((int)app_machine_state(), ST_COMPLETE, "remjet complete next tick"); expect_int((int)app_machine_state(), ST_ARMED, "remjet auto-armed next");
expect_int((int)app_machine_step_index(), 2, "remjet auto-advance step");
} }
static void stop_ignored_meaningless_in_idle(void) static void stop_ignored_meaningless_in_idle(void)
@@ -275,7 +274,8 @@ static void c41_clock(void)
app_machine_tick(179999); app_machine_tick(179999);
expect_int((int)app_machine_state(), ST_RUNNING, "c41 tick179999"); expect_int((int)app_machine_state(), ST_RUNNING, "c41 tick179999");
app_machine_tick(180000); app_machine_tick(180000);
expect_int((int)app_machine_state(), ST_COMPLETE, "c41 tick180000"); expect_int((int)app_machine_state(), ST_ARMED, "c41 auto-armed next");
expect_int((int)app_machine_step_index(), 1, "c41 auto-advance step");
} }
int main(void) int main(void)
@@ -285,7 +285,7 @@ int main(void)
arm_start_complete_custom_10s(); arm_start_complete_custom_10s();
stop_disables_motor_and_resume(); stop_disables_motor_and_resume();
return_from_stopped(); return_from_stopped();
stop_during_complete_cancels_alarm(); auto_advance_last_step_goes_idle();
ecn2_remjet_zero_time(); ecn2_remjet_zero_time();
stop_ignored_meaningless_in_idle(); stop_ignored_meaningless_in_idle();
c41_clock(); c41_clock();