Skip to content

Commit

Permalink
Sample rotary-encoder inputs at 4x frequency of regular buttons (ie 2…
Browse files Browse the repository at this point in the history
…kHz rather than 500Hz).

Fixes missed detents on some cheap rotary encoders.

Seems to have no bad effect on high-rate images (eg. HD HFE, ED IMG, as in FF_TestBed).
  • Loading branch information
keirf committed Jul 22, 2020
1 parent 8f5ac9a commit 133c02c
Showing 1 changed file with 29 additions and 3 deletions.
32 changes: 29 additions & 3 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -460,8 +460,9 @@ static void button_timer_fn(void *unused)
[B_LEFT] = B_RIGHT, [B_RIGHT] = B_LEFT
};

static uint8_t rotary_ticks, rotary_scan_rate, rb;
static uint32_t _b[3]; /* 0 = left, 1 = right, 2 = select */
uint8_t b = osd_buttons_rx, rb;
uint8_t b = osd_buttons_rx;
bool_t twobutton_rotary =
(ff_cfg.twobutton_action & TWOBUTTON_mask) == TWOBUTTON_rotary;
int i, twobutton_reverse = !!(ff_cfg.twobutton_action & TWOBUTTON_reverse);
Expand All @@ -473,6 +474,24 @@ static void button_timer_fn(void *unused)
gpio_write_pin(gpioa, 4, HIGH);
}

/* Higher sample rate can be specified for rotary encoder. */
if (++rotary_ticks < rotary_scan_rate) {
switch (ff_cfg.rotary & ~ROT_reverse) {
case ROT_trackball:
case ROT_buttons:
case ROT_none:
break;
default: /* rotary encoder */ {
rotary = ((rotary << 2) | ((gpioc->idr >> 10) & 3)) & 15;
rb = read_rotary(rotary) ?: rb;
break;
}
}
goto out;
}
rotary_ticks = 0;
rotary_scan_rate = 1;

/* We debounce the switches by waiting for them to be pressed continuously
* for 32 consecutive sample periods (32 * 2ms == 64ms) */
for (i = 0; i < 3; i++) {
Expand Down Expand Up @@ -523,15 +542,20 @@ static void button_timer_fn(void *unused)
rb = rotary_reverse[rotary & 3];
break;

case ROT_none:
break;

default: /* rotary encoder */ {
rb = read_rotary(rotary);
rb = read_rotary(rotary) ?: rb;
rotary_scan_rate = 4; /* sample rotary inputs at 4x button rate */
break;
}

}
if (ff_cfg.rotary & ROT_reverse)
rb = rotary_reverse[rb];
b |= rb;
rb = 0;

switch (display_mode) {
case DM_LCD_OLED:
Expand All @@ -544,7 +568,9 @@ static void button_timer_fn(void *unused)

/* Latch final button state and reset the timer. */
buttons = b;
timer_set(&button_timer, button_timer.deadline + time_ms(BUTTON_SCAN_MS));
out:
timer_set(&button_timer, button_timer.deadline
+ time_ms(BUTTON_SCAN_MS) / rotary_scan_rate);
}

static void canary_init(void)
Expand Down

0 comments on commit 133c02c

Please sign in to comment.