#pragma once #include #include #include #include "domain.h" #include "esp_err.h" #include "freertos/FreeRTOS.h" #include "freertos/event_groups.h" #include "freertos/queue.h" #include "freertos/semphr.h" #include "freertos/task.h" #define PROTO_ADDR 0x01 #define CMD_POWER 0x00 #define CMD_GET_STATUS 0x01 #define CMD_SET_DISTANCE 0x02 #define CMD_SET_PARAM 0x03 #define CMD_SEND_DATA 0x04 #define CMD_GAP_MOVE 0x05 #define CMD_GET_OFFSET 0x06 #define CMD_SET_OFFSET 0x07 #define CMD_BOOT_JUMP_BOOT 0xA0 #define CMD_BOOT_ERASE_PAGE 0xA1 #define CMD_BOOT_WRITE_DATA 0xA2 #define CMD_BOOT_JUMP_APP 0xA3 #define CMD_BOOT_GET_VERSION 0xA4 #define EVT_ACK BIT0 #define EVT_SHUTDOWN BIT1 #define EVT_WORKER_EXITED BIT2 #define EVT_STATUS_POLL_EXITED BIT3 #define JOB_QUEUE_LEN 8 #define JOB_SLOT_MAX 16 #define MAX_RASTER_BYTES (384 * 3000 / 8) #define STATUS_POLL_PAUSE_SLOT_MAX 8 #define PRINTER_JOB_SENTINEL_STOP 0u #define OTA_MAX_DATA_PER_FRAME 236u typedef struct { bool used; bool cancel_requested; uint32_t id; print_job_state_t state; uint8_t progress; uint16_t width; uint16_t height; size_t data_len; char density[16]; char error[96]; int64_t created_ms; int64_t started_ms; int64_t finished_ms; uint8_t *data; } job_slot_t; typedef struct { bool has_paper; uint8_t battery; float temperature; int64_t updated_ms; } parsed_status_t; extern SemaphoreHandle_t s_mutex; extern QueueHandle_t s_job_queue; extern EventGroupHandle_t s_evt; extern uint32_t s_busy_refcnt; extern parsed_status_t s_status; extern uint8_t s_last_rsp_cmd; extern uint16_t s_last_rsp_payload_len; extern uint8_t s_last_rsp_payload[252]; extern uint32_t s_status_poll_pause_next_token; extern uint32_t s_status_poll_pause_tokens[STATUS_POLL_PAUSE_SLOT_MAX]; extern uint32_t s_next_job_id; extern job_slot_t s_jobs[JOB_SLOT_MAX]; extern TaskHandle_t s_worker_task; extern TaskHandle_t s_status_poll_task_handle; extern bool s_protocol_initialized; extern bool s_protocol_stopping; bool printer_protocol_acquire_control_lane(uint32_t timeout_ms, char *err, size_t err_len); void printer_protocol_release_control_lane(void); esp_err_t printer_protocol_send_cmd_wait_response(uint8_t cmd, const uint8_t *payload, uint16_t payload_len, bool with_checksum, uint32_t timeout_ms, bool expect_ack, uint8_t *out_payload, size_t out_payload_cap, uint16_t *out_payload_len, char *err, size_t err_len); esp_err_t printer_protocol_send_frame(uint8_t cmd, const uint8_t *payload, uint16_t payload_len, bool with_checksum); bool printer_protocol_wait_response(uint8_t cmd, uint8_t *out_payload, size_t out_payload_cap, uint16_t *out_payload_len, uint32_t timeout_ms); bool printer_protocol_send_cmd_with_ack(uint8_t cmd, const uint8_t *payload, uint16_t payload_len, bool with_checksum, uint32_t timeout_ms); int printer_protocol_find_job_idx_locked(uint32_t id); int printer_protocol_alloc_job_slot_locked(void); bool printer_protocol_is_terminal_state(print_job_state_t state); void printer_protocol_worker_task(void *arg); bool printer_protocol_is_stopping(void);