summaryrefslogtreecommitdiff
path: root/firmware/target/arm
diff options
context:
space:
mode:
authorRafaël Carré <rafael.carre@gmail.com>2011-12-13 23:12:21 +0000
committerRafaël Carré <rafael.carre@gmail.com>2011-12-13 23:12:21 +0000
commitdfff88562e700ab1772c9bbb50c47bff00b9a002 (patch)
treec3479f8daff4b28c91823724257e3bfdf5263452 /firmware/target/arm
parent744adcba81f462f41c18557d28883c086c27edf7 (diff)
Sansa Clip: simplify matrix key scan
Merge clipv1/clipv2 code since they use the same 3x3 matrix clipzip keyscan buttons now work in bootloader clipplus untouched (no matrix) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31235 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm')
-rw-r--r--firmware/target/arm/as3525/button-clip.c (renamed from firmware/target/arm/as3525/sansa-clipv2/button-clip.c)115
-rw-r--r--firmware/target/arm/as3525/sansa-clip/button-clip.c156
-rw-r--r--firmware/target/arm/as3525/sansa-clipzip/button-clipzip.c97
3 files changed, 82 insertions, 286 deletions
diff --git a/firmware/target/arm/as3525/sansa-clipv2/button-clip.c b/firmware/target/arm/as3525/button-clip.c
index 1356bfbc55..b6679ca359 100644
--- a/firmware/target/arm/as3525/sansa-clipv2/button-clip.c
+++ b/firmware/target/arm/as3525/button-clip.c
@@ -27,14 +27,37 @@
#include "backlight.h"
#endif
+#if defined(SANSA_CLIP)
+# define OUT_PIN GPIOC_PIN
+# define OUT_DIR GPIOC_DIR
+# define OUT_INITIAL 0
+# define IN_PIN GPIOB_PIN
+# define IN_DIR GPIOB_DIR
+#elif defined(SANSA_CLIPV2)
+# define OUT_PIN GPIOD_PIN
+# define OUT_DIR GPIOD_DIR
+# define OUT_INITIAL 1
+# define IN_PIN GPIOD_PIN
+# define IN_DIR GPIOD_DIR
+#endif
+
+static const int rows[3] = {
+#if defined(SANSA_CLIP)
+ 4, 5, 6
+#elif defined(SANSA_CLIPV2)
+ 5, 6, 4
+#endif
+};
+
void button_init_device(void)
{
GPIOA_DIR &= ~((1<<7) | (1<<3));
- GPIOD_DIR &= ~((1<<2) | (1<<1) | (1<<0));
- GPIOD_PIN(3) = 1<<3;
- GPIOD_PIN(4) = 1<<4;
- GPIOD_PIN(5) = 1<<5;
- GPIOD_DIR |= ((1<<5) | (1<<4) | (1<<3));
+ IN_DIR &= ~((1<<2) | (1<<1) | (1<<0));
+
+ for (int i = 0; i < 3; i++) {
+ OUT_PIN(rows[i]) = OUT_INITIAL << rows[i];
+ OUT_DIR |= 1 << rows[i];
+ }
/* get initial readings */
button_read_device();
@@ -44,9 +67,8 @@ void button_init_device(void)
int button_read_device(void)
{
- static int row = 0;
- static int buttons = 0;
- static unsigned power_counter = 0;
+ static int row, buttons;
+ static unsigned power_counter;
if(button_hold())
{
@@ -66,84 +88,47 @@ int button_read_device(void)
else
buttons &= ~BUTTON_POWER;
- /* This is a keypad using D3-D5 as columns and D0-D2 as rows */
- switch (row) {
-
- case 0:
- buttons &= ~(BUTTON_VOL_UP | BUTTON_UP);
-
- (void)GPIOD_PIN(0); /* D3D0 is unused */
-
- if (!GPIOD_PIN(1))
- buttons |= BUTTON_VOL_UP;
-
- if (!GPIOD_PIN(2))
- buttons |= BUTTON_UP;
-
- GPIOD_PIN(3) = 1<<3;
- GPIOD_PIN(4) = 0x00;
- row++;
- break;
-
- case 1:
- buttons &= ~(BUTTON_LEFT | BUTTON_SELECT | BUTTON_RIGHT);
-
- if (!GPIOD_PIN(0))
- buttons |= BUTTON_LEFT;
-
- if (!GPIOD_PIN(1))
- buttons |= BUTTON_SELECT;
+ static const int matrix [3][3] = {
+ { 0 /*unused*/, BUTTON_VOL_UP, BUTTON_UP },
+ { BUTTON_LEFT, BUTTON_SELECT, BUTTON_RIGHT },
+ { BUTTON_DOWN, BUTTON_VOL_DOWN, BUTTON_HOME },
+ };
- if (!GPIOD_PIN(2))
- buttons |= BUTTON_RIGHT;
+ for (int i = 0; i<3; i++)
+ if (IN_PIN(i))
+ buttons |= matrix[row][i];
+ else
+ buttons &= ~matrix[row][i];
- GPIOD_PIN(4) = 1<<4;
- GPIOD_PIN(5) = 0x00;
- row++;
- break;
-
- case 2:
- buttons &= ~(BUTTON_DOWN | BUTTON_VOL_DOWN | BUTTON_HOME);
-
- if (!GPIOD_PIN(0))
- buttons |= BUTTON_DOWN;
-
- if (!GPIOD_PIN(1))
- buttons |= BUTTON_VOL_DOWN;
-
- if (!GPIOD_PIN(2))
- buttons |= BUTTON_HOME;
-
- GPIOD_PIN(5) = 1<<5;
- GPIOD_PIN(3) = 0x00;
-
- default:
- row = 0;
- break;
- }
+ /* prepare next row */
+ OUT_PIN(rows[row]) = 0 << rows[row];
+ row++;
+ row %= 3;
+ OUT_PIN(rows[row]) = 1 << rows[row];
return buttons;
}
bool button_hold(void)
{
-#ifndef BOOTLOADER
- static bool hold_button_old = false;
-#endif
-
+#ifdef SANSA_CLIPV2
GPIOA_DIR |= 1<<7;
GPIOA_PIN(7) = 1<<7;
int delay = 50;
while(delay--)
asm("nop");
+#endif
bool hold_button = (GPIOA_PIN(3) != 0);
+#ifdef SANSA_CLIPV2
GPIOA_PIN(7) = 0;
GPIOA_DIR &= ~(1<<7);
+#endif
#ifndef BOOTLOADER
+ static bool hold_button_old = false;
/* light handling */
if (hold_button != hold_button_old)
{
diff --git a/firmware/target/arm/as3525/sansa-clip/button-clip.c b/firmware/target/arm/as3525/sansa-clip/button-clip.c
deleted file mode 100644
index a64fddb564..0000000000
--- a/firmware/target/arm/as3525/sansa-clip/button-clip.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * Copyright (C) 2009 Bertrik Sikken
- * Copyright (C) 2008 François Dinel
- * Copyright (C) 2008 Rafaël Carré
- *
- * 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 "system.h"
-#include "button-target.h"
-#include "as3525.h"
-#ifndef BOOTLOADER /* backlight on hold handling */
-#include "backlight.h"
-#endif
-
-/* The Sansa Clip uses a button matrix that is scanned by selecting one of
- three rows and reading back the button states from the columns.
-
- In this driver, the row is changed at each call (i.e. once per tick).
- In one tick, column data from one row is read back and then the next row
- is selected for the following tick. This mechanism ensures that there is
- plenty time between selecting a row and reading the columns, avoiding the
- need for explicit delays.
-*/
-
-
-void button_init_device(void)
-{
- GPIOA_DIR &= ~((1<<7) | (1<<3));
- GPIOB_DIR &= ~((1<<2) | (1<<1) | (1<<0));
- GPIOC_PIN(4) = 0;
- GPIOC_PIN(5) = 0;
- GPIOC_PIN(6) = 0;
- GPIOC_DIR |= ((1<<6) | (1<<5) | (1<<4));
-
- /* get initial readings */
- button_read_device();
- button_read_device();
- button_read_device();
-}
-
-int button_read_device(void)
-{
- static int row = 0;
- static int buttons = 0;
- static unsigned power_counter = 0;
-
- if(button_hold())
- {
- power_counter = HZ;
- return 0;
- }
-
- /* direct GPIO connections */
- /* read power, but not if hold button was just released, since
- * you basically always hit power due to the slider mechanism after
- * releasing hold (wait 1 sec) */
- if (power_counter)
- power_counter--;
-
- if (GPIOA_PIN(7) && !power_counter)
- buttons |= BUTTON_POWER;
- else
- buttons &= ~BUTTON_POWER;
-
- /* This is a keypad using C4-C6 as columns and B0-B2 as rows */
- switch (row) {
-
- case 0:
- buttons &= ~(BUTTON_VOL_UP | BUTTON_UP);
-
- (void)GPIOB_PIN(0); /* C4B0 is unused */
-
- if (GPIOB_PIN(1))
- buttons |= BUTTON_VOL_UP;
-
- if (GPIOB_PIN(2))
- buttons |= BUTTON_UP;
-
- GPIOC_PIN(4) = 0;
- GPIOC_PIN(5) = (1<<5);
- row++;
- break;
-
- case 1:
- buttons &= ~(BUTTON_LEFT | BUTTON_SELECT | BUTTON_RIGHT);
-
- if (GPIOB_PIN(0))
- buttons |= BUTTON_LEFT;
-
- if (GPIOB_PIN(1))
- buttons |= BUTTON_SELECT;
-
- if (GPIOB_PIN(2))
- buttons |= BUTTON_RIGHT;
-
- GPIOC_PIN(5) = 0;
- GPIOC_PIN(6) = (1<<6);
- row++;
- break;
-
- case 2:
- buttons &= ~(BUTTON_DOWN | BUTTON_VOL_DOWN | BUTTON_HOME);
-
- if (GPIOB_PIN(0))
- buttons |= BUTTON_DOWN;
-
- if (GPIOB_PIN(1))
- buttons |= BUTTON_VOL_DOWN;
-
- if (GPIOB_PIN(2))
- buttons |= BUTTON_HOME;
-
- GPIOC_PIN(6) = 0;
- GPIOC_PIN(4) = (1<<4);
-
- default:
- row = 0;
- break;
- }
-
- return buttons;
-}
-
-bool button_hold(void)
-{
- bool hold_button = (GPIOA_PIN(3) != 0);
-
-#ifndef BOOTLOADER
- /* backlight handling */
-
- static bool hold_button_old = false;
-
- if (hold_button != hold_button_old)
- {
- hold_button_old = hold_button;
- backlight_hold_changed(hold_button);
- }
-#endif /* BOOTLOADER */
-
- return hold_button;
-}
diff --git a/firmware/target/arm/as3525/sansa-clipzip/button-clipzip.c b/firmware/target/arm/as3525/sansa-clipzip/button-clipzip.c
index 40b20cdce3..c22c5e24e9 100644
--- a/firmware/target/arm/as3525/sansa-clipzip/button-clipzip.c
+++ b/firmware/target/arm/as3525/sansa-clipzip/button-clipzip.c
@@ -21,97 +21,64 @@
****************************************************************************/
#include "config.h"
-
#include "button-target.h"
#include "as3525v2.h"
+#include "system.h"
#include "kernel.h"
-#include "system-target.h"
static int keyscan(void)
{
- static int buttons = 0;
- static int row = 1;
+ static int buttons, row;
+ static const int matrix[2][3] = {
+ { BUTTON_RIGHT, BUTTON_SELECT, BUTTON_UP },
+ { BUTTON_HOME, BUTTON_DOWN, BUTTON_LEFT },
+ };
+
+ for (int i = 0; i < 3; i++)
+ if (GPIOC_PIN(3 + i))
+ buttons |= matrix[row][i];
+ else
+ buttons &= ~matrix[row][i];
- switch (row) {
-
- case 1:
- /* read row 1 */
- buttons &= ~(BUTTON_RIGHT | BUTTON_SELECT | BUTTON_UP);
- if (GPIOC_PIN(3)) {
- buttons |= BUTTON_RIGHT;
- }
- if (GPIOC_PIN(4)) {
- buttons |= BUTTON_SELECT;
- }
- if (GPIOC_PIN(5)) {
- buttons |= BUTTON_UP;
- }
-
- /* prepare row 2 */
- GPIOC_PIN(1) = 0;
- GPIOC_PIN(2) = (1 << 2);
- row = 2;
- break;
-
- case 2:
- /* read row 2 */
- buttons &= ~(BUTTON_HOME | BUTTON_DOWN | BUTTON_LEFT);
- if (GPIOC_PIN(3)) {
- buttons |= BUTTON_HOME;
- }
- if (GPIOC_PIN(4)) {
- buttons |= BUTTON_DOWN;
- }
- if (GPIOC_PIN(5)) {
- buttons |= BUTTON_LEFT;
- }
-
- /* prepare row 1 */
- GPIOC_PIN(1) = (1 << 1);
- GPIOC_PIN(2) = 0;
- row = 1;
- break;
+ /* prepare next row */
+ GPIOC_PIN(1) = row << 1;
+ row ^= 1;
+ GPIOC_PIN(2) = row << 2;
+
+ /* delay a bit if interrupts are disabled, to be sure next row will read */
+ if (!irq_enabled())
+ for (volatile int i = 0; i < 0x500; i++) ;
- default:
- row = 1;
- break;
- }
-
return buttons;
}
void button_init_device(void)
{
/* GPIO A6, A7 and D6 are direct button inputs */
- GPIOA_DIR &= ~(1 << 6);
- GPIOA_DIR &= ~(1 << 7);
+ GPIOA_DIR &= ~(1 << 6 | 1<< 7);
GPIOD_DIR &= ~(1 << 6);
-
+
/* GPIO C1, C2, C3, C4, C5 are used in a column/row key scan matrix */
GPIOC_DIR |= ((1 << 1) | (1 << 2));
GPIOC_DIR &= ~((1 << 3) | (1 << 4) | (1 << 5));
+
+ /* initial reading */
+ button_read_device();
+ sleep(1);
+ button_read_device();
+ sleep(1);
}
int button_read_device(void)
{
int buttons = 0;
- /* power */
- if (GPIOD_PIN(6)) {
+ if (GPIOD_PIN(6))
buttons |= BUTTON_POWER;
- }
-
- /* volume */
- if (GPIOA_PIN(6)) {
+ if (GPIOA_PIN(6))
buttons |= BUTTON_VOL_DOWN;
- }
- if (GPIOA_PIN(7)) {
+ if (GPIOA_PIN(7))
buttons |= BUTTON_VOL_UP;
- }
-
- /* keyscan buttons */
- buttons |= keyscan();
- return buttons;
+ return buttons | keyscan();
}
-