添加热敏打印机调试功能
This commit is contained in:
@@ -61,12 +61,29 @@ typedef struct {
|
||||
const volatile bool *cancel_flag;
|
||||
} platform_direct_print_request_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t shift_clock_high_us;
|
||||
uint16_t shift_clock_low_us;
|
||||
uint16_t latch_pulse_us;
|
||||
bool strobe_active_high;
|
||||
bool boost_active_high;
|
||||
uint16_t override_strobe_on_us;
|
||||
uint16_t override_strobe_interval_us;
|
||||
uint16_t override_motor_step_us;
|
||||
uint8_t override_steps_per_line;
|
||||
} platform_direct_debug_config_t;
|
||||
|
||||
esp_err_t platform_direct_printer_init(void);
|
||||
void platform_direct_printer_deinit(void);
|
||||
esp_err_t platform_direct_printer_connect(uint32_t timeout_ms);
|
||||
void platform_direct_printer_disconnect(void);
|
||||
bool platform_direct_printer_is_connected(void);
|
||||
esp_err_t platform_direct_printer_get_sensors(platform_printer_sensors_t *out_sensors);
|
||||
esp_err_t platform_direct_printer_get_debug_config(platform_direct_debug_config_t *out_config);
|
||||
esp_err_t platform_direct_printer_set_debug_config(const platform_direct_debug_config_t *config,
|
||||
bool reset_defaults,
|
||||
char *err,
|
||||
size_t err_len);
|
||||
esp_err_t platform_direct_printer_print(const platform_direct_print_request_t *request,
|
||||
char *err,
|
||||
size_t err_len);
|
||||
|
||||
@@ -23,14 +23,21 @@
|
||||
#endif
|
||||
|
||||
#if CONFIG_TQ_KEY_PRINT_BOOST_ACTIVE_HIGH
|
||||
#define BOOST_ON_LEVEL 1
|
||||
#define BOOST_OFF_LEVEL 0
|
||||
#define BOOST_DEFAULT_ACTIVE_HIGH 1
|
||||
#else
|
||||
#define BOOST_ON_LEVEL 0
|
||||
#define BOOST_OFF_LEVEL 1
|
||||
#define BOOST_DEFAULT_ACTIVE_HIGH 0
|
||||
#endif
|
||||
|
||||
#define ADC_RAW_MAX 4095
|
||||
#define DEBUG_SHIFT_CLOCK_US_MIN 1
|
||||
#define DEBUG_SHIFT_CLOCK_US_MAX 50
|
||||
#define DEBUG_LATCH_PULSE_US_MIN 1
|
||||
#define DEBUG_LATCH_PULSE_US_MAX 50
|
||||
|
||||
static const uint16_t k_default_shift_clock_high_us = 5;
|
||||
static const uint16_t k_default_shift_clock_low_us = 5;
|
||||
static const uint16_t k_default_latch_pulse_us = 1;
|
||||
static const bool k_default_strobe_active_high = true;
|
||||
|
||||
static const char *TAG = "direct_printer";
|
||||
static const uint8_t k_print_yield_lines = 8;
|
||||
@@ -46,6 +53,7 @@ typedef struct {
|
||||
bool initialized;
|
||||
bool connected;
|
||||
uint8_t motor_phase;
|
||||
platform_direct_debug_config_t debug;
|
||||
SemaphoreHandle_t lock;
|
||||
adc_oneshot_unit_handle_t adc1_handle;
|
||||
adc_oneshot_unit_handle_t adc2_handle;
|
||||
@@ -57,6 +65,31 @@ static direct_printer_state_t s_state;
|
||||
|
||||
static const uint8_t k_motor_step_table[4] = {0x05, 0x09, 0x0A, 0x06};
|
||||
|
||||
static int boost_on_level_locked(void) {
|
||||
return s_state.debug.boost_active_high ? 1 : 0;
|
||||
}
|
||||
|
||||
static int boost_off_level_locked(void) {
|
||||
return s_state.debug.boost_active_high ? 0 : 1;
|
||||
}
|
||||
|
||||
static int strobe_active_level_locked(void) {
|
||||
return s_state.debug.strobe_active_high ? 1 : 0;
|
||||
}
|
||||
|
||||
static int strobe_idle_level_locked(void) {
|
||||
return s_state.debug.strobe_active_high ? 0 : 1;
|
||||
}
|
||||
|
||||
static void set_debug_defaults_locked(void) {
|
||||
memset(&s_state.debug, 0, sizeof(s_state.debug));
|
||||
s_state.debug.shift_clock_high_us = k_default_shift_clock_high_us;
|
||||
s_state.debug.shift_clock_low_us = k_default_shift_clock_low_us;
|
||||
s_state.debug.latch_pulse_us = k_default_latch_pulse_us;
|
||||
s_state.debug.strobe_active_high = k_default_strobe_active_high;
|
||||
s_state.debug.boost_active_high = BOOST_DEFAULT_ACTIVE_HIGH != 0;
|
||||
}
|
||||
|
||||
static bool is_gpio_valid(int gpio_num) {
|
||||
return gpio_num >= 0;
|
||||
}
|
||||
@@ -118,9 +151,10 @@ static esp_err_t config_input_pin(int gpio_num, bool pull_up, const char *name)
|
||||
}
|
||||
|
||||
static void set_stb_level_locked(int level) {
|
||||
set_gpio_level_if_valid(CONFIG_TQ_PRINT_STB_12_PIN, level);
|
||||
set_gpio_level_if_valid(CONFIG_TQ_PRINT_STB_34_PIN, level);
|
||||
set_gpio_level_if_valid(CONFIG_TQ_PRINT_STB_56_PIN, level);
|
||||
int out_level = level ? strobe_active_level_locked() : strobe_idle_level_locked();
|
||||
set_gpio_level_if_valid(CONFIG_TQ_PRINT_STB_12_PIN, out_level);
|
||||
set_gpio_level_if_valid(CONFIG_TQ_PRINT_STB_34_PIN, out_level);
|
||||
set_gpio_level_if_valid(CONFIG_TQ_PRINT_STB_56_PIN, out_level);
|
||||
}
|
||||
|
||||
static void motor_apply_pattern_locked(uint8_t pattern) {
|
||||
@@ -141,13 +175,19 @@ static void safe_drive_off_locked(bool keep_boost_on) {
|
||||
set_gpio_level_if_valid(CONFIG_TQ_PRINT_LAT_PIN, 1);
|
||||
motor_off_locked();
|
||||
if (!keep_boost_on) {
|
||||
set_gpio_level_if_valid(CONFIG_TQ_KEY_PRINT_PIN, BOOST_OFF_LEVEL);
|
||||
set_gpio_level_if_valid(CONFIG_TQ_KEY_PRINT_PIN, boost_off_level_locked());
|
||||
}
|
||||
}
|
||||
|
||||
static void pulse_latch_locked(void) {
|
||||
uint16_t latch_us = s_state.debug.latch_pulse_us;
|
||||
if (latch_us < DEBUG_LATCH_PULSE_US_MIN) {
|
||||
latch_us = DEBUG_LATCH_PULSE_US_MIN;
|
||||
} else if (latch_us > DEBUG_LATCH_PULSE_US_MAX) {
|
||||
latch_us = DEBUG_LATCH_PULSE_US_MAX;
|
||||
}
|
||||
set_gpio_level_if_valid(CONFIG_TQ_PRINT_LAT_PIN, 0);
|
||||
esp_rom_delay_us(1);
|
||||
esp_rom_delay_us(latch_us);
|
||||
set_gpio_level_if_valid(CONFIG_TQ_PRINT_LAT_PIN, 1);
|
||||
}
|
||||
|
||||
@@ -174,15 +214,28 @@ static void motor_step_once_locked(uint16_t step_delay_us) {
|
||||
}
|
||||
|
||||
static void write_line_bits_locked(const uint8_t *line, size_t line_bytes) {
|
||||
uint16_t high_us = s_state.debug.shift_clock_high_us;
|
||||
uint16_t low_us = s_state.debug.shift_clock_low_us;
|
||||
if (high_us < DEBUG_SHIFT_CLOCK_US_MIN) {
|
||||
high_us = DEBUG_SHIFT_CLOCK_US_MIN;
|
||||
} else if (high_us > DEBUG_SHIFT_CLOCK_US_MAX) {
|
||||
high_us = DEBUG_SHIFT_CLOCK_US_MAX;
|
||||
}
|
||||
if (low_us < DEBUG_SHIFT_CLOCK_US_MIN) {
|
||||
low_us = DEBUG_SHIFT_CLOCK_US_MIN;
|
||||
} else if (low_us > DEBUG_SHIFT_CLOCK_US_MAX) {
|
||||
low_us = DEBUG_SHIFT_CLOCK_US_MAX;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < line_bytes; ++i) {
|
||||
uint8_t byte = line[i];
|
||||
for (int bit = 7; bit >= 0; --bit) {
|
||||
int pixel = ((byte >> bit) & 0x01) ? 1 : 0;
|
||||
set_gpio_level_if_valid(CONFIG_TQ_SPI_SHARED_MOSI_PIN, pixel);
|
||||
set_gpio_level_if_valid(CONFIG_TQ_SPI_SHARED_CLK_PIN, 1);
|
||||
esp_rom_delay_us(1);
|
||||
esp_rom_delay_us(high_us);
|
||||
set_gpio_level_if_valid(CONFIG_TQ_SPI_SHARED_CLK_PIN, 0);
|
||||
esp_rom_delay_us(1);
|
||||
esp_rom_delay_us(low_us);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -423,17 +476,18 @@ esp_err_t platform_direct_printer_init(void) {
|
||||
if (s_state.lock == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
set_debug_defaults_locked();
|
||||
|
||||
esp_err_t err = ESP_OK;
|
||||
err = config_output_pin(CONFIG_TQ_PRINT_STB_12_PIN, 0, "print_stb12");
|
||||
err = config_output_pin(CONFIG_TQ_PRINT_STB_12_PIN, strobe_idle_level_locked(), "print_stb12");
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
err = config_output_pin(CONFIG_TQ_PRINT_STB_34_PIN, 0, "print_stb34");
|
||||
err = config_output_pin(CONFIG_TQ_PRINT_STB_34_PIN, strobe_idle_level_locked(), "print_stb34");
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
err = config_output_pin(CONFIG_TQ_PRINT_STB_56_PIN, 0, "print_stb56");
|
||||
err = config_output_pin(CONFIG_TQ_PRINT_STB_56_PIN, strobe_idle_level_locked(), "print_stb56");
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
@@ -466,7 +520,7 @@ esp_err_t platform_direct_printer_init(void) {
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
err = config_output_pin(CONFIG_TQ_KEY_PRINT_PIN, BOOST_OFF_LEVEL, "print_boost");
|
||||
err = config_output_pin(CONFIG_TQ_KEY_PRINT_PIN, boost_off_level_locked(), "print_boost");
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
@@ -527,7 +581,7 @@ esp_err_t platform_direct_printer_connect(uint32_t timeout_ms) {
|
||||
}
|
||||
|
||||
if (!s_state.connected) {
|
||||
set_gpio_level_if_valid(CONFIG_TQ_KEY_PRINT_PIN, BOOST_ON_LEVEL);
|
||||
set_gpio_level_if_valid(CONFIG_TQ_KEY_PRINT_PIN, boost_on_level_locked());
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
safe_drive_off_locked(true);
|
||||
s_state.connected = true;
|
||||
@@ -577,6 +631,103 @@ esp_err_t platform_direct_printer_get_sensors(platform_printer_sensors_t *out_se
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t platform_direct_printer_get_debug_config(platform_direct_debug_config_t *out_config) {
|
||||
#if !CONFIG_TQ_DIRECT_PRINTER_ENABLE
|
||||
(void)out_config;
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
#else
|
||||
if (out_config == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
esp_err_t init_rc = platform_direct_printer_init();
|
||||
if (init_rc != ESP_OK) {
|
||||
return init_rc;
|
||||
}
|
||||
if (xSemaphoreTake(s_state.lock, pdMS_TO_TICKS(500)) != pdTRUE) {
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
*out_config = s_state.debug;
|
||||
xSemaphoreGive(s_state.lock);
|
||||
return ESP_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
esp_err_t platform_direct_printer_set_debug_config(const platform_direct_debug_config_t *config,
|
||||
bool reset_defaults,
|
||||
char *err,
|
||||
size_t err_len) {
|
||||
#if !CONFIG_TQ_DIRECT_PRINTER_ENABLE
|
||||
(void)config;
|
||||
(void)reset_defaults;
|
||||
write_err(err, err_len, "direct backend disabled");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
#else
|
||||
if (config == NULL && !reset_defaults) {
|
||||
write_err(err, err_len, "invalid args");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_err_t init_rc = platform_direct_printer_init();
|
||||
if (init_rc != ESP_OK) {
|
||||
write_err(err, err_len, "direct backend not initialized");
|
||||
return init_rc;
|
||||
}
|
||||
if (xSemaphoreTake(s_state.lock, pdMS_TO_TICKS(1000)) != pdTRUE) {
|
||||
write_err(err, err_len, "direct printer lock timeout");
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
|
||||
if (reset_defaults) {
|
||||
set_debug_defaults_locked();
|
||||
}
|
||||
|
||||
if (config != NULL) {
|
||||
if (config->shift_clock_high_us < DEBUG_SHIFT_CLOCK_US_MIN ||
|
||||
config->shift_clock_high_us > DEBUG_SHIFT_CLOCK_US_MAX ||
|
||||
config->shift_clock_low_us < DEBUG_SHIFT_CLOCK_US_MIN ||
|
||||
config->shift_clock_low_us > DEBUG_SHIFT_CLOCK_US_MAX) {
|
||||
xSemaphoreGive(s_state.lock);
|
||||
write_err(err, err_len, "shift clock us out of range (1..50)");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (config->latch_pulse_us < DEBUG_LATCH_PULSE_US_MIN ||
|
||||
config->latch_pulse_us > DEBUG_LATCH_PULSE_US_MAX) {
|
||||
xSemaphoreGive(s_state.lock);
|
||||
write_err(err, err_len, "latch pulse us out of range (1..50)");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (config->override_strobe_on_us != 0 &&
|
||||
(config->override_strobe_on_us < 100 || config->override_strobe_on_us > 10000)) {
|
||||
xSemaphoreGive(s_state.lock);
|
||||
write_err(err, err_len, "strobe_on_us must be 0 or 100..10000");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (config->override_strobe_interval_us > 10000) {
|
||||
xSemaphoreGive(s_state.lock);
|
||||
write_err(err, err_len, "strobe_interval_us must be 0..10000");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (config->override_motor_step_us != 0 &&
|
||||
(config->override_motor_step_us < 100 || config->override_motor_step_us > 20000)) {
|
||||
xSemaphoreGive(s_state.lock);
|
||||
write_err(err, err_len, "motor_step_us must be 0 or 100..20000");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (config->override_steps_per_line > 8) {
|
||||
xSemaphoreGive(s_state.lock);
|
||||
write_err(err, err_len, "steps_per_line must be 0..8");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
s_state.debug = *config;
|
||||
}
|
||||
|
||||
safe_drive_off_locked(s_state.connected);
|
||||
xSemaphoreGive(s_state.lock);
|
||||
return ESP_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
esp_err_t platform_direct_printer_print(const platform_direct_print_request_t *request,
|
||||
char *err,
|
||||
size_t err_len) {
|
||||
@@ -610,19 +761,6 @@ esp_err_t platform_direct_printer_print(const platform_direct_print_request_t *r
|
||||
timeout_ms = runtime_policy_direct_printer_operation_timeout_ms();
|
||||
}
|
||||
|
||||
const uint16_t strobe_on_us = (request->strobe_on_time_us > 0)
|
||||
? request->strobe_on_time_us
|
||||
: runtime_policy_direct_printer_strobe_on_us();
|
||||
const uint16_t strobe_interval_us = (request->strobe_interval_us > 0)
|
||||
? request->strobe_interval_us
|
||||
: runtime_policy_direct_printer_strobe_interval_us();
|
||||
const uint16_t motor_step_us = (request->motor_step_delay_us > 0)
|
||||
? request->motor_step_delay_us
|
||||
: runtime_policy_direct_printer_motor_step_us();
|
||||
const uint8_t steps_per_line = (request->motor_steps_per_line > 0)
|
||||
? request->motor_steps_per_line
|
||||
: runtime_policy_direct_printer_steps_per_line();
|
||||
|
||||
if (xSemaphoreTake(s_state.lock, pdMS_TO_TICKS(1000)) != pdTRUE) {
|
||||
write_err(err, err_len, "direct printer lock timeout");
|
||||
return ESP_ERR_TIMEOUT;
|
||||
@@ -634,6 +772,32 @@ esp_err_t platform_direct_printer_print(const platform_direct_print_request_t *r
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
uint16_t strobe_on_us = (request->strobe_on_time_us > 0)
|
||||
? request->strobe_on_time_us
|
||||
: runtime_policy_direct_printer_strobe_on_us();
|
||||
uint16_t strobe_interval_us = (request->strobe_interval_us > 0)
|
||||
? request->strobe_interval_us
|
||||
: runtime_policy_direct_printer_strobe_interval_us();
|
||||
uint16_t motor_step_us = (request->motor_step_delay_us > 0)
|
||||
? request->motor_step_delay_us
|
||||
: runtime_policy_direct_printer_motor_step_us();
|
||||
uint8_t steps_per_line = (request->motor_steps_per_line > 0)
|
||||
? request->motor_steps_per_line
|
||||
: runtime_policy_direct_printer_steps_per_line();
|
||||
|
||||
if (s_state.debug.override_strobe_on_us > 0) {
|
||||
strobe_on_us = s_state.debug.override_strobe_on_us;
|
||||
}
|
||||
if (s_state.debug.override_strobe_interval_us > 0) {
|
||||
strobe_interval_us = s_state.debug.override_strobe_interval_us;
|
||||
}
|
||||
if (s_state.debug.override_motor_step_us > 0) {
|
||||
motor_step_us = s_state.debug.override_motor_step_us;
|
||||
}
|
||||
if (s_state.debug.override_steps_per_line > 0) {
|
||||
steps_per_line = s_state.debug.override_steps_per_line;
|
||||
}
|
||||
|
||||
esp_err_t rc = ESP_OK;
|
||||
if (!request->ignore_precheck) {
|
||||
rc = precheck_before_print_locked(err, err_len);
|
||||
@@ -725,6 +889,9 @@ esp_err_t platform_direct_printer_gap_move(uint32_t timeout_ms, char *err, size_
|
||||
esp_err_t rc = ESP_OK;
|
||||
uint16_t steps = runtime_policy_direct_printer_gap_steps();
|
||||
uint16_t step_delay_us = runtime_policy_direct_printer_motor_step_us();
|
||||
if (s_state.debug.override_motor_step_us > 0) {
|
||||
step_delay_us = s_state.debug.override_motor_step_us;
|
||||
}
|
||||
platform_printer_sensors_t sensors = {0};
|
||||
sample_sensors_locked(&sensors);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user