From ac52685a3734cbcb26bab56285a28f07ccc4fcba Mon Sep 17 00:00:00 2001 From: XiNGRZ Date: Fri, 20 Oct 2023 12:05:44 +0800 Subject: [PATCH] knob: Make profiles configurable via DTS --- .../boards/arm/hw75_dynamic/hw75_dynamic.dts | 2 ++ .../knob/include/knob/drivers/profile.h | 4 +-- .../sensor/knob/lib/include/knob/math.h | 2 +- config/drivers/sensor/knob/profile/spring.c | 22 ++++++++----- config/drivers/sensor/knob/profile/switch.c | 31 ++++++++++++------- .../knob/profile/zmk,knob-profile-spring.yaml | 6 ++++ .../knob/profile/zmk,knob-profile-switch.yaml | 6 ++++ 7 files changed, 51 insertions(+), 22 deletions(-) diff --git a/config/boards/arm/hw75_dynamic/hw75_dynamic.dts b/config/boards/arm/hw75_dynamic/hw75_dynamic.dts index 462c575a..fec79fa7 100644 --- a/config/boards/arm/hw75_dynamic/hw75_dynamic.dts +++ b/config/boards/arm/hw75_dynamic/hw75_dynamic.dts @@ -104,6 +104,7 @@ torque-limit-mv = <1500>; velocity-pid = <50 0 0>; angle-pid = <100000 0 3500>; + minimal-movement-deg = <20>; }; profile_damped: damped@4 { @@ -135,6 +136,7 @@ torque-limit-mv = <1500>; velocity-pid = <50 0 0>; angle-pid = <100000 0 3500>; + on-off-distance-deg = <80>; }; }; diff --git a/config/drivers/sensor/knob/include/knob/drivers/profile.h b/config/drivers/sensor/knob/include/knob/drivers/profile.h index 981c193f..e2e60de2 100644 --- a/config/drivers/sensor/knob/include/knob/drivers/profile.h +++ b/config/drivers/sensor/knob/include/knob/drivers/profile.h @@ -25,10 +25,10 @@ ((float)DT_INST_PROP_BY_IDX(0, prop, 2) / 1000.0f) #define KNOB_PROFILE_HAS_VELOCITY_PID DT_INST_NODE_HAS_PROP(0, velocity_pid) -#define KNOB_PROFILE_VELOCITY_PID Z_KNOB_PROFILE_PID(velocity_pid) +#define KNOB_PROFILE_VELOCITY_PID Z_KNOB_PROFILE_PID(velocity_pid) #define KNOB_PROFILE_HAS_ANGLE_PID DT_INST_NODE_HAS_PROP(0, angle_pid) -#define KNOB_PROFILE_ANGLE_PID Z_KNOB_PROFILE_PID(angle_pid) +#define KNOB_PROFILE_ANGLE_PID Z_KNOB_PROFILE_PID(angle_pid) #ifdef __cplusplus extern "C" { diff --git a/config/drivers/sensor/knob/lib/include/knob/math.h b/config/drivers/sensor/knob/lib/include/knob/math.h index b31778d4..d406b4e1 100644 --- a/config/drivers/sensor/knob/lib/include/knob/math.h +++ b/config/drivers/sensor/knob/lib/include/knob/math.h @@ -67,4 +67,4 @@ static inline float norm_rad(float radian) /** * @brief Degree to radian */ -#define deg_to_rad(deg) (deg / 360.0f * PI2) +#define deg_to_rad(deg) ((float)deg / 360.0f * PI2) diff --git a/config/drivers/sensor/knob/profile/spring.c b/config/drivers/sensor/knob/profile/spring.c index 39f89074..a571510a 100644 --- a/config/drivers/sensor/knob/profile/spring.c +++ b/config/drivers/sensor/knob/profile/spring.c @@ -16,15 +16,15 @@ #include LOG_MODULE_REGISTER(knob_spring, CONFIG_ZMK_LOG_LEVEL); -#define CENTER (deg_to_rad(180.0f)) -#define UP (deg_to_rad(160.0f)) -#define DN (deg_to_rad(200.0f)) - struct knob_spring_config { KNOB_PROFILE_CFG_ROM; + uint32_t minimal_movement_deg; }; struct knob_spring_data { + float center; + float up; + float down; int32_t value; int32_t last_report; }; @@ -32,6 +32,7 @@ struct knob_spring_data { static int knob_spring_enable(const struct device *dev) { const struct knob_spring_config *cfg = dev->config; + struct knob_spring_data *data = dev->data; motor_set_torque_limit(cfg->motor, KNOB_PROFILE_TORQUE_LIMIT); @@ -43,6 +44,10 @@ static int knob_spring_enable(const struct device *dev) motor_set_angle_pid(cfg->motor, KNOB_PROFILE_ANGLE_PID); #endif /* KNOB_PROFILE_HAS_ANGLE_PID */ + data->center = deg_to_rad(180); + data->up = data->center - deg_to_rad(cfg->minimal_movement_deg); + data->down = data->center + deg_to_rad(cfg->minimal_movement_deg); + return 0; } @@ -61,16 +66,16 @@ static int knob_spring_tick(const struct device *dev, struct motor_control *mc) ARG_UNUSED(mc); float p = knob_get_position(cfg->knob); - if (p < UP) { + if (p < data->up) { data->value = 1; - } else if (p > DN) { + } else if (p > data->down) { data->value = -1; } else { data->value = 0; } mc->mode = ANGLE; - mc->target = CENTER; + mc->target = data->center; return 0; } @@ -106,7 +111,8 @@ static const struct knob_profile_api knob_spring_api = { static struct knob_spring_data knob_spring_data; -static const struct knob_spring_config knob_spring_cfg = { KNOB_PROFILE_CFG_INIT }; +static const struct knob_spring_config knob_spring_cfg = { + .minimal_movement_deg = DT_INST_PROP(0, minimal_movement_deg), KNOB_PROFILE_CFG_INIT}; DEVICE_DT_INST_DEFINE(0, knob_spring_init, NULL, &knob_spring_data, &knob_spring_cfg, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, &knob_spring_api); diff --git a/config/drivers/sensor/knob/profile/switch.c b/config/drivers/sensor/knob/profile/switch.c index 7870a0dc..27541777 100644 --- a/config/drivers/sensor/knob/profile/switch.c +++ b/config/drivers/sensor/knob/profile/switch.c @@ -16,15 +16,17 @@ #include LOG_MODULE_REGISTER(knob_switch, CONFIG_ZMK_LOG_LEVEL); -#define CENTER (deg_to_rad(180.0f)) -#define ON (deg_to_rad(140.0f)) -#define OFF (deg_to_rad(220.0f)) - struct knob_switch_config { KNOB_PROFILE_CFG_ROM; + uint32_t on_off_distance_deg; }; struct knob_switch_data { + float center; + float on; + float on_2; + float off; + float off_2; bool state; bool last_report; }; @@ -44,6 +46,12 @@ static int knob_switch_enable(const struct device *dev) motor_set_angle_pid(cfg->motor, KNOB_PROFILE_ANGLE_PID); #endif /* KNOB_PROFILE_HAS_ANGLE_PID */ + data->center = deg_to_rad(180); + data->off = data->center + deg_to_rad(cfg->on_off_distance_deg) * 0.5f; + data->off_2 = data->center + deg_to_rad(cfg->on_off_distance_deg) * 0.25f; + data->on = data->center - deg_to_rad(cfg->on_off_distance_deg) * 0.5f; + data->on_2 = data->center - deg_to_rad(cfg->on_off_distance_deg) * 0.25f; + data->state = false; return 0; @@ -65,14 +73,14 @@ static int knob_switch_tick(const struct device *dev, struct motor_control *mc) mc->mode = ANGLE; float p = knob_get_position(cfg->knob); - if (p < ON + (CENTER - ON) / 2.0f) { - mc->target = ON; + if (p < data->on_2) { + mc->target = data->on; data->state = true; - } else if (p < OFF - (OFF - CENTER) / 2.0f) { - mc->target = CENTER + (p - CENTER) * 2.0f; - } else { - mc->target = OFF; + } else if (p > data->off_2) { + mc->target = data->off; data->state = false; + } else { + mc->target = data->center + (p - data->center) * 2.0f; } return 0; @@ -109,7 +117,8 @@ static const struct knob_profile_api knob_switch_api = { static struct knob_switch_data knob_switch_data; -static const struct knob_switch_config knob_switch_cfg = { KNOB_PROFILE_CFG_INIT }; +static const struct knob_switch_config knob_switch_cfg = { + .on_off_distance_deg = DT_INST_PROP(0, on_off_distance_deg), KNOB_PROFILE_CFG_INIT}; DEVICE_DT_INST_DEFINE(0, knob_switch_init, NULL, &knob_switch_data, &knob_switch_cfg, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, &knob_switch_api); diff --git a/config/dts/bindings/sensor/knob/profile/zmk,knob-profile-spring.yaml b/config/dts/bindings/sensor/knob/profile/zmk,knob-profile-spring.yaml index 345df841..283edbb3 100644 --- a/config/dts/bindings/sensor/knob/profile/zmk,knob-profile-spring.yaml +++ b/config/dts/bindings/sensor/knob/profile/zmk,knob-profile-spring.yaml @@ -6,3 +6,9 @@ description: Knob spring profile compatible: "zmk,knob-profile-spring" include: knob-profile.yaml + +properties: + minimal-movement-deg: + type: int + required: false + default: 20 diff --git a/config/dts/bindings/sensor/knob/profile/zmk,knob-profile-switch.yaml b/config/dts/bindings/sensor/knob/profile/zmk,knob-profile-switch.yaml index 8f8b910b..07bd1c6b 100644 --- a/config/dts/bindings/sensor/knob/profile/zmk,knob-profile-switch.yaml +++ b/config/dts/bindings/sensor/knob/profile/zmk,knob-profile-switch.yaml @@ -6,3 +6,9 @@ description: Knob switch profile compatible: "zmk,knob-profile-switch" include: knob-profile.yaml + +properties: + on-off-distance-deg: + type: int + required: false + default: 80