Index: apps/lang/english.lang
===================================================================
--- apps/lang/english.lang (revision 14653)
+++ apps/lang/english.lang (working copy)
@@ -3345,6 +3345,20 @@
+ id: LANG_WHEEL_ACCEL_START
+ desc: wheel acceleration start
+ user:
+
+ *: "Wheel Acceleration Start"
+
+
+ *: "Wheel Acceleration Start"
+
+
+ *: "Wheel Acceleration Start"
+
+
+
id: LANG_BARS_MENU
desc: in the display sub menu
user:
Index: apps/gui/list.c
===================================================================
--- apps/gui/list.c (revision 14653)
+++ apps/gui/list.c (working copy)
@@ -898,8 +898,13 @@
int i;
#ifdef HAVE_SCROLLWHEEL
- int next_item_modifier = button_apply_acceleration(get_action_data(),
- WHEEL_ACCELERATION_FACTOR);
+ unsigned long long factor = global_settings.wheel_accel_start;
+
+ /* factor = (10^6 / global_settings.wheel_accel_start)^2 */
+ factor = 1000000/factor;
+ factor *= factor;
+
+ int next_item_modifier = button_apply_acceleration(get_action_data(), factor);
#else
static int next_item_modifier = 1;
static int last_accel_tick = 0;
Index: apps/settings.h
===================================================================
--- apps/settings.h (revision 14653)
+++ apps/settings.h (working copy)
@@ -747,6 +747,8 @@
#ifndef HAVE_SCROLLWHEEL
int list_accel_start_delay; /* ms before we start increaseing step size */
int list_accel_wait; /* ms between increases */
+#else
+ unsigned int wheel_accel_start; /* value in clicks/sec from which acceleration starts */
#endif
#ifdef HAVE_USBSTACK
int usb_stack_mode; /* device or host */
Index: apps/menus/display_menu.c
===================================================================
--- apps/menus/display_menu.c (revision 14653)
+++ apps/menus/display_menu.c (working copy)
@@ -317,6 +317,8 @@
MENUITEM_SETTING(list_accel_start_delay,
&global_settings.list_accel_start_delay, NULL);
MENUITEM_SETTING(list_accel_wait, &global_settings.list_accel_wait, NULL);
+#else
+MENUITEM_SETTING(wheel_accel_start, &global_settings.wheel_accel_start, NULL);
#endif /* HAVE_SCROLLWHEEL */
#ifdef HAVE_LCD_BITMAP
int screenscroll_callback(int action,const struct menu_item_ex *this_item)
@@ -354,6 +356,8 @@
&scroll_paginated,
#ifndef HAVE_SCROLLWHEEL
&list_accel_start_delay, &list_accel_wait
+#else
+ &wheel_accel_start
#endif
);
/* SCROLL MENU */
Index: apps/settings_list.c
===================================================================
--- apps/settings_list.c (revision 14653)
+++ apps/settings_list.c (working copy)
@@ -242,6 +242,12 @@
(void)unit;
snprintf(buffer, buffer_size, "%ds", ff_rewind_min_stepvals[val]);
}
+static long wheel_accel_getlang(int value)
+{
+ if (value == 0)
+ return LANG_OFF;
+ return TALK_ID(value, UNIT_INT);
+}
static long scanaccel_getlang(int value)
{
if (value == 0)
@@ -257,6 +263,15 @@
else
snprintf(buffer, buffer_size, "2x/%ds", val);
}
+static void wheel_accel_formatter(char *buffer, size_t buffer_size,
+ int val, const char *unit)
+{
+ (void)unit;
+ if (val == 0)
+ strcpy(buffer, str(LANG_OFF));
+ else
+ snprintf(buffer, buffer_size, "%3d clicks/s", val);
+}
static const unsigned char poweroff_idle_timer_times[] = {0,1,2,3,4,5,6,7,8,9,10,15,30,45,60};
static long poweroff_idle_timer_getlang(int value)
@@ -1262,6 +1277,10 @@
INT_SETTING(0, list_accel_wait, LANG_LISTACCEL_ACCEL_SPEED,
3, "list_accel_wait", UNIT_SEC, 1, 10, 1,
scanaccel_formatter, scanaccel_getlang, NULL),
+#else
+ INT_SETTING(0, wheel_accel_start, LANG_WHEEL_ACCEL_START, DEFAULT_WHEEL_ACCEL_START,
+ "wheel_accel_start", UNIT_INT, 10, 200, 10,
+ wheel_accel_formatter, wheel_accel_getlang, NULL),
#endif /* HAVE_SCROLLWHEEL */
#ifdef HAVE_USBSTACK
CHOICE_SETTING(0, usb_stack_mode, LANG_USBSTACK_MODE, 0, "usb mode",
Index: firmware/export/button.h
===================================================================
--- firmware/export/button.h (revision 14653)
+++ firmware/export/button.h (working copy)
@@ -51,7 +51,7 @@
#endif
#ifdef HAVE_SCROLLWHEEL
-int button_apply_acceleration(unsigned int data, unsigned int factor);
+int button_apply_acceleration(unsigned int data, unsigned long long factor);
#endif
#define BUTTON_NONE 0x00000000
Index: firmware/export/config-e200.h
===================================================================
--- firmware/export/config-e200.h (revision 14653)
+++ firmware/export/config-e200.h (working copy)
@@ -97,9 +97,8 @@
/* 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)
+/* define from which wheelticks/sec on the acceleration starts */
+#define DEFAULT_WHEEL_ACCEL_START 90
/* define this if you have a flash memory storage */
#define HAVE_FLASH_STORAGE
Index: firmware/export/config-ipodvideo.h
===================================================================
--- firmware/export/config-ipodvideo.h (revision 14653)
+++ firmware/export/config-ipodvideo.h (working copy)
@@ -73,6 +73,11 @@
/* We can fade the backlight by using PWM */
#define HAVE_BACKLIGHT_PWM_FADING
+/* define this if the unit uses a scrollwheel for navigation */
+#define HAVE_SCROLLWHEEL
+/* define from which wheelticks/sec on the acceleration starts */
+#define DEFAULT_WHEEL_ACCEL_START 10
+
/* Define this if you can detect headphones */
#define HAVE_HEADPHONE_DETECTION
Index: firmware/target/arm/ipod/button-clickwheel.c
===================================================================
--- firmware/target/arm/ipod/button-clickwheel.c (revision 14653)
+++ firmware/target/arm/ipod/button-clickwheel.c (working copy)
@@ -40,6 +40,16 @@
#include "system.h"
#include "powermgmt.h"
+#define WHEEL_FAST_OFF_INTERVAL 500000 /* 500ms */
+
+static int old_wheel_value = -1;
+static int repeat = 0;
+static int wheel_delta = 0;
+static int accumulated_wheel_delta = 0;
+static unsigned int wheel_repeat = 0;
+static unsigned long last_wheel_usec = 0;
+static unsigned long wheel_velocity = 0;
+
/* Variable to use for setting button status in interrupt handler */
int int_btn = BUTTON_NONE;
#ifdef HAVE_WHEEL_POSITION
@@ -96,9 +106,6 @@
outl(0x0, 0x7000c140); /* clear interrupt status? */
if ((status & 0x800000ff) == 0x8000001a) {
- static int old_wheel_value IDATA_ATTR = -1;
- static int wheel_repeat = 0;
-
if (status & 0x100)
btn |= BUTTON_SELECT;
if (status & 0x200)
@@ -113,53 +120,101 @@
/* NB: highest wheel = 0x5F, clockwise increases */
int new_wheel_value = (status << 9) >> 25;
whl = new_wheel_value;
+
+ /* switch on backlight (again), reset power-off timer */
backlight_on();
reset_poweroff_timer();
+
/* The queue should have no other events when scrolling */
- if (queue_empty(&button_queue) && old_wheel_value >= 0) {
-
+ if (queue_empty(&button_queue) && old_wheel_value >= 0)
+ {
/* This is for later = BUTTON_SCROLL_TOUCH;*/
- int wheel_delta = new_wheel_value - old_wheel_value;
- unsigned long data;
- int wheel_keycode;
-
+ wheel_delta = new_wheel_value - old_wheel_value;
+ unsigned int wheel_keycode = BUTTON_NONE;
+
if (wheel_delta < -48)
wheel_delta += 96; /* Forward wrapping case */
else if (wheel_delta > 48)
wheel_delta -= 96; /* Backward wrapping case */
-
- if (wheel_delta > 4) {
+
+ /* getting wheel_keycode from wheel_delta */
+ if (wheel_delta > 4)
wheel_keycode = BUTTON_SCROLL_FWD;
- } else if (wheel_delta < -4) {
+ else if (wheel_delta < -4)
wheel_keycode = BUTTON_SCROLL_BACK;
- } else goto wheel_end;
-
+ else
+ wheel_keycode = BUTTON_NONE;
+
+ /* add the current wheel_delta */
+ accumulated_wheel_delta += wheel_delta;
+
+ if (wheel_keycode != BUTTON_NONE)
+ {
+ unsigned long usec = USEC_TIMER;
+ long v = (usec - last_wheel_usec) & 0x7fffffff;
+
+ v = v ? (0xffffff * accumulated_wheel_delta) / v : 0; /* clicks/usec * 0xffffff */
+ v = (v<0) ? -v : v; /* undo signedness */
+ v = (v>0x3ffff) ? 0x3ffff : v; /* limit to 2^18 */
+
+ /* some velocity filtering to smooth things out */
+ wheel_velocity = (7*wheel_velocity + v) / 8;
+
+ /* direction reversals nullify acceleration */
+ if (wheel_keycode != wheel_repeat)
+ {
+ wheel_repeat = wheel_keycode;
+ wheel_velocity = 0;
+ }
+ /* timeout nullifies acceleration */
+ if (TIME_AFTER(usec, last_wheel_usec + WHEEL_FAST_OFF_INTERVAL))
+ {
+ wheel_velocity = 0;
+ }
+
#ifdef HAVE_WHEEL_POSITION
- if (send_events)
+ if (send_events)
#endif
- {
- data = (wheel_delta << 16) | new_wheel_value;
- queue_post(&button_queue, wheel_keycode | wheel_repeat,
- data);
+ {
+ /* use data-format for HAVE_SCROLLWHEEL */
+ /* always use acceleration mode (1<<31) */
+ /* always set message post count to (1<<24) */
+ /* this way the scrolling is always calculated from wheel_velocity */
+ queue_post(&button_queue, wheel_keycode | repeat,
+ (1<<31) | (1 << 24) | wheel_velocity);
+ }
+
+ if (!repeat) repeat = BUTTON_REPEAT;
+
+ accumulated_wheel_delta = 0;
+
+ last_wheel_usec = usec;
}
-
- if (!wheel_repeat) wheel_repeat = BUTTON_REPEAT;
+ else
+ {
+ /* take from former revision */
+ goto wheel_end;
+ }
}
old_wheel_value = new_wheel_value;
- } else if (old_wheel_value >= 0) {
- /* scroll wheel up */
+ }
+ else if (old_wheel_value >= 0)
+ {
+ // scroll wheel up
old_wheel_value = -1;
- wheel_repeat = 0;
+ repeat = 0;
}
- } else if (status == 0xffffffff) {
+ }
+ else if (status == 0xffffffff)
+ {
opto_i2c_init();
}
}
wheel_end:
-
+
if ((inl(reg) & 0x8000000) != 0) {
outl(0xffffffff, 0x7000c120);
outl(0xffffffff, 0x7000c124);
@@ -200,14 +255,21 @@
void button_init_device(void)
{
opto_i2c_init();
+
/* hold button - enable as input */
GPIOA_ENABLE |= 0x20;
GPIOA_OUTPUT_EN &= ~0x20;
+
/* hold button - set interrupt levels */
GPIOA_INT_LEV = ~(GPIOA_INPUT_VAL & 0x20);
GPIOA_INT_CLR = GPIOA_INT_STAT & 0x20;
+
+ /* Get current tick before enabling button interrupts */
+ last_wheel_usec = USEC_TIMER;
+
/* enable interrupts */
GPIOA_INT_EN = 0x20;
+
/* unmask interrupt */
CPU_INT_EN = 0x40000000;
CPU_HI_INT_EN = I2C_MASK;
Index: firmware/drivers/button.c
===================================================================
--- firmware/drivers/button.c (revision 14653)
+++ firmware/drivers/button.c (working copy)
@@ -497,7 +497,7 @@
* 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 button_apply_acceleration(unsigned int data, unsigned long long factor)
{
int delta = (data >> 24) & 0x7f;