summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2010-04-01 16:07:56 +0000
committerThomas Martitz <kugel@rockbox.org>2010-04-01 16:07:56 +0000
commitf376fd2f4aa9b27f2a6299177b4cc3c014da01f3 (patch)
treee42edd558e2deff42d3522189d92d158e861a307
parent47dcf58e28930af8b468aa2151f1288e9ec334df (diff)
downloadrockbox-f376fd2f4aa9b27f2a6299177b4cc3c014da01f3.tar.gz
rockbox-f376fd2f4aa9b27f2a6299177b4cc3c014da01f3.zip
Fuzev2: Scrollwheel works like a charm :)
Move scrollwheel parsing function into separate file as it's reused. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25425 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/SOURCES3
-rw-r--r--firmware/export/config/sansafuzev2.h8
-rw-r--r--firmware/target/arm/as3525/button-e200v2-fuze.c108
-rw-r--r--firmware/target/arm/as3525/kernel-as3525.c2
-rw-r--r--firmware/target/arm/as3525/sansa-e200v2/button-target.h6
-rw-r--r--firmware/target/arm/as3525/sansa-fuze/button-target.h7
-rw-r--r--firmware/target/arm/as3525/sansa-fuzev2/button-fuzev2.c38
-rw-r--r--firmware/target/arm/as3525/sansa-fuzev2/button-target.h6
-rw-r--r--firmware/target/arm/as3525/scrollwheel-as3525.c124
9 files changed, 187 insertions, 115 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 0d845f2b3c..b5151c3950 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -408,6 +408,9 @@ target/arm/pnx0101/timer-pnx0101.c
408target/arm/as3525/system-as3525.c 408target/arm/as3525/system-as3525.c
409target/arm/as3525/kernel-as3525.c 409target/arm/as3525/kernel-as3525.c
410target/arm/as3525/timer-as3525.c 410target/arm/as3525/timer-as3525.c
411#ifdef HAVE_SCROLLWHEEL
412target/arm/as3525/scrollwheel-as3525.c
413#endif
411#if CONFIG_CPU == AS3525 414#if CONFIG_CPU == AS3525
412target/arm/as3525/sd-as3525.c 415target/arm/as3525/sd-as3525.c
413#else /* AS3535v2 */ 416#else /* AS3535v2 */
diff --git a/firmware/export/config/sansafuzev2.h b/firmware/export/config/sansafuzev2.h
index b71f852007..88d7650ca3 100644
--- a/firmware/export/config/sansafuzev2.h
+++ b/firmware/export/config/sansafuzev2.h
@@ -127,13 +127,13 @@
127#define CONFIG_BACKLIGHT_FADING BACKLIGHT_FADING_SW_SETTING 127#define CONFIG_BACKLIGHT_FADING BACKLIGHT_FADING_SW_SETTING
128 128
129/* define this if the unit uses a scrollwheel for navigation */ 129/* define this if the unit uses a scrollwheel for navigation */
130//#define HAVE_SCROLLWHEEL 130#define HAVE_SCROLLWHEEL
131/* define to activate advanced wheel acceleration code */ 131/* define to activate advanced wheel acceleration code */
132//#define HAVE_WHEEL_ACCELERATION 132#define HAVE_WHEEL_ACCELERATION
133/* define from which rotation speed [degree/sec] on the acceleration starts */ 133/* define from which rotation speed [degree/sec] on the acceleration starts */
134//#define WHEEL_ACCEL_START 540 134#define WHEEL_ACCEL_START 540
135/* define type of acceleration (1 = ^2, 2 = ^3, 3 = ^4) */ 135/* define type of acceleration (1 = ^2, 2 = ^3, 3 = ^4) */
136//#define WHEEL_ACCELERATION 1 136#define WHEEL_ACCELERATION 1
137 137
138/* define this if you have a flash memory storage */ 138/* define this if you have a flash memory storage */
139#define HAVE_FLASH_STORAGE 139#define HAVE_FLASH_STORAGE
diff --git a/firmware/target/arm/as3525/button-e200v2-fuze.c b/firmware/target/arm/as3525/button-e200v2-fuze.c
index 2a75fa1e6f..2cbdcf5130 100644
--- a/firmware/target/arm/as3525/button-e200v2-fuze.c
+++ b/firmware/target/arm/as3525/button-e200v2-fuze.c
@@ -27,21 +27,14 @@
27#include "backlight.h" 27#include "backlight.h"
28#include "dbop-as3525.h" 28#include "dbop-as3525.h"
29 29
30extern void scrollwheel(unsigned wheel_value);
30 31
31#if defined(SANSA_FUZE) || defined(SANSA_FUZEV2) 32#if defined(SANSA_FUZE)
32#define DBOP_BIT15_BUTTON BUTTON_HOME 33#define DBOP_BIT15_BUTTON BUTTON_HOME
33#define WHEEL_REPEAT_INTERVAL (HZ/5)
34#define WHEEL_COUNTER_DIV 4
35#define ACCEL_INCREMENT 2
36#define ACCEL_SHIFT 2
37#endif 34#endif
38 35
39#ifdef SANSA_E200V2 36#ifdef SANSA_E200V2
40#define DBOP_BIT15_BUTTON BUTTON_REC 37#define DBOP_BIT15_BUTTON BUTTON_REC
41#define WHEEL_REPEAT_INTERVAL (HZ/5)
42#define WHEEL_COUNTER_DIV 2
43#define ACCEL_INCREMENT 3
44#define ACCEL_SHIFT 1
45#endif 38#endif
46 39
47/* Buttons */ 40/* Buttons */
@@ -56,103 +49,6 @@ void button_init_device(void)
56 GPIOA_PIN(1) = (1<<1); 49 GPIOA_PIN(1) = (1<<1);
57} 50}
58 51
59#if !defined(BOOTLOADER) && defined(HAVE_SCROLLWHEEL)
60static void scrollwheel(unsigned int wheel_value)
61{
62 /* current wheel values, parsed from dbop and the resulting button */
63 unsigned btn = BUTTON_NONE;
64 /* old wheel values */
65 static unsigned old_wheel_value = 0;
66 static unsigned old_btn = BUTTON_NONE;
67
68 /*
69 * Getting BUTTON_REPEAT works like this: Remember when the btn value was
70 * posted to the button_queue last, and if it was recent enough, generate
71 * BUTTON_REPEAT
72 */
73 static long last_wheel_post = 0;
74
75 /*
76 * Providing wheel acceleration works as follows: We increment accel
77 * by 2 if the wheel was turned, and decrement it by 1 each tick
78 * (no matter if it was turned), that means: the longer and faster you turn,
79 * the higher accel will be. accel>>2 will actually posted to the button_queue
80 */
81 static int accel = 0;
82 /* We only post every 4th action, as this matches better with the physical
83 * clicks of the wheel */
84 static int counter = 0;
85 /* Read wheel
86 * Bits 13 and 14 of DBOP_DIN change as follows (Gray Code):
87 * Clockwise rotation 00 -> 01 -> 11 -> 10 -> 00
88 * Counter-clockwise 00 -> 10 -> 11 -> 01 -> 00
89 *
90 * For easy look-up, actual wheel values act as indicies also,
91 * which is why the table seems to be not ordered correctly
92 */
93 static const unsigned char wheel_tbl[2][4] =
94 {
95 { 2, 0, 3, 1 }, /* Clockwise rotation */
96 { 1, 3, 0, 2 }, /* Counter-clockwise */
97 };
98
99 if(hold_button)
100 {
101 accel = counter = 0;
102 return;
103 }
104
105 if (old_wheel_value == wheel_tbl[0][wheel_value])
106 btn = BUTTON_SCROLL_FWD;
107 else if (old_wheel_value == wheel_tbl[1][wheel_value])
108 btn = BUTTON_SCROLL_BACK;
109 else if (old_wheel_value != wheel_value && accel > ACCEL_INCREMENT)
110 { /* if no button is read and wheel_value changed, assume old_btn */
111 btn = old_btn;
112 }
113 /* else btn = BUTTON_NONE */
114
115 if (btn != BUTTON_NONE)
116 {
117 if (btn != old_btn)
118 {
119 /* direction reversals nullify acceleration and counters */
120 old_btn = btn;
121 accel = counter = 0;
122 }
123 /* wheel_delta will cause lists to jump over items,
124 * we want this for fast scrolling, but we must keep it accurate
125 * for slow scrolling */
126 int wheel_delta = 0;
127 /* generate BUTTON_REPEAT if quick enough, scroll slightly faster too*/
128 if (TIME_BEFORE(current_tick, last_wheel_post + WHEEL_REPEAT_INTERVAL))
129 {
130 btn |= BUTTON_REPEAT;
131 wheel_delta = accel>>ACCEL_SHIFT;
132 }
133
134 accel += ACCEL_INCREMENT;
135
136 /* the wheel is more reliable if we don't send every change,
137 * every WHEEL_COUNTER_DIVth is basically one "physical click"
138 * which should make up 1 item in lists */
139 if (++counter >= WHEEL_COUNTER_DIV && queue_empty(&button_queue))
140 {
141 buttonlight_on();
142 backlight_on();
143 queue_post(&button_queue, btn, ((wheel_delta+1)<<24));
144 /* message posted - reset count and remember post */
145 counter = 0;
146 last_wheel_post = current_tick;
147 }
148 }
149 if (accel > 0)
150 accel--;
151
152 old_wheel_value = wheel_value;
153}
154#endif /* !defined(BOOTLOADER) && defined(SCROLLWHEEL) */
155
156bool button_hold(void) 52bool button_hold(void)
157{ 53{
158 return hold_button; 54 return hold_button;
diff --git a/firmware/target/arm/as3525/kernel-as3525.c b/firmware/target/arm/as3525/kernel-as3525.c
index 4c421e50fc..ebaef71c99 100644
--- a/firmware/target/arm/as3525/kernel-as3525.c
+++ b/firmware/target/arm/as3525/kernel-as3525.c
@@ -44,7 +44,7 @@ static inline void do_scrollwheel(void)
44 else 44 else
45 { 45 {
46 if (!button_hold()) 46 if (!button_hold())
47 button_read_dbop(); /* Read the scrollwheel */ 47 get_scrollwheel(); /* Read the scrollwheel */
48 } 48 }
49 49
50 poll_scrollwheel ^= 1; 50 poll_scrollwheel ^= 1;
diff --git a/firmware/target/arm/as3525/sansa-e200v2/button-target.h b/firmware/target/arm/as3525/sansa-e200v2/button-target.h
index b1feb58cad..7a0e9e50f1 100644
--- a/firmware/target/arm/as3525/sansa-e200v2/button-target.h
+++ b/firmware/target/arm/as3525/sansa-e200v2/button-target.h
@@ -31,6 +31,12 @@ bool button_hold(void);
31void button_init_device(void); 31void button_init_device(void);
32int button_read_device(void); 32int button_read_device(void);
33unsigned short button_read_dbop(void); 33unsigned short button_read_dbop(void);
34#define get_scrollwheel button_read_dbop
35
36#define WHEEL_REPEAT_INTERVAL (HZ/5)
37#define WHEEL_COUNTER_DIV 2
38#define ACCEL_INCREMENT 3
39#define ACCEL_SHIFT 1
34 40
35/* Sandisk Sansa E200 button codes */ 41/* Sandisk Sansa E200 button codes */
36 42
diff --git a/firmware/target/arm/as3525/sansa-fuze/button-target.h b/firmware/target/arm/as3525/sansa-fuze/button-target.h
index 6dcd37460a..2cee93723e 100644
--- a/firmware/target/arm/as3525/sansa-fuze/button-target.h
+++ b/firmware/target/arm/as3525/sansa-fuze/button-target.h
@@ -31,6 +31,13 @@ void button_init_device(void);
31bool button_hold(void); 31bool button_hold(void);
32int button_read_device(void); 32int button_read_device(void);
33unsigned short button_read_dbop(void); 33unsigned short button_read_dbop(void);
34#define get_scrollwheel button_read_dbop
35
36#define WHEEL_REPEAT_INTERVAL (HZ/5)
37#define WHEEL_COUNTER_DIV 4
38#define ACCEL_INCREMENT 2
39#define ACCEL_SHIFT 2
40
34/* Sandisk Sansa Fuze button codes */ 41/* Sandisk Sansa Fuze button codes */
35 42
36/* Main unit's buttons */ 43/* Main unit's buttons */
diff --git a/firmware/target/arm/as3525/sansa-fuzev2/button-fuzev2.c b/firmware/target/arm/as3525/sansa-fuzev2/button-fuzev2.c
index 0a6d2c919c..4848d9e7d9 100644
--- a/firmware/target/arm/as3525/sansa-fuzev2/button-fuzev2.c
+++ b/firmware/target/arm/as3525/sansa-fuzev2/button-fuzev2.c
@@ -24,21 +24,50 @@
24#include "button.h" 24#include "button.h"
25#include "backlight.h" 25#include "backlight.h"
26 26
27/* 27extern void scrollwheel(unsigned wheel_value);
28 * TODO: Scrollwheel! 28
29 */
30
31#ifdef HAS_BUTTON_HOLD 29#ifdef HAS_BUTTON_HOLD
32static bool hold_button = false; 30static bool hold_button = false;
33#endif 31#endif
34void button_init_device(void) 32void button_init_device(void)
33{ /* activate the wheel */
34 volatile int i;
35 GPIOB_DIR |= 1<<4;
36 for(i = 20; i; i--) nop;
37 GPIOB_PIN(4) = 0x10;
38}
39
40unsigned read_GPIOA_67(void)
35{ 41{
42 unsigned ret = 0;
43 volatile int i;
44 DBOP_CTRL |= 1<<19;
45 for(i = 20; i; i--) nop;
46 GPIOA_DIR &= ~0xc0;
47 for(i = 20; i; i--) nop;
48 if (GPIOA_PIN(6) != 0)
49 ret = 1<<0;
50 for(i = 20; i; i--) nop;
51 if (GPIOA_PIN(7) != 0)
52 ret |= 1<<1;
53 DBOP_CTRL &= ~(1<<19);
54 for(i = 20; i; i--) nop;
55 return ret;
56}
57
58void get_scrollwheel(void)
59{
60#if defined(HAVE_SCROLLWHEEL) && !defined(BOOTLOADER)
61 /* scroll wheel handling */
62 scrollwheel(read_GPIOA_67());
63#endif
36} 64}
37 65
38/* 66/*
39 * Get button pressed from hardware 67 * Get button pressed from hardware
40 */ 68 */
41 69
70
42int button_read_device(void) 71int button_read_device(void)
43{ 72{
44 int btn = 0; 73 int btn = 0;
@@ -48,6 +77,7 @@ int button_read_device(void)
48 unsigned gpiod = GPIOD_DATA; 77 unsigned gpiod = GPIOD_DATA;
49 unsigned gpioa_dir = GPIOA_DIR; 78 unsigned gpioa_dir = GPIOA_DIR;
50 unsigned gpiod6; 79 unsigned gpiod6;
80 get_scrollwheel();
51 for(delay = 500; delay; delay--) nop; 81 for(delay = 500; delay; delay--) nop;
52 CCU_IO &= ~(1<<12); 82 CCU_IO &= ~(1<<12);
53 for(delay=8;delay;delay--) nop; 83 for(delay=8;delay;delay--) nop;
diff --git a/firmware/target/arm/as3525/sansa-fuzev2/button-target.h b/firmware/target/arm/as3525/sansa-fuzev2/button-target.h
index 6dcd37460a..14f3db18f7 100644
--- a/firmware/target/arm/as3525/sansa-fuzev2/button-target.h
+++ b/firmware/target/arm/as3525/sansa-fuzev2/button-target.h
@@ -31,6 +31,12 @@ void button_init_device(void);
31bool button_hold(void); 31bool button_hold(void);
32int button_read_device(void); 32int button_read_device(void);
33unsigned short button_read_dbop(void); 33unsigned short button_read_dbop(void);
34void get_scrollwheel(void);
35
36#define WHEEL_REPEAT_INTERVAL (HZ/5)
37#define WHEEL_COUNTER_DIV 4
38#define ACCEL_INCREMENT 2
39#define ACCEL_SHIFT 2
34/* Sandisk Sansa Fuze button codes */ 40/* Sandisk Sansa Fuze button codes */
35 41
36/* Main unit's buttons */ 42/* Main unit's buttons */
diff --git a/firmware/target/arm/as3525/scrollwheel-as3525.c b/firmware/target/arm/as3525/scrollwheel-as3525.c
new file mode 100644
index 0000000000..a9e012a31f
--- /dev/null
+++ b/firmware/target/arm/as3525/scrollwheel-as3525.c
@@ -0,0 +1,124 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2009-2010 by Thomas Martitz
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "config.h"
23#include "button.h"
24#include "kernel.h"
25#include "backlight.h"
26
27void scrollwheel(unsigned int wheel_value)
28{
29#ifndef BOOTLOADER
30 /* current wheel values, parsed from dbop and the resulting button */
31 unsigned btn = BUTTON_NONE;
32 /* old wheel values */
33 static unsigned old_wheel_value = 0;
34 static unsigned old_btn = BUTTON_NONE;
35
36 /*
37 * Getting BUTTON_REPEAT works like this: Remember when the btn value was
38 * posted to the button_queue last, and if it was recent enough, generate
39 * BUTTON_REPEAT
40 */
41 static long last_wheel_post = 0;
42
43 /*
44 * Providing wheel acceleration works as follows: We increment accel
45 * by 2 if the wheel was turned, and decrement it by 1 each tick
46 * (no matter if it was turned), that means: the longer and faster you turn,
47 * the higher accel will be. accel>>2 will actually posted to the button_queue
48 */
49 static int accel = 0;
50 /* We only post every 4th action, as this matches better with the physical
51 * clicks of the wheel */
52 static int counter = 0;
53 /* Read wheel
54 * Bits 13 and 14 of DBOP_DIN change as follows (Gray Code):
55 * Clockwise rotation 00 -> 01 -> 11 -> 10 -> 00
56 * Counter-clockwise 00 -> 10 -> 11 -> 01 -> 00
57 *
58 * For easy look-up, actual wheel values act as indicies also,
59 * which is why the table seems to be not ordered correctly
60 */
61 static const unsigned char wheel_tbl[2][4] =
62 {
63 { 2, 0, 3, 1 }, /* Clockwise rotation */
64 { 1, 3, 0, 2 }, /* Counter-clockwise */
65 };
66
67 if(button_hold())
68 {
69 accel = counter = 0;
70 return;
71 }
72
73 if (old_wheel_value == wheel_tbl[0][wheel_value])
74 btn = BUTTON_SCROLL_FWD;
75 else if (old_wheel_value == wheel_tbl[1][wheel_value])
76 btn = BUTTON_SCROLL_BACK;
77 else if (old_wheel_value != wheel_value && accel > ACCEL_INCREMENT)
78 { /* if no button is read and wheel_value changed, assume old_btn */
79 btn = old_btn;
80 }
81 /* else btn = BUTTON_NONE */
82
83 if (btn != BUTTON_NONE)
84 {
85 if (btn != old_btn)
86 {
87 /* direction reversals nullify acceleration and counters */
88 old_btn = btn;
89 accel = counter = 0;
90 }
91 /* wheel_delta will cause lists to jump over items,
92 * we want this for fast scrolling, but we must keep it accurate
93 * for slow scrolling */
94 int wheel_delta = 0;
95 /* generate BUTTON_REPEAT if quick enough, scroll slightly faster too*/
96 if (TIME_BEFORE(current_tick, last_wheel_post + WHEEL_REPEAT_INTERVAL))
97 {
98 btn |= BUTTON_REPEAT;
99 wheel_delta = accel>>ACCEL_SHIFT;
100 }
101
102 accel += ACCEL_INCREMENT;
103
104 /* the wheel is more reliable if we don't send every change,
105 * every WHEEL_COUNTER_DIVth is basically one "physical click"
106 * which should make up 1 item in lists */
107 if (++counter >= WHEEL_COUNTER_DIV && queue_empty(&button_queue))
108 {
109 buttonlight_on();
110 backlight_on();
111 queue_post(&button_queue, btn, ((wheel_delta+1)<<24));
112 /* message posted - reset count and remember post */
113 counter = 0;
114 last_wheel_post = current_tick;
115 }
116 }
117 if (accel > 0)
118 accel--;
119
120 old_wheel_value = wheel_value;
121#else
122 (void)wheel_value
123#endif
124}