Wheel acceleration for e200. A general acceleration interface intended for use on any scroll target and by any code. A general interface to obtain data associated with most recently dequeued button presses and actions. Use #define HAVE_SCROLLWHEEL and set appropriate constants, values in the scroller driver that feel right.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13959 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
3213d4a0f5
commit
873e0fd1ef
11 changed files with 168 additions and 30 deletions
|
@ -31,6 +31,7 @@
|
||||||
|
|
||||||
static int last_button = BUTTON_NONE|BUTTON_REL; /* allow the ipod wheel to
|
static int last_button = BUTTON_NONE|BUTTON_REL; /* allow the ipod wheel to
|
||||||
work on startup */
|
work on startup */
|
||||||
|
static intptr_t last_data = 0;
|
||||||
static int last_action = ACTION_NONE;
|
static int last_action = ACTION_NONE;
|
||||||
static bool repeated = false;
|
static bool repeated = false;
|
||||||
|
|
||||||
|
@ -113,6 +114,7 @@ static int get_action_worker(int context, int timeout,
|
||||||
else
|
else
|
||||||
button = button_get_w_tmo(timeout);
|
button = button_get_w_tmo(timeout);
|
||||||
|
|
||||||
|
/* Data from sys events can be pulled with button_get_data */
|
||||||
if (button == BUTTON_NONE || button&SYS_EVENT)
|
if (button == BUTTON_NONE || button&SYS_EVENT)
|
||||||
{
|
{
|
||||||
return button;
|
return button;
|
||||||
|
@ -201,6 +203,7 @@ static int get_action_worker(int context, int timeout,
|
||||||
|
|
||||||
last_button = button;
|
last_button = button;
|
||||||
last_action = ret;
|
last_action = ret;
|
||||||
|
last_data = button_get_data();
|
||||||
last_action_tick = current_tick;
|
last_action_tick = current_tick;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -230,6 +233,11 @@ bool is_keys_locked(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
intptr_t get_action_data(void)
|
||||||
|
{
|
||||||
|
return last_data;
|
||||||
|
}
|
||||||
|
|
||||||
int get_action_statuscode(int *button)
|
int get_action_statuscode(int *button)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
|
@ -253,6 +253,8 @@ bool is_keys_locked(void);
|
||||||
#define ACTION_REPEAT 0x2 /* action was repeated (NOT button) */
|
#define ACTION_REPEAT 0x2 /* action was repeated (NOT button) */
|
||||||
int get_action_statuscode(int *button);
|
int get_action_statuscode(int *button);
|
||||||
|
|
||||||
|
/* returns the data value associated with the last action that is not
|
||||||
|
BUTTON_NONE or flagged with SYS_EVENT */
|
||||||
|
intptr_t get_action_data(void);
|
||||||
|
|
||||||
|
#endif /* __ACTION_H__ */
|
||||||
#endif
|
|
||||||
|
|
|
@ -887,15 +887,22 @@ static void gui_synclist_scroll_left(struct gui_synclist * lists)
|
||||||
}
|
}
|
||||||
#endif /* HAVE_LCD_BITMAP */
|
#endif /* HAVE_LCD_BITMAP */
|
||||||
|
|
||||||
|
extern intptr_t get_action_data(void);
|
||||||
|
|
||||||
unsigned gui_synclist_do_button(struct gui_synclist * lists,
|
unsigned gui_synclist_do_button(struct gui_synclist * lists,
|
||||||
unsigned button,enum list_wrap wrap)
|
unsigned button,enum list_wrap wrap)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_LCD_BITMAP
|
#ifdef HAVE_LCD_BITMAP
|
||||||
static bool scrolling_left = false;
|
static bool scrolling_left = false;
|
||||||
#endif
|
#endif
|
||||||
|
int i;
|
||||||
|
|
||||||
|
#ifdef HAVE_SCROLLWHEEL
|
||||||
|
int next_item_modifier = button_apply_acceleration(get_action_data(),
|
||||||
|
WHEEL_ACCELERATION_FACTOR);
|
||||||
|
#else
|
||||||
static int next_item_modifier = 1;
|
static int next_item_modifier = 1;
|
||||||
static int last_accel_tick = 0;
|
static int last_accel_tick = 0;
|
||||||
int i;
|
|
||||||
|
|
||||||
if (global_settings.list_accel_start_delay)
|
if (global_settings.list_accel_start_delay)
|
||||||
{
|
{
|
||||||
|
@ -919,6 +926,7 @@ unsigned gui_synclist_do_button(struct gui_synclist * lists,
|
||||||
last_accel_tick = 0;
|
last_accel_tick = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (wrap)
|
switch (wrap)
|
||||||
{
|
{
|
||||||
|
@ -953,8 +961,12 @@ unsigned gui_synclist_do_button(struct gui_synclist * lists,
|
||||||
case ACTION_STD_PREVREPEAT:
|
case ACTION_STD_PREVREPEAT:
|
||||||
FOR_NB_SCREENS(i)
|
FOR_NB_SCREENS(i)
|
||||||
gui_list_select_at_offset(&(lists->gui_list[i]), -next_item_modifier);
|
gui_list_select_at_offset(&(lists->gui_list[i]), -next_item_modifier);
|
||||||
|
#ifndef HAVE_SCROLLWHEEL
|
||||||
if (queue_count(&button_queue) < FRAMEDROP_TRIGGER)
|
if (queue_count(&button_queue) < FRAMEDROP_TRIGGER)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
gui_synclist_draw(lists);
|
gui_synclist_draw(lists);
|
||||||
|
}
|
||||||
yield();
|
yield();
|
||||||
return ACTION_STD_PREV;
|
return ACTION_STD_PREV;
|
||||||
|
|
||||||
|
@ -962,8 +974,12 @@ unsigned gui_synclist_do_button(struct gui_synclist * lists,
|
||||||
case ACTION_STD_NEXTREPEAT:
|
case ACTION_STD_NEXTREPEAT:
|
||||||
FOR_NB_SCREENS(i)
|
FOR_NB_SCREENS(i)
|
||||||
gui_list_select_at_offset(&(lists->gui_list[i]), next_item_modifier);
|
gui_list_select_at_offset(&(lists->gui_list[i]), next_item_modifier);
|
||||||
|
#ifndef HAVE_SCROLLWHEEL
|
||||||
if (queue_count(&button_queue) < FRAMEDROP_TRIGGER)
|
if (queue_count(&button_queue) < FRAMEDROP_TRIGGER)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
gui_synclist_draw(lists);
|
gui_synclist_draw(lists);
|
||||||
|
}
|
||||||
yield();
|
yield();
|
||||||
return ACTION_STD_NEXT;
|
return ACTION_STD_NEXT;
|
||||||
|
|
||||||
|
|
|
@ -10955,12 +10955,15 @@
|
||||||
desc: Delay before list starts accelerating
|
desc: Delay before list starts accelerating
|
||||||
user:
|
user:
|
||||||
<source>
|
<source>
|
||||||
|
e200: ""
|
||||||
*: "List Acceleration Start Delay"
|
*: "List Acceleration Start Delay"
|
||||||
</source>
|
</source>
|
||||||
<dest>
|
<dest>
|
||||||
|
e200: ""
|
||||||
*: "List Acceleration Start Delay"
|
*: "List Acceleration Start Delay"
|
||||||
</dest>
|
</dest>
|
||||||
<voice>
|
<voice>
|
||||||
|
e200: ""
|
||||||
*: "List Acceleration Start Delay"
|
*: "List Acceleration Start Delay"
|
||||||
</voice>
|
</voice>
|
||||||
</phrase>
|
</phrase>
|
||||||
|
@ -10969,12 +10972,15 @@
|
||||||
desc: list acceleration speed
|
desc: list acceleration speed
|
||||||
user:
|
user:
|
||||||
<source>
|
<source>
|
||||||
|
e200: ""
|
||||||
*: "List Acceleration Speed"
|
*: "List Acceleration Speed"
|
||||||
</source>
|
</source>
|
||||||
<dest>
|
<dest>
|
||||||
|
e200: ""
|
||||||
*: "List Acceleration Speed"
|
*: "List Acceleration Speed"
|
||||||
</dest>
|
</dest>
|
||||||
<voice>
|
<voice>
|
||||||
|
e200: ""
|
||||||
*: "List Acceleration Speed"
|
*: "List Acceleration Speed"
|
||||||
</voice>
|
</voice>
|
||||||
</phrase>
|
</phrase>
|
||||||
|
|
|
@ -313,9 +313,11 @@ MENUITEM_SETTING(jump_scroll, &global_settings.jump_scroll, NULL);
|
||||||
MENUITEM_SETTING(jump_scroll_delay, &global_settings.jump_scroll_delay, NULL);
|
MENUITEM_SETTING(jump_scroll_delay, &global_settings.jump_scroll_delay, NULL);
|
||||||
#endif
|
#endif
|
||||||
/* list acceleration */
|
/* list acceleration */
|
||||||
|
#ifndef HAVE_SCROLLWHEEL
|
||||||
MENUITEM_SETTING(list_accel_start_delay,
|
MENUITEM_SETTING(list_accel_start_delay,
|
||||||
&global_settings.list_accel_start_delay, NULL);
|
&global_settings.list_accel_start_delay, NULL);
|
||||||
MENUITEM_SETTING(list_accel_wait, &global_settings.list_accel_wait, NULL);
|
MENUITEM_SETTING(list_accel_wait, &global_settings.list_accel_wait, NULL);
|
||||||
|
#endif /* HAVE_SCROLLWHEEL */
|
||||||
#ifdef HAVE_LCD_BITMAP
|
#ifdef HAVE_LCD_BITMAP
|
||||||
int screenscroll_callback(int action,const struct menu_item_ex *this_item)
|
int screenscroll_callback(int action,const struct menu_item_ex *this_item)
|
||||||
{
|
{
|
||||||
|
@ -350,7 +352,9 @@ MAKE_MENU(scroll_settings_menu, ID2P(LANG_SCROLL_MENU), 0, Icon_NOICON,
|
||||||
&offset_out_of_view, &screen_scroll_step,
|
&offset_out_of_view, &screen_scroll_step,
|
||||||
#endif
|
#endif
|
||||||
&scroll_paginated,
|
&scroll_paginated,
|
||||||
|
#ifndef HAVE_SCROLLWHEEL
|
||||||
&list_accel_start_delay, &list_accel_wait
|
&list_accel_start_delay, &list_accel_wait
|
||||||
|
#endif
|
||||||
);
|
);
|
||||||
/* SCROLL MENU */
|
/* SCROLL MENU */
|
||||||
/***********************************/
|
/***********************************/
|
||||||
|
|
|
@ -731,8 +731,10 @@ struct user_settings
|
||||||
#ifdef HAVE_BUTTONLIGHT_BRIGHTNESS
|
#ifdef HAVE_BUTTONLIGHT_BRIGHTNESS
|
||||||
int buttonlight_brightness;
|
int buttonlight_brightness;
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef HAVE_SCROLLWHEEL
|
||||||
int list_accel_start_delay; /* ms before we start increaseing step size */
|
int list_accel_start_delay; /* ms before we start increaseing step size */
|
||||||
int list_accel_wait; /* ms between increases */
|
int list_accel_wait; /* ms between increases */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/** global variables **/
|
/** global variables **/
|
||||||
|
|
|
@ -274,6 +274,7 @@ static void poweroff_idle_timer_formatter(char *buffer, int buffer_size,
|
||||||
snprintf(buffer, buffer_size, "%dm", poweroff_idle_timer_times[val]);
|
snprintf(buffer, buffer_size, "%dm", poweroff_idle_timer_times[val]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_SCROLLWHEEL
|
||||||
static long listaccel_getlang(int value)
|
static long listaccel_getlang(int value)
|
||||||
{
|
{
|
||||||
if (value == 0)
|
if (value == 0)
|
||||||
|
@ -289,6 +290,7 @@ static void listaccel_formatter(char *buffer, int buffer_size,
|
||||||
else
|
else
|
||||||
snprintf(buffer, buffer_size, "%d ms", 5*HZ*val);
|
snprintf(buffer, buffer_size, "%d ms", 5*HZ*val);
|
||||||
}
|
}
|
||||||
|
#endif /* HAVE_SCROLLWHEEL */
|
||||||
|
|
||||||
#if CONFIG_CODEC == SWCODEC
|
#if CONFIG_CODEC == SWCODEC
|
||||||
static void crossfeed_format(char* buffer, int buffer_size, int value,
|
static void crossfeed_format(char* buffer, int buffer_size, int value,
|
||||||
|
@ -1235,12 +1237,14 @@ const struct settings_list settings[] = {
|
||||||
"button light brightness",UNIT_INT, MIN_BRIGHTNESS_SETTING, MAX_BRIGHTNESS_SETTING, 1,
|
"button light brightness",UNIT_INT, MIN_BRIGHTNESS_SETTING, MAX_BRIGHTNESS_SETTING, 1,
|
||||||
NULL, NULL, buttonlight_set_brightness),
|
NULL, NULL, buttonlight_set_brightness),
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef HAVE_SCROLLWHEEL
|
||||||
INT_SETTING(0, list_accel_start_delay, LANG_LISTACCEL_START_DELAY,
|
INT_SETTING(0, list_accel_start_delay, LANG_LISTACCEL_START_DELAY,
|
||||||
2, "list_accel_start_delay", UNIT_MS, 0, 10, 1,
|
2, "list_accel_start_delay", UNIT_MS, 0, 10, 1,
|
||||||
listaccel_formatter, listaccel_getlang, NULL),
|
listaccel_formatter, listaccel_getlang, NULL),
|
||||||
INT_SETTING(0, list_accel_wait, LANG_LISTACCEL_ACCEL_SPEED,
|
INT_SETTING(0, list_accel_wait, LANG_LISTACCEL_ACCEL_SPEED,
|
||||||
3, "list_accel_wait", UNIT_SEC, 1, 10, 1,
|
3, "list_accel_wait", UNIT_SEC, 1, 10, 1,
|
||||||
scanaccel_formatter, scanaccel_getlang, NULL),
|
scanaccel_formatter, scanaccel_getlang, NULL),
|
||||||
|
#endif /* HAVE_SCROLLWHEEL */
|
||||||
};
|
};
|
||||||
|
|
||||||
const int nb_settings = sizeof(settings)/sizeof(*settings);
|
const int nb_settings = sizeof(settings)/sizeof(*settings);
|
||||||
|
|
|
@ -49,6 +49,7 @@ struct event_queue button_queue;
|
||||||
|
|
||||||
static long lastbtn; /* Last valid button status */
|
static long lastbtn; /* Last valid button status */
|
||||||
static long last_read; /* Last button status, for debouncing/filtering */
|
static long last_read; /* Last button status, for debouncing/filtering */
|
||||||
|
static intptr_t button_data; /* data value from last message dequeued */
|
||||||
#ifdef HAVE_LCD_BITMAP
|
#ifdef HAVE_LCD_BITMAP
|
||||||
static bool flipped; /* buttons can be flipped to match the LCD flip */
|
static bool flipped; /* buttons can be flipped to match the LCD flip */
|
||||||
#endif
|
#endif
|
||||||
|
@ -309,7 +310,7 @@ long button_get(bool block)
|
||||||
if (current_tick - ev.tick > MAX_EVENT_AGE)
|
if (current_tick - ev.tick > MAX_EVENT_AGE)
|
||||||
return BUTTON_NONE;
|
return BUTTON_NONE;
|
||||||
#endif
|
#endif
|
||||||
|
button_data = ev.data;
|
||||||
return ev.id;
|
return ev.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,7 +330,17 @@ long button_get_w_tmo(int ticks)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
queue_wait_w_tmo(&button_queue, &ev, ticks);
|
queue_wait_w_tmo(&button_queue, &ev, ticks);
|
||||||
return (ev.id != SYS_TIMEOUT)? ev.id: BUTTON_NONE;
|
if (ev.id == SYS_TIMEOUT)
|
||||||
|
ev.id = BUTTON_NONE;
|
||||||
|
else
|
||||||
|
button_data = ev.data;
|
||||||
|
|
||||||
|
return ev.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
intptr_t button_get_data(void)
|
||||||
|
{
|
||||||
|
return button_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void button_init(void)
|
void button_init(void)
|
||||||
|
@ -470,3 +481,33 @@ void button_clear_queue(void)
|
||||||
{
|
{
|
||||||
queue_clear(&button_queue);
|
queue_clear(&button_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_SCROLLWHEEL
|
||||||
|
/**
|
||||||
|
* data:
|
||||||
|
* [31] Use acceleration
|
||||||
|
* [30:24] Message post count (skipped + 1) (1-127)
|
||||||
|
* [23:0] Velocity - clicks/uS - 0.24 fixed point
|
||||||
|
*
|
||||||
|
* factor:
|
||||||
|
* Wheel acceleration scaling factor - x.24 fixed point -
|
||||||
|
* no greater than what will not overflow 64 bits when multiplied
|
||||||
|
* by the driver's maximum velocity in (clicks/usec)^2 in 0.24
|
||||||
|
*/
|
||||||
|
int button_apply_acceleration(unsigned int data, unsigned int factor)
|
||||||
|
{
|
||||||
|
int delta = (data >> 24) & 0x7f;
|
||||||
|
|
||||||
|
if ((data & (1 << 31)) != 0)
|
||||||
|
{
|
||||||
|
unsigned int v = data & 0xffffff;
|
||||||
|
|
||||||
|
v = factor * (unsigned long long)v*v / 0xffffffffffffull;
|
||||||
|
|
||||||
|
if (v > 1)
|
||||||
|
delta *= v;
|
||||||
|
}
|
||||||
|
|
||||||
|
return delta;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_SCROLLWHEEL */
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#define _BUTTON_H_
|
#define _BUTTON_H_
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <inttypes.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "button-target.h"
|
#include "button-target.h"
|
||||||
|
|
||||||
|
@ -28,6 +29,7 @@ extern struct event_queue button_queue;
|
||||||
void button_init (void);
|
void button_init (void);
|
||||||
long button_get (bool block);
|
long button_get (bool block);
|
||||||
long button_get_w_tmo(int ticks);
|
long button_get_w_tmo(int ticks);
|
||||||
|
intptr_t button_get_data(void);
|
||||||
int button_status(void);
|
int button_status(void);
|
||||||
void button_clear_queue(void);
|
void button_clear_queue(void);
|
||||||
#ifdef HAVE_LCD_BITMAP
|
#ifdef HAVE_LCD_BITMAP
|
||||||
|
@ -48,6 +50,10 @@ int wheel_status(void);
|
||||||
void wheel_send_events(bool send);
|
void wheel_send_events(bool send);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SCROLLWHEEL
|
||||||
|
int button_apply_acceleration(unsigned int data, unsigned int factor);
|
||||||
|
#endif
|
||||||
|
|
||||||
#define BUTTON_NONE 0x00000000
|
#define BUTTON_NONE 0x00000000
|
||||||
|
|
||||||
/* Button modifiers */
|
/* Button modifiers */
|
||||||
|
|
|
@ -170,4 +170,10 @@
|
||||||
|
|
||||||
#define ICODE_ATTR_TREMOR_NOT_MDCT
|
#define ICODE_ATTR_TREMOR_NOT_MDCT
|
||||||
|
|
||||||
#endif
|
/* define this if the unit uses a scrollwheel for navigation */
|
||||||
|
#define HAVE_SCROLLWHEEL
|
||||||
|
/* define wheel acceleration scaling factor */
|
||||||
|
/* Range for this target: 0xffffff*(0.0-16.000000894069724921567733381255) */
|
||||||
|
#define WHEEL_ACCELERATION_FACTOR (0xffffff*7)
|
||||||
|
|
||||||
|
#endif /* SIMULATOR */
|
||||||
|
|
|
@ -23,19 +23,21 @@
|
||||||
#include "button.h"
|
#include "button.h"
|
||||||
#include "backlight.h"
|
#include "backlight.h"
|
||||||
|
|
||||||
#define WHEEL_REPEAT_INTERVAL 30
|
#define WHEEL_REPEAT_INTERVAL 300000
|
||||||
#define WHEEL_FAST_ON_INTERVAL 2
|
#define WHEEL_FAST_ON_INTERVAL 20000
|
||||||
#define WHEEL_FAST_OFF_INTERVAL 6
|
#define WHEEL_FAST_OFF_INTERVAL 60000
|
||||||
|
|
||||||
/* Clickwheel */
|
/* Clickwheel */
|
||||||
#ifndef BOOTLOADER
|
#ifndef BOOTLOADER
|
||||||
static unsigned int old_wheel_value = 0;
|
static unsigned int old_wheel_value = 0;
|
||||||
static unsigned int wheel_repeat = BUTTON_NONE;
|
static unsigned int wheel_repeat = BUTTON_NONE;
|
||||||
static unsigned int wheel_click_count = 0;
|
static unsigned int wheel_click_count = 0;
|
||||||
|
static unsigned int wheel_delta = 0;
|
||||||
static int wheel_fast_mode = 0;
|
static int wheel_fast_mode = 0;
|
||||||
static unsigned long last_wheel_tick = 0;
|
static unsigned long last_wheel_usec = 0;
|
||||||
static unsigned long last_wheel_post = 0;
|
static unsigned long wheel_velocity = 0;
|
||||||
static unsigned long next_backlight_on = 0;
|
static long last_wheel_post = 0;
|
||||||
|
static long next_backlight_on = 0;
|
||||||
/* Buttons */
|
/* Buttons */
|
||||||
static bool hold_button = false;
|
static bool hold_button = false;
|
||||||
static bool hold_button_old = false;
|
static bool hold_button_old = false;
|
||||||
|
@ -64,8 +66,8 @@ void button_init_device(void)
|
||||||
GPIOH_INT_EN &= ~0xc0;
|
GPIOH_INT_EN &= ~0xc0;
|
||||||
|
|
||||||
/* Get current tick before enabling button interrupts */
|
/* Get current tick before enabling button interrupts */
|
||||||
last_wheel_tick = current_tick;
|
last_wheel_usec = USEC_TIMER;
|
||||||
last_wheel_post = current_tick;
|
last_wheel_post = last_wheel_usec;
|
||||||
|
|
||||||
GPIOH_ENABLE |= 0xc0;
|
GPIOH_ENABLE |= 0xc0;
|
||||||
GPIOH_OUTPUT_EN &= ~0xc0;
|
GPIOH_OUTPUT_EN &= ~0xc0;
|
||||||
|
@ -130,38 +132,67 @@ void clickwheel_int(void)
|
||||||
|
|
||||||
if (btn != BUTTON_NONE)
|
if (btn != BUTTON_NONE)
|
||||||
{
|
{
|
||||||
int repeat = 1;
|
int repeat = 1; /* assume repeat */
|
||||||
|
unsigned long usec = USEC_TIMER;
|
||||||
|
unsigned v = (usec - last_wheel_usec) & 0x7fffffff;
|
||||||
|
|
||||||
|
/* wheel velocity in 0.24 fixed point - clicks/uS */
|
||||||
|
|
||||||
|
/* velocity cap to 18 bits to allow up to x16 scaling */
|
||||||
|
v = (v < 0x40) ? 0xffffff / 0x40 : 0xffffff / v;
|
||||||
|
|
||||||
|
/* some velocity filtering to smooth things out */
|
||||||
|
wheel_velocity = (7*wheel_velocity + v) / 8;
|
||||||
|
|
||||||
if (btn != wheel_repeat)
|
if (btn != wheel_repeat)
|
||||||
{
|
{
|
||||||
|
/* direction reversals nullify all fast mode states */
|
||||||
wheel_repeat = btn;
|
wheel_repeat = btn;
|
||||||
repeat =
|
repeat =
|
||||||
wheel_fast_mode =
|
wheel_fast_mode =
|
||||||
|
wheel_velocity =
|
||||||
wheel_click_count = 0;
|
wheel_click_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wheel_fast_mode)
|
if (wheel_fast_mode != 0)
|
||||||
{
|
{
|
||||||
if (TIME_AFTER(current_tick,
|
/* fast OFF happens immediately when velocity drops below
|
||||||
last_wheel_tick + WHEEL_FAST_OFF_INTERVAL))
|
threshold */
|
||||||
|
if (TIME_AFTER(usec,
|
||||||
|
last_wheel_usec + WHEEL_FAST_OFF_INTERVAL))
|
||||||
{
|
{
|
||||||
if (++wheel_click_count < 2)
|
/* moving out of fast mode */
|
||||||
btn = BUTTON_NONE;
|
|
||||||
wheel_fast_mode = 0;
|
wheel_fast_mode = 0;
|
||||||
|
/* reset velocity */
|
||||||
|
wheel_velocity = 0;
|
||||||
|
/* wheel_delta is always 1 in slow mode */
|
||||||
|
wheel_delta = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (repeat && TIME_BEFORE(current_tick,
|
/* fast ON gets filtered to avoid inadvertent jumps to fast mode */
|
||||||
last_wheel_tick + WHEEL_FAST_ON_INTERVAL))
|
if (repeat && wheel_velocity > 0xffffff/WHEEL_FAST_ON_INTERVAL)
|
||||||
wheel_fast_mode = 1;
|
{
|
||||||
|
/* moving into fast mode */
|
||||||
|
wheel_fast_mode = 1 << 31;
|
||||||
|
wheel_click_count = 0;
|
||||||
|
wheel_velocity = 0xffffff/WHEEL_FAST_OFF_INTERVAL;
|
||||||
|
}
|
||||||
else if (++wheel_click_count < 2)
|
else if (++wheel_click_count < 2)
|
||||||
|
{
|
||||||
btn = BUTTON_NONE;
|
btn = BUTTON_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* wheel_delta is always 1 in slow mode */
|
||||||
|
wheel_delta = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TIME_AFTER(current_tick, next_backlight_on))
|
if (TIME_AFTER(usec, next_backlight_on))
|
||||||
{
|
{
|
||||||
next_backlight_on = current_tick + HZ/4;
|
/* poke backlight to turn it on or maintain it no more often
|
||||||
|
than every 1/4 second*/
|
||||||
|
next_backlight_on = usec + 1000000/4;
|
||||||
backlight_on();
|
backlight_on();
|
||||||
button_backlight_on();
|
button_backlight_on();
|
||||||
}
|
}
|
||||||
|
@ -170,17 +201,29 @@ void clickwheel_int(void)
|
||||||
{
|
{
|
||||||
wheel_click_count = 0;
|
wheel_click_count = 0;
|
||||||
|
|
||||||
if (repeat && TIME_BEFORE(current_tick,
|
/* generate repeats if quick enough */
|
||||||
last_wheel_post + WHEEL_REPEAT_INTERVAL))
|
if (repeat && TIME_BEFORE(usec,
|
||||||
|
last_wheel_post + WHEEL_REPEAT_INTERVAL))
|
||||||
btn |= BUTTON_REPEAT;
|
btn |= BUTTON_REPEAT;
|
||||||
|
|
||||||
last_wheel_post = current_tick;
|
last_wheel_post = usec;
|
||||||
|
|
||||||
if (queue_empty(&button_queue))
|
if (queue_empty(&button_queue))
|
||||||
queue_post(&button_queue, btn, 0);
|
{
|
||||||
|
queue_post(&button_queue, btn, wheel_fast_mode |
|
||||||
|
(wheel_delta << 24) | wheel_velocity);
|
||||||
|
/* message posted - reset delta */
|
||||||
|
wheel_delta = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* skipped post - increment delta */
|
||||||
|
if (++wheel_delta > 0x7f)
|
||||||
|
wheel_delta = 0x7f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
last_wheel_tick = current_tick;
|
last_wheel_usec = usec;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue