#include #include #include #include "../src/main.h" #define BOOT_THRESHOLD 200 typedef struct { bool device_on; bool boot_btn_released; bool power_btn_suspended; uint16_t cnt_s; } boot_sm_t; static void route_step(const char *name) { printf(" -> %s\n", name); } static void print_main_boot_route(bool resume_without_button, bool dfu_confirm_pending, bool dfu_reset_resume) { printf("main() boot route\n"); route_step("boot_context_detect()"); printf(" resume_without_power_button=%u, dfu_confirm_pending=%u, dfu_reset_resume=%u\n", resume_without_button ? 1U : 0U, dfu_confirm_pending ? 1U : 0U, dfu_reset_resume ? 1U : 0U); route_step("power_hold_init()"); printf(" POWER_HOLD initial=%s\n", (resume_without_button || dfu_confirm_pending || dfu_reset_resume) ? "ON" : "OFF"); route_step("confirm_running_image()"); route_step("gpio_init()"); route_step("timers_init()"); route_step("log_mcuboot_state()"); route_step("load_default_config()"); route_step("led_init()"); route_step("battery_adc_init()"); route_step("battery_timer_init()"); route_step("imu_init()"); route_step("piezo_config_init()"); route_step("ble_service_init(ble_rx_handler)"); if (resume_without_button || dfu_confirm_pending || dfu_reset_resume) { route_step("resume_device_after_soft_reset()"); route_step("POWER_HOLD ON, LED_ADVERTISING, battery_timer_start(), adv_start_work"); } route_step("timers_start()"); route_step("idle loop"); } static void power_control(bool on, const char *reason) { printf(" POWER_HOLD=%s reason=%s\n", on ? "ON" : "OFF", reason); } static void boot_button_tick(boot_sm_t *sm, bool button_pressed) { if (sm->power_btn_suspended) { return; } if (!sm->device_on) { if (!button_pressed) { power_control(false, "boot-button-released-before-latch"); sm->cnt_s = 0; } else { sm->cnt_s++; if (sm->cnt_s == BOOT_THRESHOLD) { sm->device_on = true; sm->cnt_s = 0; power_control(true, "button-2s-latch"); printf(" led_set_state(LED_STATE_ADVERTISING)\n"); printf(" adv_start_work submitted\n"); printf(" battery_timer_start()\n"); } } return; } if (!sm->boot_btn_released) { if (!button_pressed) { sm->boot_btn_released = true; printf(" boot button released after latch\n"); } } else if (button_pressed) { sm->cnt_s++; if (sm->cnt_s >= BOOT_THRESHOLD) { printf(" battery_timer_stop()\n"); printf(" adv_stop_work submitted\n"); sm->device_on = false; sm->boot_btn_released = false; sm->cnt_s = 0; printf(" sleep_mode_enter_reason(button-long-press)\n"); } } else { sm->cnt_s = 0; } } static void simulate_short_press(void) { boot_sm_t sm = {0}; printf("\nscenario: short press during boot\n"); for (int i = 0; i < 80; i++) { boot_button_tick(&sm, true); } boot_button_tick(&sm, false); printf(" result: device_on=%u cnt_s=%u\n", sm.device_on ? 1U : 0U, sm.cnt_s); } static void simulate_long_press_boot(void) { boot_sm_t sm = {0}; printf("\nscenario: hold button until boot latch\n"); for (int i = 0; i < BOOT_THRESHOLD; i++) { boot_button_tick(&sm, true); } boot_button_tick(&sm, false); printf(" result: device_on=%u boot_btn_released=%u cnt_s=%u\n", sm.device_on ? 1U : 0U, sm.boot_btn_released ? 1U : 0U, sm.cnt_s); } static void simulate_power_off_after_boot(void) { boot_sm_t sm = { .device_on = true, .boot_btn_released = true, }; printf("\nscenario: long press while already ON\n"); for (int i = 0; i < BOOT_THRESHOLD; i++) { boot_button_tick(&sm, true); } printf(" result: device_on=%u cnt_s=%u\n", sm.device_on ? 1U : 0U, sm.cnt_s); } int main(void) { printf("PC GCC boot-route simulator for %s\n\n", FIRMWARE_VERSION); print_main_boot_route(false, false, false); printf("\nsoft-reset/DFU resume route\n"); print_main_boot_route(true, false, false); simulate_short_press(); simulate_long_press_boot(); simulate_power_off_after_boot(); return 0; }