diff options
| author | Marcin Bukat <marcin.bukat@gmail.com> | 2012-01-25 09:07:52 +0100 |
|---|---|---|
| committer | Marcin Bukat <marcin.bukat@gmail.com> | 2012-01-25 09:07:52 +0100 |
| commit | 36281c4cc9d83203753bb55963fafb2487c2d2de (patch) | |
| tree | b77c1d421cb32ac7eee424339005e8d983427754 | |
| parent | 76440aa214765037139aa9d74c4450f4045f38e1 (diff) | |
| download | rockbox-36281c4cc9d83203753bb55963fafb2487c2d2de.zip rockbox-36281c4cc9d83203753bb55963fafb2487c2d2de.tar.gz rockbox-36281c4cc9d83203753bb55963fafb2487c2d2de.tar.bz2 rockbox-36281c4cc9d83203753bb55963fafb2487c2d2de.tar.xz | |
MPIO HD300: Fix scrollstip issue at driver level.
Scrollstrip (as well as scrollwheel on ipods/sansas) works like
quadrature encoder. The states of input lines are tracked by the
gpio ISR and when the sequence is correct, appropriate button
event is pushed to the button queue directly. The downside of
this implementation is that scrollstrip doesn't emit _REL
events which has some weird consequences. For the scrollwheels
some hack have been crafted in action system to accomodate for
this. I don't like this approach. IMO the correct fix is to
properly emit _REL event when the user stops interacting with
the device or reverses the direction of the move. This patch
implements timeout which forces to emit _REL when expired.
Change-Id: I588ac5810dd2ab00c68935d23a62979cb1c2a912
| -rw-r--r-- | firmware/target/coldfire/mpio/hd300/button-hd300.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/firmware/target/coldfire/mpio/hd300/button-hd300.c b/firmware/target/coldfire/mpio/hd300/button-hd300.c index 8239b54..95de05c 100644 --- a/firmware/target/coldfire/mpio/hd300/button-hd300.c +++ b/firmware/target/coldfire/mpio/hd300/button-hd300.c @@ -29,10 +29,17 @@ #include "powermgmt.h" #define SLIDER_BASE_SENSITIVITY 8 +#define SLIDER_REL_TIMEOUT HZ/2 /* GPI7 H-L, GPI6 H-L, GPI7 L-H, GPI6 L-H */ #define SLIDER_GPIO_MASK ((1<<15)|(1<<14)|(1<<7)|(1<<6)) +static volatile struct scroll_state_t { + signed char dir; + long timeout; + bool rel; +} scroll; + static inline void disable_scrollstrip_interrupts(void) { and_l(~SLIDER_GPIO_MASK,&GPIO_INT_EN); @@ -89,10 +96,20 @@ void scrollstrip_isr(void) scroll_dir = scroll_state[prev_scroll_lines][new_scroll_lines]; prev_scroll_lines = new_scroll_lines; - + + /* catch sequence error */ + if (scroll_dir == BUTTON_NONE) + return; + + /* direction reversal */ if (direction != scroll_dir) { - /* direction reversal */ + /* post release event to the button queue */ + if (queue_empty(&button_queue)) + queue_post(&button_queue, direction|BUTTON_REL, 0); + + scroll.rel = true; + direction = scroll_dir; count = 0; ack_scrollstrip_interrupt(); @@ -121,6 +138,10 @@ void scrollstrip_isr(void) if (queue_empty(&button_queue)) queue_post(&button_queue, scroll_dir, 0); + scroll.dir = scroll_dir; + scroll.timeout = current_tick + SLIDER_REL_TIMEOUT; + scroll.rel = false; + ack_scrollstrip_interrupt(); enable_scrollstrip_interrupts(); } @@ -235,5 +256,15 @@ int button_read_device(void) } /* !button_hold() */ + if (!scroll.rel) + if (TIME_AFTER(current_tick, scroll.timeout)) + { + if (queue_empty(&button_queue)) + { + queue_post(&button_queue, scroll.dir|BUTTON_REL, 0); + scroll.rel = true; + } + } + return btn; } |