-
-
Notifications
You must be signed in to change notification settings - Fork 39.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Enhancement] Improvements for debounce test coverage + bug fixes for sym_defer_g and sym_eager_pr #21667
Conversation
785402c
to
fc564fb
Compare
b15c7ef
to
4aed15d
Compare
@lesshonor thanks. Brainfart. I rebased and changed the target branch. |
25bba8d
to
78bda4f
Compare
baeb921
to
b830183
Compare
Ok, everything is done now. Tests have been added, too. There was one big omission from the tests in that they didn't check if the boolean returned from debounce actually matched when the output had not changed. When it returned I made a test for reproducing an async tick and, sure enough, @filterpaper I managed to get the size down to 16768 bytes. With some other changes, I can manage to get to 16752, by applying the patch below. Let me know if you think it's worth it. I honestly think this is even better, but I want your opinion on it. diff --git a/platforms/avr/timer.c b/platforms/avr/timer.c
index 65b2db1343..ca89b3dc59 100644
--- a/platforms/avr/timer.c
+++ b/platforms/avr/timer.c
@@ -83,13 +83,7 @@ inline void timer_clear(void) {
* FIXME: needs doc
*/
inline uint16_t timer_read(void) {
- uint32_t t;
-
- ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
- t = timer_count;
- }
-
- return (uint16_t)t;
+ return (uint16_t)timer_read32();
}
/** \brief timer read32
@@ -111,27 +105,16 @@ inline uint32_t timer_read32(void) {
* FIXME: needs doc
*/
inline uint16_t timer_elapsed(uint16_t last) {
- uint32_t t;
-
- ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
- t = timer_count;
- }
-
- return TIMER_DIFF_16((uint16_t)t, last);
+ return TIMER_DIFF_16(timer_read(), last);
}
/** \brief timer elapsed32
*
+
* FIXME: needs doc
*/
inline uint32_t timer_elapsed32(uint32_t last) {
- uint32_t t;
-
- ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
- t = timer_count;
- }
-
- return TIMER_DIFF_32(t, last);
+ return TIMER_DIFF_32(timer_read32(), last);
} |
b830183
to
ac35422
Compare
@filterpaper I went ahead and applied this patch. I can't see any downsides, with everything inlined. |
Ok, so, after digging a little bit further into the subject, I see a source of problems here. It seems that, for AVR, we get the time from the usual means, using ISRs and getting the interrupt from the CPU and using a prescaler to get the interrupt to represent 1ms. This means, @Nebuleon and @filterpaper, that I think it's also possible to get a jump of 1ms between subsequent invocations of a timer read inside the same call to debounce, even on AVR. And due to integer division, we have a timing problem, because the current checks are basically (in all algorithms) As an example (frequency of 16MHz and prescaler of 64, getting us 1 interrupt every 1ms, or 1 interrupt every 250 CPU cycles, and a
We finished debouncing at less than 5 ms here. Currently, our approach only guarantees the debounce will happen at So we have two choices here:
@drashna not sure if this needs to involve other teams or something. Tagging you because you usually look at my PRs 😜 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've tested these changes to none
, sym_defer_g
and sym_eager_pr
on my keyboard while playing a Touhou MIDI file (notoriously full of notes) to induce extra interrupts taking 1-3 ms every 7.8 ms at DEBOUNCE
values of 1 and 5, as well as disabling my per-key RGB to increase the matrix scan rate, and the changes work at least as well as the original code.
I've also looked at the new AsyncTickOneKeyShort1
test and the changes it required to the test harness, and they look good.
In order to make the tests you introduce in this PR pass for sym_defer_g
, you had to make some changes to it, and those are also good. The changes to sym_eager_pr
to make sure cooked_changed
is updated based on the correct cooked row, i.e. before the update, are good and needed as well.
The only thing that remains is the matter of sym_defer_g
being a bit larger on AVR. But, since it is now only calling the timer function once, which is more correct in the face of interrupts updating the timer, it's not a concern for me if this happens to be a few bytes larger.
* Add tests for none * Add check for consistency between cooked_changed and actual result * Add check for ensuring debounce never reads the timer more than once * Fix sym_eager_pr incorrectly returning cooked_changed as false * Fix sym_defer_g reading the timer twice when debouncing * Save some useless memory copies on none when there are no changes * Restructure sym_defer_g so it is smaller on AVR
09b7000
to
bcf58fe
Compare
@Nebuleon not anymore. It's now smaller than in develop. @filterpaper these are the latest results.
|
Co-authored-by: Nebuleon <2391500+Nebuleon@users.noreply.github.com>
bcf58fe
to
9315725
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All OK for me. The change to warn on overflow of #define DEBOUNCE
instead of clamping in all implementations can go in another PR, which would conflict with this one so it must be done after this one is merged.
Any chance we can get this merged? @drashna @sigprof @filterpaper I think it was reduced enough and tested enough to be proven benign. I have a couple other improvements/cleanups on the way but those depend on this being on |
… sym_defer_g and sym_eager_pr (qmk#21667) Co-authored-by: Nebuleon <2391500+Nebuleon@users.noreply.github.com>
… sym_defer_g and sym_eager_pr (qmk#21667) Co-authored-by: Nebuleon <2391500+Nebuleon@users.noreply.github.com>
… sym_defer_g and sym_eager_pr (qmk#21667) Co-authored-by: Nebuleon <2391500+Nebuleon@users.noreply.github.com>
… sym_defer_g and sym_eager_pr (qmk#21667) Co-authored-by: Nebuleon <2391500+Nebuleon@users.noreply.github.com>
Description
Types of Changes
Issues Fixed or Closed by This PR
Checklist