summaryrefslogtreecommitdiffstats
path: root/firmware/target/arm
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 /firmware/target/arm
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
Diffstat (limited to 'firmware/target/arm')
-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
7 files changed, 180 insertions, 111 deletions
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 @@
#include "backlight.h"
#include "dbop-as3525.h"
+extern void scrollwheel(unsigned wheel_value);
-#if defined(SANSA_FUZE) || defined(SANSA_FUZEV2)
+#if defined(SANSA_FUZE)
#define DBOP_BIT15_BUTTON BUTTON_HOME
-#define WHEEL_REPEAT_INTERVAL (HZ/5)
-#define WHEEL_COUNTER_DIV 4
-#define ACCEL_INCREMENT 2
-#define ACCEL_SHIFT 2
#endif
#ifdef SANSA_E200V2
#define DBOP_BIT15_BUTTON BUTTON_REC
-#define WHEEL_REPEAT_INTERVAL (HZ/5)
-#define WHEEL_COUNTER_DIV 2
-#define ACCEL_INCREMENT 3
-#define ACCEL_SHIFT 1
#endif
/* Buttons */
@@ -56,103 +49,6 @@ void button_init_device(void)
GPIOA_PIN(1) = (1<<1);
}
-#if !defined(BOOTLOADER) && defined(HAVE_SCROLLWHEEL)
-static void scrollwheel(unsigned int wheel_value)
-{
- /* current wheel values, parsed from dbop and the resulting button */
- unsigned btn = BUTTON_NONE;
- /* old wheel values */
- static unsigned old_wheel_value = 0;
- static unsigned old_btn = BUTTON_NONE;
-
- /*
- * Getting BUTTON_REPEAT works like this: Remember when the btn value was
- * posted to the button_queue last, and if it was recent enough, generate
- * BUTTON_REPEAT
- */
- static long last_wheel_post = 0;
-
- /*
- * Providing wheel acceleration works as follows: We increment accel
- * by 2 if the wheel was turned, and decrement it by 1 each tick
- * (no matter if it was turned), that means: the longer and faster you turn,
- * the higher accel will be. accel>>2 will actually posted to the button_queue
- */
- static int accel = 0;
- /* We only post every 4th action, as this matches better with the physical
- * clicks of the wheel */
- static int counter = 0;
- /* Read wheel
- * Bits 13 and 14 of DBOP_DIN change as follows (Gray Code):
- * Clockwise rotation 00 -> 01 -> 11 -> 10 -> 00
- * Counter-clockwise 00 -> 10 -> 11 -> 01 -> 00
- *
- * For easy look-up, actual wheel values act as indicies also,
- * which is why the table seems to be not ordered correctly
- */
- static const unsigned char wheel_tbl[2][4] =
- {
- { 2, 0, 3, 1 }, /* Clockwise rotation */
- { 1, 3, 0, 2 }, /* Counter-clockwise */
- };
-
- if(hold_button)
- {
- accel = counter = 0;
- return;
- }
-
- if (old_wheel_value == wheel_tbl[0][wheel_value])
- btn = BUTTON_SCROLL_FWD;
- else if (old_wheel_value == wheel_tbl[1][wheel_value])
- btn = BUTTON_SCROLL_BACK;
- else if (old_wheel_value != wheel_value && accel > ACCEL_INCREMENT)
- { /* if no button is read and wheel_value changed, assume old_btn */
- btn = old_btn;
- }
- /* else btn = BUTTON_NONE */
-
- if (btn != BUTTON_NONE)
- {
- if (btn != old_btn)
- {
- /* direction reversals nullify acceleration and counters */
- old_btn = btn;
- accel = counter = 0;
- }
- /* wheel_delta will cause lists to jump over items,
- * we want this for fast scrolling, but we must keep it accurate
- * for slow scrolling */
- int wheel_delta = 0;
- /* generate BUTTON_REPEAT if quick enough, scroll slightly faster too*/
- if (TIME_BEFORE(current_tick, last_wheel_post + WHEEL_REPEAT_INTERVAL))
- {
- btn |= BUTTON_REPEAT;
- wheel_delta = accel>>ACCEL_SHIFT;
- }
-
- accel += ACCEL_INCREMENT;
-
- /* the wheel is more reliable if we don't send every change,
- * every WHEEL_COUNTER_DIVth is basically one "physical click"
- * which should make up 1 item in lists */
- if (++counter >= WHEEL_COUNTER_DIV && queue_empty(&button_queue))
- {
- buttonlight_on();
- backlight_on();
- queue_post(&button_queue, btn, ((wheel_delta+1)<<24));
- /* message posted - reset count and remember post */
- counter = 0;
- last_wheel_post = current_tick;
- }
- }
- if (accel > 0)
- accel--;
-
- old_wheel_value = wheel_value;
-}
-#endif /* !defined(BOOTLOADER) && defined(SCROLLWHEEL) */
-
bool button_hold(void)
{
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)
else
{
if (!button_hold())
- button_read_dbop(); /* Read the scrollwheel */
+ get_scrollwheel(); /* Read the scrollwheel */
}
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);
void button_init_device(void);
int button_read_device(void);
unsigned short button_read_dbop(void);
+#define get_scrollwheel button_read_dbop
+
+#define WHEEL_REPEAT_INTERVAL (HZ/5)
+#define WHEEL_COUNTER_DIV 2
+#define ACCEL_INCREMENT 3
+#define ACCEL_SHIFT 1
/* Sandisk Sansa E200 button codes */
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);
bool button_hold(void);
int button_read_device(void);
unsigned short button_read_dbop(void);
+#define get_scrollwheel button_read_dbop
+
+#define WHEEL_REPEAT_INTERVAL (HZ/5)
+#define WHEEL_COUNTER_DIV 4
+#define ACCEL_INCREMENT 2
+#define ACCEL_SHIFT 2
+
/* Sandisk Sansa Fuze button codes */
/* 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 @@
#include "button.h"
#include "backlight.h"
-/*
- * TODO: Scrollwheel!
- */
-
+extern void scrollwheel(unsigned wheel_value);
+
#ifdef HAS_BUTTON_HOLD
static bool hold_button = false;
#endif
void button_init_device(void)
+{ /* activate the wheel */
+ volatile int i;
+ GPIOB_DIR |= 1<<4;
+ for(i = 20; i; i--) nop;
+ GPIOB_PIN(4) = 0x10;
+}
+
+unsigned read_GPIOA_67(void)
{
+ unsigned ret = 0;
+ volatile int i;
+ DBOP_CTRL |= 1<<19;
+ for(i = 20; i; i--) nop;
+ GPIOA_DIR &= ~0xc0;
+ for(i = 20; i; i--) nop;
+ if (GPIOA_PIN(6) != 0)
+ ret = 1<<0;
+ for(i = 20; i; i--) nop;
+ if (GPIOA_PIN(7) != 0)
+ ret |= 1<<1;
+ DBOP_CTRL &= ~(1<<19);
+ for(i = 20; i; i--) nop;
+ return ret;
+}
+
+void get_scrollwheel(void)
+{
+#if defined(HAVE_SCROLLWHEEL) && !defined(BOOTLOADER)
+ /* scroll wheel handling */
+ scrollwheel(read_GPIOA_67());
+#endif
}
/*
* Get button pressed from hardware
*/
+
int button_read_device(void)
{
int btn = 0;
@@ -48,6 +77,7 @@ int button_read_device(void)
unsigned gpiod = GPIOD_DATA;
unsigned gpioa_dir = GPIOA_DIR;
unsigned gpiod6;
+ get_scrollwheel();
for(delay = 500; delay; delay--) nop;
CCU_IO &= ~(1<<12);
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);
bool button_hold(void);
int button_read_device(void);
unsigned short button_read_dbop(void);
+void get_scrollwheel(void);
+
+#define WHEEL_REPEAT_INTERVAL (HZ/5)
+#define WHEEL_COUNTER_DIV 4
+#define ACCEL_INCREMENT 2
+#define ACCEL_SHIFT 2
/* Sandisk Sansa Fuze button codes */
/* 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 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2009-2010 by Thomas Martitz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "config.h"
+#include "button.h"
+#include "kernel.h"
+#include "backlight.h"
+
+void scrollwheel(unsigned int wheel_value)
+{
+#ifndef BOOTLOADER
+ /* current wheel values, parsed from dbop and the resulting button */
+ unsigned btn = BUTTON_NONE;
+ /* old wheel values */
+ static unsigned old_wheel_value = 0;
+ static unsigned old_btn = BUTTON_NONE;
+
+ /*
+ * Getting BUTTON_REPEAT works like this: Remember when the btn value was
+ * posted to the button_queue last, and if it was recent enough, generate
+ * BUTTON_REPEAT
+ */
+ static long last_wheel_post = 0;
+
+ /*
+ * Providing wheel acceleration works as follows: We increment accel
+ * by 2 if the wheel was turned, and decrement it by 1 each tick
+ * (no matter if it was turned), that means: the longer and faster you turn,
+ * the higher accel will be. accel>>2 will actually posted to the button_queue
+ */
+ static int accel = 0;
+ /* We only post every 4th action, as this matches better with the physical
+ * clicks of the wheel */
+ static int counter = 0;
+ /* Read wheel
+ * Bits 13 and 14 of DBOP_DIN change as follows (Gray Code):
+ * Clockwise rotation 00 -> 01 -> 11 -> 10 -> 00
+ * Counter-clockwise 00 -> 10 -> 11 -> 01 -> 00
+ *
+ * For easy look-up, actual wheel values act as indicies also,
+ * which is why the table seems to be not ordered correctly
+ */
+ static const unsigned char wheel_tbl[2][4] =
+ {
+ { 2, 0, 3, 1 }, /* Clockwise rotation */
+ { 1, 3, 0, 2 }, /* Counter-clockwise */
+ };
+
+ if(button_hold())
+ {
+ accel = counter = 0;
+ return;
+ }
+
+ if (old_wheel_value == wheel_tbl[0][wheel_value])
+ btn = BUTTON_SCROLL_FWD;
+ else if (old_wheel_value == wheel_tbl[1][wheel_value])
+ btn = BUTTON_SCROLL_BACK;
+ else if (old_wheel_value != wheel_value && accel > ACCEL_INCREMENT)
+ { /* if no button is read and wheel_value changed, assume old_btn */
+ btn = old_btn;
+ }
+ /* else btn = BUTTON_NONE */
+
+ if (btn != BUTTON_NONE)
+ {
+ if (btn != old_btn)
+ {
+ /* direction reversals nullify acceleration and counters */
+ old_btn = btn;
+ accel = counter = 0;
+ }
+ /* wheel_delta will cause lists to jump over items,
+ * we want this for fast scrolling, but we must keep it accurate
+ * for slow scrolling */
+ int wheel_delta = 0;
+ /* generate BUTTON_REPEAT if quick enough, scroll slightly faster too*/
+ if (TIME_BEFORE(current_tick, last_wheel_post + WHEEL_REPEAT_INTERVAL))
+ {
+ btn |= BUTTON_REPEAT;
+ wheel_delta = accel>>ACCEL_SHIFT;
+ }
+
+ accel += ACCEL_INCREMENT;
+
+ /* the wheel is more reliable if we don't send every change,
+ * every WHEEL_COUNTER_DIVth is basically one "physical click"
+ * which should make up 1 item in lists */
+ if (++counter >= WHEEL_COUNTER_DIV && queue_empty(&button_queue))
+ {
+ buttonlight_on();
+ backlight_on();
+ queue_post(&button_queue, btn, ((wheel_delta+1)<<24));
+ /* message posted - reset count and remember post */
+ counter = 0;
+ last_wheel_post = current_tick;
+ }
+ }
+ if (accel > 0)
+ accel--;
+
+ old_wheel_value = wheel_value;
+#else
+ (void)wheel_value
+#endif
+}