Compare commits

...

3 Commits

Author SHA1 Message Date
Dasky
fccea80f26
Merge a11c01be28 into 88afd53b1f 2024-11-21 17:16:55 +11:00
Pablo Martínez
88afd53b1f
[CLI] Refactor painter arguments to table instead of commandline (#24456)
Co-authored-by: Nick Brassel <nick@tzarc.org>
2024-11-21 17:16:46 +11:00
Dasky
a11c01be28 Improve I2C behaviour while polling. 2024-11-17 15:53:27 +00:00
5 changed files with 56 additions and 42 deletions

View File

@ -17,6 +17,7 @@
#define AZOTEQ_IQS5XX_REG_PREVIOUS_CYCLE_TIME 0x000C #define AZOTEQ_IQS5XX_REG_PREVIOUS_CYCLE_TIME 0x000C
#define AZOTEQ_IQS5XX_REG_SYSTEM_CONTROL_1 0x0432 #define AZOTEQ_IQS5XX_REG_SYSTEM_CONTROL_1 0x0432
#define AZOTEQ_IQS5XX_REG_REPORT_RATE_ACTIVE 0x057A #define AZOTEQ_IQS5XX_REG_REPORT_RATE_ACTIVE 0x057A
#define AZOTEQ_IQS5XX_REG_IDLE_MODE_TIMEOUT 0x0586
#define AZOTEQ_IQS5XX_REG_SYSTEM_CONFIG_0 0x058E #define AZOTEQ_IQS5XX_REG_SYSTEM_CONFIG_0 0x058E
#define AZOTEQ_IQS5XX_REG_SYSTEM_CONFIG_1 0x058F #define AZOTEQ_IQS5XX_REG_SYSTEM_CONFIG_1 0x058F
#define AZOTEQ_IQS5XX_REG_X_RESOLUTION 0x066E #define AZOTEQ_IQS5XX_REG_X_RESOLUTION 0x066E
@ -77,6 +78,10 @@
#ifndef AZOTEQ_IQS5XX_ZOOM_CONSECUTIVE_DISTANCE #ifndef AZOTEQ_IQS5XX_ZOOM_CONSECUTIVE_DISTANCE
# define AZOTEQ_IQS5XX_ZOOM_CONSECUTIVE_DISTANCE 0x19 # define AZOTEQ_IQS5XX_ZOOM_CONSECUTIVE_DISTANCE 0x19
#endif #endif
#ifndef AZOTEQ_IQS5XX_EVENT_MODE
// Event mode can't be used until the pointing code has changed (stuck buttons)
# define AZOTEQ_IQS5XX_EVENT_MODE false
#endif
#if defined(AZOTEQ_IQS5XX_TPS43) #if defined(AZOTEQ_IQS5XX_TPS43)
# define AZOTEQ_IQS5XX_WIDTH_MM 43 # define AZOTEQ_IQS5XX_WIDTH_MM 43
@ -112,12 +117,6 @@ static struct {
uint16_t resolution_y; uint16_t resolution_y;
} azoteq_iqs5xx_device_resolution_t; } azoteq_iqs5xx_device_resolution_t;
i2c_status_t azoteq_iqs5xx_wake(void) {
uint8_t data = 0;
i2c_status_t status = i2c_read_register16(AZOTEQ_IQS5XX_ADDRESS, AZOTEQ_IQS5XX_REG_PREVIOUS_CYCLE_TIME, (uint8_t *)&data, sizeof(data), 1);
wait_us(150);
return status;
}
i2c_status_t azoteq_iqs5xx_end_session(void) { i2c_status_t azoteq_iqs5xx_end_session(void) {
const uint8_t END_BYTE = 1; // any data const uint8_t END_BYTE = 1; // any data
return i2c_write_register16(AZOTEQ_IQS5XX_ADDRESS, AZOTEQ_IQS5XX_REG_END_COMMS, &END_BYTE, 1, AZOTEQ_IQS5XX_TIMEOUT_MS); return i2c_write_register16(AZOTEQ_IQS5XX_ADDRESS, AZOTEQ_IQS5XX_REG_END_COMMS, &END_BYTE, 1, AZOTEQ_IQS5XX_TIMEOUT_MS);
@ -324,14 +323,19 @@ static i2c_status_t azoteq_iqs5xx_init_status = 1;
void azoteq_iqs5xx_init(void) { void azoteq_iqs5xx_init(void) {
i2c_init(); i2c_init();
azoteq_iqs5xx_wake(); i2c_ping_address(AZOTEQ_IQS5XX_ADDRESS, 1); // wake
azoteq_iqs5xx_reset_suspend(true, false, true); azoteq_iqs5xx_reset_suspend(true, false, true);
wait_ms(100); wait_ms(100);
azoteq_iqs5xx_wake(); i2c_ping_address(AZOTEQ_IQS5XX_ADDRESS, 1); // wake
if (azoteq_iqs5xx_get_product() != AZOTEQ_IQS5XX_UNKNOWN) { if (azoteq_iqs5xx_get_product() != AZOTEQ_IQS5XX_UNKNOWN) {
azoteq_iqs5xx_setup_resolution(); azoteq_iqs5xx_setup_resolution();
azoteq_iqs5xx_init_status = azoteq_iqs5xx_set_report_rate(AZOTEQ_IQS5XX_REPORT_RATE, AZOTEQ_IQS5XX_ACTIVE, false); azoteq_iqs5xx_init_status = azoteq_iqs5xx_set_report_rate(AZOTEQ_IQS5XX_REPORT_RATE, AZOTEQ_IQS5XX_ACTIVE, false);
azoteq_iqs5xx_init_status |= azoteq_iqs5xx_set_event_mode(false, false); azoteq_iqs5xx_init_status = azoteq_iqs5xx_set_report_rate(AZOTEQ_IQS5XX_REPORT_RATE, AZOTEQ_IQS5XX_IDLE, false);
azoteq_iqs5xx_init_status = azoteq_iqs5xx_set_report_rate(AZOTEQ_IQS5XX_REPORT_RATE, AZOTEQ_IQS5XX_IDLE_TOUCH, false);
uint8_t no_timeout = 255;
azoteq_iqs5xx_init_status |= i2c_write_register16(AZOTEQ_IQS5XX_ADDRESS, AZOTEQ_IQS5XX_REG_IDLE_MODE_TIMEOUT, &no_timeout, 1, AZOTEQ_IQS5XX_TIMEOUT_MS); // Don't enter LP1, LP2 states
azoteq_iqs5xx_init_status |= azoteq_iqs5xx_set_event_mode(AZOTEQ_IQS5XX_EVENT_MODE, false);
azoteq_iqs5xx_init_status |= azoteq_iqs5xx_set_reati(true, false); azoteq_iqs5xx_init_status |= azoteq_iqs5xx_set_reati(true, false);
#if defined(AZOTEQ_IQS5XX_ROTATION_90) #if defined(AZOTEQ_IQS5XX_ROTATION_90)
azoteq_iqs5xx_init_status |= azoteq_iqs5xx_set_xy_config(false, true, true, true, false); azoteq_iqs5xx_init_status |= azoteq_iqs5xx_set_xy_config(false, true, true, true, false);
@ -349,20 +353,18 @@ void azoteq_iqs5xx_init(void) {
report_mouse_t azoteq_iqs5xx_get_report(report_mouse_t mouse_report) { report_mouse_t azoteq_iqs5xx_get_report(report_mouse_t mouse_report) {
report_mouse_t temp_report = {0}; report_mouse_t temp_report = {0};
static uint8_t previous_button_state = 0;
static uint8_t read_error_count = 0;
if (azoteq_iqs5xx_init_status == I2C_STATUS_SUCCESS) { if (azoteq_iqs5xx_init_status == I2C_STATUS_SUCCESS) {
azoteq_iqs5xx_base_data_t base_data = {0}; azoteq_iqs5xx_base_data_t base_data = {0};
#if !defined(POINTING_DEVICE_MOTION_PIN)
azoteq_iqs5xx_wake();
#endif
i2c_status_t status = azoteq_iqs5xx_get_base_data(&base_data); i2c_status_t status = azoteq_iqs5xx_get_base_data(&base_data);
bool ignore_movement = false; bool ignore_movement = false;
if (status == I2C_STATUS_SUCCESS) { if (status == I2C_STATUS_SUCCESS) {
// pd_dprintf("IQS5XX - previous cycle time: %d \n", base_data.previous_cycle_time); #ifdef POINTING_DEVICE_DEBUG
read_error_count = 0; if (base_data.previous_cycle_time > AZOTEQ_IQS5XX_REPORT_RATE) {
pd_dprintf("IQS5XX - previous cycle time missed, took: %dms\n", base_data.previous_cycle_time);
}
#endif
if (base_data.gesture_events_0.single_tap || base_data.gesture_events_0.press_and_hold) { if (base_data.gesture_events_0.single_tap || base_data.gesture_events_0.press_and_hold) {
pd_dprintf("IQS5XX - Single tap/hold.\n"); pd_dprintf("IQS5XX - Single tap/hold.\n");
temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON1); temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON1);
@ -403,20 +405,11 @@ report_mouse_t azoteq_iqs5xx_get_report(report_mouse_t mouse_report) {
temp_report.y = CONSTRAIN_HID_XY(AZOTEQ_IQS5XX_COMBINE_H_L_BYTES(base_data.y.h, base_data.y.l)); temp_report.y = CONSTRAIN_HID_XY(AZOTEQ_IQS5XX_COMBINE_H_L_BYTES(base_data.y.h, base_data.y.l));
} }
previous_button_state = temp_report.buttons;
} else { } else {
if (read_error_count > 10) { pd_dprintf("IQS5XX - get report failed, i2c status: %d \n", status);
read_error_count = 0;
previous_button_state = 0;
} else {
read_error_count++;
}
temp_report.buttons = previous_button_state;
pd_dprintf("IQS5XX - get report failed: %d \n", status);
} }
} else { } else {
pd_dprintf("IQS5XX - Init failed: %d \n", azoteq_iqs5xx_init_status); pd_dprintf("IQS5XX - Init failed, i2c status: %d \n", azoteq_iqs5xx_init_status);
} }
return temp_report; return temp_report;

View File

@ -173,7 +173,8 @@ typedef struct {
# define AZOTEQ_IQS5XX_REPORT_RATE 10 # define AZOTEQ_IQS5XX_REPORT_RATE 10
#endif #endif
#if !defined(POINTING_DEVICE_TASK_THROTTLE_MS) && !defined(POINTING_DEVICE_MOTION_PIN) #if !defined(POINTING_DEVICE_TASK_THROTTLE_MS) && !defined(POINTING_DEVICE_MOTION_PIN)
# define POINTING_DEVICE_TASK_THROTTLE_MS AZOTEQ_IQS5XX_REPORT_RATE // Polling the Azoteq isn't recommended, ensuring we only poll after the report is ready stops any unexpected NACKs
# define POINTING_DEVICE_TASK_THROTTLE_MS AZOTEQ_IQS5XX_REPORT_RATE + 1
#endif #endif
const pointing_device_driver_t azoteq_iqs5xx_pointing_device_driver; const pointing_device_driver_t azoteq_iqs5xx_pointing_device_driver;

View File

@ -60,9 +60,7 @@ def painter_convert_graphics(cli):
return return
# Work out the text substitutions for rendering the output data # Work out the text substitutions for rendering the output data
args_str = " ".join((f"--{arg} {getattr(cli.args, arg.replace('-', '_'))}" for arg in ["input", "output", "format", "no-rle", "no-deltas"])) subs = generate_subs(cli, out_bytes, image_metadata=metadata, command_name="painter_convert_graphics")
command = f"qmk painter-convert-graphics {args_str}"
subs = generate_subs(cli, out_bytes, image_metadata=metadata, command=command)
# Render and write the header file # Render and write the header file
header_text = render_header(subs) header_text = render_header(subs)

View File

@ -61,10 +61,8 @@ def painter_convert_font_image(cli):
return return
# Work out the text substitutions for rendering the output data # Work out the text substitutions for rendering the output data
args_str = " ".join((f"--{arg} {getattr(cli.args, arg.replace('-', '_'))}" for arg in ["input", "output", "no-ascii", "unicode-glyphs", "format", "no-rle"]))
command = f"qmk painter-convert-font-image {args_str}"
metadata = {"glyphs": _generate_font_glyphs_list(not cli.args.no_ascii, cli.args.unicode_glyphs)} metadata = {"glyphs": _generate_font_glyphs_list(not cli.args.no_ascii, cli.args.unicode_glyphs)}
subs = generate_subs(cli, out_bytes, font_metadata=metadata, command=command) subs = generate_subs(cli, out_bytes, font_metadata=metadata, command_name="painter_convert_font_image")
# Render and write the header file # Render and write the header file
header_text = render_header(subs) header_text = render_header(subs)

View File

@ -3,6 +3,7 @@
import datetime import datetime
import math import math
import re import re
from pathlib import Path
from string import Template from string import Template
from PIL import Image, ImageOps from PIL import Image, ImageOps
@ -137,10 +138,31 @@ def _render_image_metadata(metadata):
return "\n".join(lines) return "\n".join(lines)
def generate_subs(cli, out_bytes, *, font_metadata=None, image_metadata=None, command): def command_args_str(cli, command_name):
"""Given a command name, introspect milc to get the arguments passed in."""
args = {}
max_length = 0
for arg_name, was_passed in cli.args_passed[command_name].items():
max_length = max(max_length, len(arg_name))
val = getattr(cli.args, arg_name.replace("-", "_"))
# do not leak full paths, keep just file name
if isinstance(val, Path):
val = val.name
args[arg_name] = val
return "\n".join(f"// {arg_name.ljust(max_length)} | {val}" for arg_name, val in args.items())
def generate_subs(cli, out_bytes, *, font_metadata=None, image_metadata=None, command_name):
if font_metadata is not None and image_metadata is not None: if font_metadata is not None and image_metadata is not None:
raise ValueError("Cant generate subs for font and image at the same time") raise ValueError("Cant generate subs for font and image at the same time")
args = command_args_str(cli, command_name)
subs = { subs = {
"year": datetime.date.today().strftime("%Y"), "year": datetime.date.today().strftime("%Y"),
"input_file": cli.args.input.name, "input_file": cli.args.input.name,
@ -148,7 +170,8 @@ def generate_subs(cli, out_bytes, *, font_metadata=None, image_metadata=None, co
"byte_count": len(out_bytes), "byte_count": len(out_bytes),
"bytes_lines": render_bytes(out_bytes), "bytes_lines": render_bytes(out_bytes),
"format": cli.args.format, "format": cli.args.format,
"generator_command": command, "generator_command": command_name.replace("_", "-"),
"command_args": args,
} }
if font_metadata is not None: if font_metadata is not None:
@ -167,7 +190,7 @@ def generate_subs(cli, out_bytes, *, font_metadata=None, image_metadata=None, co
subs.update({ subs.update({
"generated_type": "image", "generated_type": "image",
"var_prefix": "gfx", "var_prefix": "gfx",
"generator_command": command, "generator_command": command_name,
"metadata": _render_image_metadata(image_metadata), "metadata": _render_image_metadata(image_metadata),
}) })
@ -183,7 +206,8 @@ license_template = """\
// Copyright ${year} QMK -- generated source code only, ${generated_type} retains original copyright // Copyright ${year} QMK -- generated source code only, ${generated_type} retains original copyright
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
// This file was auto-generated by `${generator_command}` // This file was auto-generated by `${generator_command}` with arguments:
${command_args}
""" """