summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2009-06-02 01:31:16 +0000
committerThomas Martitz <kugel@rockbox.org>2009-06-02 01:31:16 +0000
commit4aec45e68f8d94d1a2c96915b9797d47be63b3d5 (patch)
tree8b5b0b8cf65c108d15ae4acb81249585550d8ca3
parent9c3e679d188ec6c117a33ef280d81943a8e37bc8 (diff)
downloadrockbox-4aec45e68f8d94d1a2c96915b9797d47be63b3d5.tar.gz
rockbox-4aec45e68f8d94d1a2c96915b9797d47be63b3d5.zip
Revisite Sansa fuze button driver:
*Correct/update some comments *Make BUTTON_REPEAT generation more relable (do it like the e200v2, but with a shorter repeat intervall) *adjust button_delay *remove unecessary wait for fifo empty (no lcd function returns with fifo not empty) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21166 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/arm/as3525/sansa-fuze/button-fuze.c67
1 files changed, 38 insertions, 29 deletions
diff --git a/firmware/target/arm/as3525/sansa-fuze/button-fuze.c b/firmware/target/arm/as3525/sansa-fuze/button-fuze.c
index efa1c593a3..f8c489c4dd 100644
--- a/firmware/target/arm/as3525/sansa-fuze/button-fuze.c
+++ b/firmware/target/arm/as3525/sansa-fuze/button-fuze.c
@@ -23,8 +23,8 @@
23 23
24/* Basic button driver for the Fuze 24/* Basic button driver for the Fuze
25 * 25 *
26 * TODO: - Get the wheel working with interrupts 26 * TODO: - Get the wheel working with interrupts (seems to be impossible
27 * - find that Home button 27 * so far)
28 */ 28 */
29 29
30#include "system.h" 30#include "system.h"
@@ -32,6 +32,8 @@
32#include "button-target.h" 32#include "button-target.h"
33#include "backlight.h" 33#include "backlight.h"
34 34
35#define WHEEL_REPEAT_INTERVAL (HZ/5)
36
35/* Buttons */ 37/* Buttons */
36static bool hold_button = false; 38static bool hold_button = false;
37#ifndef BOOTLOADER 39#ifndef BOOTLOADER
@@ -58,13 +60,22 @@ static void scrollwheel(unsigned short dbop_din)
58 static unsigned old_wheel_value = 0; 60 static unsigned old_wheel_value = 0;
59 static unsigned old_btn = BUTTON_NONE; 61 static unsigned old_btn = BUTTON_NONE;
60 62
61 /* getting BUTTON_REPEAT works like this: We increment repeat by 2 if the 63 /*
62 * wheel was turned, and decrement it by 1 each tick, 64 * Getting BUTTON_REPEAT works like this: Remember when the btn value was
63 * that means: if you change the wheel fast enough, repeat will be >1 and 65 * posted to the button_queue last, and if it was recent enough, generate
64 * we send BUTTON_REPEAT 66 * BUTTON_REPEAT
67 */
68 static long last_wheel_post = 0;
69
70 /*
71 * Providing wheel acceleration works as follows: We increment accel
72 * by 2 if the wheel was turned, and decrement it by 1 each tick
73 * (no matter if it was turned), that means: the longer and faster you turn,
74 * the higher accel will be. accel>>2 will actually posted to the button_queue
65 */ 75 */
66 static int repeat = 0; 76 static int accel = 0;
67 /* we omit 3 of 4 posts to the button_queue, that works better, so count */ 77 /* We only post every 4th action, as this matches better with the physical
78 * clicks of the wheel */
68 static int counter = 0; 79 static int counter = 0;
69 /* Read wheel 80 /* Read wheel
70 * Bits 13 and 14 of DBOP_DIN change as follows: 81 * Bits 13 and 14 of DBOP_DIN change as follows:
@@ -79,7 +90,7 @@ static void scrollwheel(unsigned short dbop_din)
79 90
80 if(hold_button) 91 if(hold_button)
81 { 92 {
82 repeat = counter = 0; 93 accel = counter = 0;
83 return; 94 return;
84 } 95 }
85 96
@@ -95,39 +106,39 @@ static void scrollwheel(unsigned short dbop_din)
95 { 106 {
96 if (btn != old_btn) 107 if (btn != old_btn)
97 { 108 {
98 /* direction reversals nullify repeats */ 109 /* direction reversals nullify acceleration and counters */
99 old_btn = btn; 110 old_btn = btn;
100 repeat = counter = 0; 111 accel = counter = 0;
101 } 112 }
102 /* wheel_delta will cause lists to jump over items, 113 /* wheel_delta will cause lists to jump over items,
103 * we want this for fast scrolling, but we must keep it accurate 114 * we want this for fast scrolling, but we must keep it accurate
104 * for slow scrolling */ 115 * for slow scrolling */
105 int wheel_delta = 0; 116 int wheel_delta = 0;
106 /* generate repeats if quick enough, scroll slightly faster too*/ 117 /* generate BUTTON_REPEAT if quick enough, scroll slightly faster too*/
107 if (repeat > 1) 118 if (TIME_BEFORE(current_tick, last_wheel_post + WHEEL_REPEAT_INTERVAL))
108 { 119 {
109 btn |= BUTTON_REPEAT; 120 btn |= BUTTON_REPEAT;
110 wheel_delta = repeat>>2; 121 wheel_delta = accel>>2;
111 } 122 }
112 123
113 repeat += 2; 124 accel += 2;
114 125
115 /* the wheel is more reliable if we don't send ever change, 126 /* the wheel is more reliable if we don't send every change,
116 * every 4th is basically one "physical click" is 1 item in 127 * every 4th is basically one "physical click" which should
117 * the rockbox menus */ 128 * make up 1 item in lists */
118 if (++counter >= 4 && queue_empty(&button_queue)) 129 if (++counter >= 4 && queue_empty(&button_queue))
119 { 130 {
120 buttonlight_on(); 131 buttonlight_on();
121 backlight_on(); 132 backlight_on();
122 queue_post(&button_queue, btn, ((wheel_delta+1)<<24)); 133 queue_post(&button_queue, btn, ((wheel_delta+1)<<24));
123 /* message posted - reset count */ 134 /* message posted - reset count and remember post */
124 counter = 0; 135 counter = 0;
136 last_wheel_post = current_tick;
125 } 137 }
126 } 138 }
127 if (repeat > 0) 139 if (accel > 0)
128 repeat--; 140 accel--;
129 else 141
130 repeat = 0;
131 old_wheel_value = wheel_value; 142 old_wheel_value = wheel_value;
132} 143}
133#endif /* !defined(BOOTLOADER) && defined(SCROLLWHEEL) */ 144#endif /* !defined(BOOTLOADER) && defined(SCROLLWHEEL) */
@@ -139,8 +150,8 @@ bool button_hold(void)
139 150
140static void button_delay(void) 151static void button_delay(void)
141{ 152{
142 int i = 32; 153 int i = 24;
143 while(i--); 154 while(i--) asm volatile ("nop\n");
144} 155}
145 156
146unsigned short button_read_dbop(void) 157unsigned short button_read_dbop(void)
@@ -155,7 +166,6 @@ unsigned short button_read_dbop(void)
155 } 166 }
156 167
157 /* Set up dbop for input */ 168 /* Set up dbop for input */
158 while (!(DBOP_STAT & (1<<10))); /* Wait for fifo to empty */
159 DBOP_CTRL |= (1<<19); /* Tri-state DBOP on read cycle */ 169 DBOP_CTRL |= (1<<19); /* Tri-state DBOP on read cycle */
160 DBOP_CTRL &= ~(1<<16); /* disable output (1:write enabled) */ 170 DBOP_CTRL &= ~(1<<16); /* disable output (1:write enabled) */
161 DBOP_TIMPOL_01 = 0xe167e167; /* Set Timing & Polarity regs 0 & 1 */ 171 DBOP_TIMPOL_01 = 0xe167e167; /* Set Timing & Polarity regs 0 & 1 */
@@ -211,8 +221,7 @@ static int button_gpio(void)
211 GPIOC_DIR &= ~(1<<2|1<<3|1<<4|1<<5|1<<6); 221 GPIOC_DIR &= ~(1<<2|1<<3|1<<4|1<<5|1<<6);
212 222
213 /* small delay needed to read buttons correctly */ 223 /* small delay needed to read buttons correctly */
214 int delay = 0; 224 button_delay();
215 while(delay++ < 32);
216 225
217 /* direct GPIO connections */ 226 /* direct GPIO connections */
218 if (!GPIOC_PIN(3)) 227 if (!GPIOC_PIN(3))
@@ -251,7 +260,7 @@ int button_read_device(void)
251 hold_button = false; 260 hold_button = false;
252 /* read power on bit 8, but not if hold button was just released, since 261 /* read power on bit 8, but not if hold button was just released, since
253 * you basically always hit power due to the slider mechanism after releasing 262 * you basically always hit power due to the slider mechanism after releasing
254 * hold (wait ~1 sec) */ 263 * hold (wait 1 sec) */
255 if (power_counter) 264 if (power_counter)
256 power_counter--; 265 power_counter--;
257 if (!power_counter && dbop & (1<<8)) 266 if (!power_counter && dbop & (1<<8))