Skip to content

Commit 62aefc5

Browse files
purdeaandreiskullydazed
authored andcommitted
Haptic and solenoid cleanup (#9700)
* solenoid: remove two functions that do nothing. These functions modify the argument, and so they do nothing. Note: versions of these functions exist in mtdjr's user folder, however to core solenoid support and mtdjr user-specific solenoid support are exclusive (only one can be used at a time). So removing these confusing functions does no harm. * solenoid: bugfix: don't allow dwell time to go 1ms below minimum time. The previous code allowed dwell time to go 1ms below the configured minimum. This change corrects it. * solenoid: bugfix: when incrementing above maximum dwell time, jump back to minimum, not to 1 The previous code used to jump back to 1, which might be way under the configured minimum setting. * solenoid: bugfix: on startup actually use the eeprom-stored dwell-time This is because the dwell time is stored in two variables. * solenoid: bugfix: on haptic_reset, actually use the newly set default dwell time. This is needed because dwell time is configured in two variables. * solenoid: on HPT_RST set buzz to a default value * solenoid: buzz: reworked to make more configurable. Previous behaviour maintained. * solenoid: documentation: clarify meaning of dwell time * solenoid: add feature SOLENOID_DWELL_STEP_SIZE * solenoid: documentation: added note about the precision of the solenoid time settings * haptic: Correctly call haptic_reset when eeprom is corrupt. * haptic: improve what happens if haptic is enabled without erasing eeprom * haptic: improve what happens if solenoid is enabled without erasing eeprom * drivers/haptic: fix compilation issue, when haptic is enabled, but solenoid isn't
1 parent 56dd52d commit 62aefc5

File tree

5 files changed

+84
-33
lines changed

5 files changed

+84
-33
lines changed

docs/feature_haptic_feedback.md

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,21 @@ First you will need a build a circuit to drive the solenoid through a mosfet as
4242
[Wiring diagram provided by Adafruit](https://playground.arduino.cc/uploads/Learning/solenoid_driver.pdf)
4343

4444

45-
| Settings | Default | Description |
46-
|--------------------------|---------------|-------------------------------------------------------|
47-
|`SOLENOID_PIN` | *Not defined* |Configures the pin that the Solenoid is connected to. |
48-
|`SOLENOID_DEFAULT_DWELL` | `12` ms |Configures the default dwell time for the solenoid. |
49-
|`SOLENOID_MIN_DWELL` | `4` ms |Sets the lower limit for the dwell. |
50-
|`SOLENOID_MAX_DWELL` | `100` ms |Sets the upper limit for the dwell. |
51-
52-
?> Dwell time is how long the "plunger" stays activated. The dwell time changes how the solenoid sounds.
45+
| Settings | Default | Description |
46+
|----------------------------|----------------------|-------------------------------------------------------|
47+
|`SOLENOID_PIN` | *Not defined* |Configures the pin that the Solenoid is connected to. |
48+
|`SOLENOID_DEFAULT_DWELL` | `12` ms |Configures the default dwell time for the solenoid. |
49+
|`SOLENOID_MIN_DWELL` | `4` ms |Sets the lower limit for the dwell. |
50+
|`SOLENOID_MAX_DWELL` | `100` ms |Sets the upper limit for the dwell. |
51+
|`SOLENOID_DWELL_STEP_SIZE` | `1` ms |The step size to use when `HPT_DWL*` keycodes are sent |
52+
|`SOLENOID_DEFAULT_BUZZ` | `0` (disabled) |On HPT_RST buzz is set "on" if this is "1" |
53+
|`SOLENOID_BUZZ_ACTUATED` | `SOLENOID_MIN_DWELL` |Actuated-time when the solenoid is in buzz mode |
54+
|`SOLENOID_BUZZ_NONACTUATED` | `SOLENOID_MIN_DWELL` |Non-Actuated-time when the solenoid is in buzz mode |
55+
56+
* If solenoid buzz is off, then dwell time is how long the "plunger" stays activated. The dwell time changes how the solenoid sounds.
57+
* If solenoid buzz is on, then dwell time sets the length of the buzz, while `SOLENOID_BUZZ_ACTUATED` and `SOLENOID_BUZZ_NONACTUATED` set the (non-)actuation times withing the buzz period.
58+
* With the current implementation, for any of the above time settings, the precision of these settings may be affected by how fast the keyboard is able to scan the matrix.
59+
Therefore, if the keyboards scanning routine is slow, it may be preferable to set `SOLENOID_DWELL_STEP_SIZE` to a value slightly smaller than the time it takes to scan the keyboard.
5360

5461
Beware that some pins may be powered during bootloader (ie. A13 on the STM32F303 chip) and will result in the solenoid kept in the on state through the whole flashing process. This may overheat and damage the solenoid. If you find that the pin the solenoid is connected to is triggering the solenoid during bootloader/DFU, select another pin.
5562

drivers/haptic/haptic.c

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,18 @@ void haptic_init(void) {
3333
eeconfig_init();
3434
}
3535
haptic_config.raw = eeconfig_read_haptic();
36-
if (haptic_config.mode < 1) {
37-
haptic_config.mode = 1;
38-
}
39-
if (!haptic_config.mode) {
40-
dprintf("No haptic config found in eeprom, setting default configs\n");
36+
#ifdef SOLENOID_ENABLE
37+
solenoid_set_dwell(haptic_config.dwell);
38+
#endif
39+
if ((haptic_config.raw == 0)
40+
#ifdef SOLENOID_ENABLE
41+
|| (haptic_config.dwell == 0)
42+
#endif
43+
) {
44+
// this will be called, if the eeprom is not corrupt,
45+
// but the previous firmware didn't have haptic enabled,
46+
// or the previous firmware didn't have solenoid enabled,
47+
// and the current one has solenoid enabled.
4148
haptic_reset();
4249
}
4350
#ifdef SOLENOID_ENABLE
@@ -118,25 +125,37 @@ void haptic_mode_decrease(void) {
118125
}
119126

120127
void haptic_dwell_increase(void) {
121-
uint8_t dwell = haptic_config.dwell + 1;
122128
#ifdef SOLENOID_ENABLE
129+
int16_t next_dwell = ((int16_t)haptic_config.dwell) + SOLENOID_DWELL_STEP_SIZE;
123130
if (haptic_config.dwell >= SOLENOID_MAX_DWELL) {
124-
dwell = 1;
131+
// if it's already at max, we wrap back to min
132+
next_dwell = SOLENOID_MIN_DWELL;
133+
} else if (next_dwell > SOLENOID_MAX_DWELL) {
134+
// if we overshoot the max, then cap at max
135+
next_dwell = SOLENOID_MAX_DWELL;
125136
}
126-
solenoid_set_dwell(dwell);
137+
solenoid_set_dwell(next_dwell);
138+
#else
139+
int16_t next_dwell = ((int16_t)haptic_config.dwell) + 1;
127140
#endif
128-
haptic_set_dwell(dwell);
141+
haptic_set_dwell(next_dwell);
129142
}
130143

131144
void haptic_dwell_decrease(void) {
132-
uint8_t dwell = haptic_config.dwell - 1;
133145
#ifdef SOLENOID_ENABLE
134-
if (haptic_config.dwell < SOLENOID_MIN_DWELL) {
135-
dwell = SOLENOID_MAX_DWELL;
146+
int16_t next_dwell = ((int16_t)haptic_config.dwell) - SOLENOID_DWELL_STEP_SIZE;
147+
if (haptic_config.dwell <= SOLENOID_MIN_DWELL) {
148+
// if it's already at min, we wrap to max
149+
next_dwell = SOLENOID_MAX_DWELL;
150+
} else if (next_dwell < SOLENOID_MIN_DWELL) {
151+
// if we go below min, then we cap to min
152+
next_dwell = SOLENOID_MIN_DWELL;
136153
}
137-
solenoid_set_dwell(dwell);
154+
solenoid_set_dwell(next_dwell);
155+
#else
156+
int16_t next_dwell = ((int16_t)haptic_config.dwell) - 1;
138157
#endif
139-
haptic_set_dwell(dwell);
158+
haptic_set_dwell(next_dwell);
140159
}
141160

142161
void haptic_reset(void) {
@@ -150,6 +169,12 @@ void haptic_reset(void) {
150169
#ifdef SOLENOID_ENABLE
151170
uint8_t dwell = SOLENOID_DEFAULT_DWELL;
152171
haptic_config.dwell = dwell;
172+
haptic_config.buzz = SOLENOID_DEFAULT_BUZZ;
173+
solenoid_set_dwell(dwell);
174+
#else
175+
// This is to trigger haptic_reset again, if solenoid is enabled in the future.
176+
haptic_config.dwell = 0;
177+
haptic_config.buzz = 0;
153178
#endif
154179
eeconfig_update_haptic(haptic_config.raw);
155180
xprintf("haptic_config.feedback = %u\n", haptic_config.feedback);

drivers/haptic/solenoid.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,6 @@ void solenoid_buzz_off(void) { haptic_set_buzz(0); }
3232

3333
void solenoid_set_buzz(int buzz) { haptic_set_buzz(buzz); }
3434

35-
void solenoid_dwell_minus(uint8_t solenoid_dwell) {
36-
if (solenoid_dwell > 0) solenoid_dwell--;
37-
}
38-
39-
void solenoid_dwell_plus(uint8_t solenoid_dwell) {
40-
if (solenoid_dwell < SOLENOID_MAX_DWELL) solenoid_dwell++;
41-
}
42-
4335
void solenoid_set_dwell(uint8_t dwell) { solenoid_dwell = dwell; }
4436

4537
void solenoid_stop(void) {
@@ -73,7 +65,7 @@ void solenoid_check(void) {
7365

7466
// Check whether to buzz the solenoid on and off
7567
if (haptic_config.buzz) {
76-
if (elapsed / SOLENOID_MIN_DWELL % 2 == 0) {
68+
if ((elapsed % (SOLENOID_BUZZ_ACTUATED + SOLENOID_BUZZ_NONACTUATED)) < SOLENOID_BUZZ_ACTUATED) {
7769
if (!solenoid_buzzing) {
7870
solenoid_buzzing = true;
7971
writePinHigh(SOLENOID_PIN);

drivers/haptic/solenoid.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,22 @@
2929
# define SOLENOID_MIN_DWELL 4
3030
#endif
3131

32+
#ifndef SOLENOID_DWELL_STEP_SIZE
33+
# define SOLENOID_DWELL_STEP_SIZE 1
34+
#endif
35+
36+
#ifndef SOLENOID_DEFAULT_BUZZ
37+
# define SOLENOID_DEFAULT_BUZZ 0
38+
#endif
39+
40+
#ifndef SOLENOID_BUZZ_ACTUATED
41+
# define SOLENOID_BUZZ_ACTUATED SOLENOID_MIN_DWELL
42+
#endif
43+
44+
#ifndef SOLENOID_BUZZ_NONACTUATED
45+
# define SOLENOID_BUZZ_NONACTUATED SOLENOID_MIN_DWELL
46+
#endif
47+
3248
#ifndef SOLENOID_PIN
3349
# error SOLENOID_PIN not defined
3450
#endif
@@ -37,8 +53,6 @@ void solenoid_buzz_on(void);
3753
void solenoid_buzz_off(void);
3854
void solenoid_set_buzz(int buzz);
3955

40-
void solenoid_dwell_minus(uint8_t solenoid_dwell);
41-
void solenoid_dwell_plus(uint8_t solenoid_dwell);
4256
void solenoid_set_dwell(uint8_t dwell);
4357

4458
void solenoid_stop(void);

tmk_core/common/eeconfig.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
# include "eeprom_driver.h"
1414
#endif
1515

16+
#if defined(HAPTIC_ENABLE)
17+
# include "haptic.h"
18+
#endif
19+
1620
/** \brief eeconfig enable
1721
*
1822
* FIXME: needs doc
@@ -65,6 +69,15 @@ void eeconfig_init_quantum(void) {
6569
eeprom_update_byte(EECONFIG_HANDEDNESS, 0);
6670
#endif
6771

72+
#if defined(HAPTIC_ENABLE)
73+
haptic_reset();
74+
#else
75+
// this is used in case haptic is disabled, but we still want sane defaults
76+
// in the haptic configuration eeprom. All zero will trigger a haptic_reset
77+
// when a haptic-enabled firmware is loaded onto the keyboard.
78+
eeprom_update_dword(EECONFIG_HAPTIC, 0);
79+
#endif
80+
6881
eeconfig_init_kb();
6982
}
7083

0 commit comments

Comments
 (0)