summaryrefslogtreecommitdiff
path: root/firmware/target/coldfire/mpio/hd300/button-hd300.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/coldfire/mpio/hd300/button-hd300.c')
-rw-r--r--firmware/target/coldfire/mpio/hd300/button-hd300.c234
1 files changed, 234 insertions, 0 deletions
diff --git a/firmware/target/coldfire/mpio/hd300/button-hd300.c b/firmware/target/coldfire/mpio/hd300/button-hd300.c
new file mode 100644
index 0000000000..19c93abfca
--- /dev/null
+++ b/firmware/target/coldfire/mpio/hd300/button-hd300.c
@@ -0,0 +1,234 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 Marcin Bukat
11 * scrollstrip logic inspired by button-mini1g.c
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22
23#include "config.h"
24#include "cpu.h"
25#include "system.h"
26#include "button.h"
27#include "backlight.h"
28#include "adc.h"
29#include "powermgmt.h"
30
31#define SLIDER_BASE_SENSITIVITY 6
32
33/* GPI7 H-L, GPI6 H-L, GPI7 L-H, GPI6 L-H */
34#define SLIDER_GPIO_MASK ((1<<15)|(1<<14)|(1<<7)|(1<<6))
35
36static inline void disable_scrollstrip_interrupts(void)
37{
38 and_l(~SLIDER_GPIO_MASK,&GPIO_INT_EN);
39}
40
41static inline void enable_scrollstrip_interrupts(void)
42{
43
44 or_l(SLIDER_GPIO_MASK,&GPIO_INT_EN);
45}
46
47static inline void ack_scrollstrip_interrupt(void)
48{
49 or_l(SLIDER_GPIO_MASK,&GPIO_INT_CLEAR);
50}
51
52void scrollstrip_isr(void) __attribute__ ((interrupt_handler,section(".icode")));
53void scrollstrip_isr(void)
54{
55 /* reading line 6 and 7 forms four possible states:
56 * 0, 1 , 2, 3
57 * tracking the order of line changes we can judge
58 * if the slide is up or down in the following way:
59 * sliding up order: 0 2 3 1 0 2 3 1
60 * sliding down order: 0 1 3 2 0 1 3 2
61 */
62 static const signed char scroll_state[4][4] ICONST_ATTR = {
63 { BUTTON_NONE, BUTTON_DOWN, BUTTON_UP, BUTTON_NONE},
64 { BUTTON_UP, BUTTON_NONE, BUTTON_NONE, BUTTON_DOWN},
65 { BUTTON_DOWN, BUTTON_NONE, BUTTON_NONE, BUTTON_UP},
66 { BUTTON_NONE, BUTTON_UP, BUTTON_DOWN, BUTTON_NONE}
67 };
68
69 static signed char prev_scroll_lines = -1;
70 static signed char direction = 0;
71 static unsigned char count = 0;
72 static long next_backlight_on = 0;
73
74 signed int new_scroll_lines;
75 signed int scroll_dir;
76
77 disable_scrollstrip_interrupts();
78
79 /* read GPIO6 and GPIO7 state*/
80 new_scroll_lines = (GPIO_READ >> 6) & 0x03;
81
82 if ( prev_scroll_lines == -1 )
83 {
84 prev_scroll_lines = new_scroll_lines;
85 ack_scrollstrip_interrupt();
86 enable_scrollstrip_interrupts();
87 return;
88 }
89
90 scroll_dir = scroll_state[prev_scroll_lines][new_scroll_lines];
91 prev_scroll_lines = new_scroll_lines;
92
93 if (direction != scroll_dir)
94 {
95 /* direction reversal */
96 direction = scroll_dir;
97 count = 0;
98 ack_scrollstrip_interrupt();
99 enable_scrollstrip_interrupts();
100 return;
101 }
102
103 /* poke backlight */
104 if (TIME_AFTER(current_tick, next_backlight_on))
105 {
106 backlight_on();
107 reset_poweroff_timer();
108 next_backlight_on = current_tick + HZ/4;
109 }
110
111 if (++count < SLIDER_BASE_SENSITIVITY)
112 {
113 ack_scrollstrip_interrupt();
114 enable_scrollstrip_interrupts();
115 return;
116 }
117
118 count = 0;
119
120 /* post scrollstrip event to the button queue */
121 if (queue_empty(&button_queue))
122 queue_post(&button_queue, scroll_dir, 0);
123
124 ack_scrollstrip_interrupt();
125 enable_scrollstrip_interrupts();
126}
127
128/* register interrupt service routine for scrollstrip lines */
129void GPI6(void) __attribute__ ((alias("scrollstrip_isr")));
130void GPI7(void) __attribute__ ((alias("scrollstrip_isr")));
131
132void button_init_device(void)
133{
134 /* GPIO56 (PLAY) general input
135 * GPIO45 (ENTER) general input
136 * GPIO41 (MENU) dual function pin shared with audio serial data
137 *
138 * GPIO6, GPIO7 scrollstrip lines
139 * GPIO31 scrollstrip enable
140 */
141
142 or_l((1<<24)|(1<<13),&GPIO1_FUNCTION);
143 and_l(~((1<<24)|(1<<13)),&GPIO1_ENABLE);
144
145 or_l((1<<31)|(1<<7)|(1<<6),&GPIO_FUNCTION);
146 and_l(~((1<<7)|(1<<6)),&GPIO_ENABLE);
147
148 /* scrollstrip enable active low */
149 and_l(~(1<<31),&GPIO_OUT);
150 or_l((1<<31),&GPIO_ENABLE);
151
152 /* GPI6, GPI7 interrupt level 4.0 */
153 or_l((4<<28)|(4<<24), &INTPRI5);
154
155 enable_scrollstrip_interrupts();
156}
157
158bool button_hold(void)
159{
160 /* GPIO51 active low */
161 return (GPIO1_READ & (1<<19))?false:true;
162}
163
164/*
165 * Get button pressed from hardware
166 */
167int button_read_device(void)
168{
169 int btn = BUTTON_NONE;
170 int data = 0;
171 static bool hold_button = false;
172
173 bool hold_button_old;
174
175
176 /* read hold buttons status */
177 hold_button_old = hold_button;
178 hold_button = button_hold();
179
180#ifndef BOOTLOADER
181 /* Only main hold affects backlight */
182 if (hold_button != hold_button_old)
183 backlight_hold_changed(hold_button);
184#endif
185
186 /* Skip if main hold is active */
187 if (!hold_button)
188 {
189 data = adc_scan(ADC_BUTTONS);
190
191 if (data < 800) /* middle */
192 {
193 if (data < 450)
194 {
195 if (data > 250)
196 btn |= BUTTON_FF;
197 }
198 else /* 800 - 450 */
199 {
200 if (data > 600)
201 btn |= BUTTON_REW;
202 }
203 }
204 else /* data > 800 */
205 {
206 if (data < 1150)
207 if (data > 950)
208 btn |= BUTTON_REC;
209 }
210 }
211
212 /* Handle GPIOs buttons
213 *
214 * GPIO56 active high PLAY/PAUSE/ON
215 * GPIO45 active low ENTER
216 * GPIO41 active low MENU
217 */
218
219 data = GPIO1_READ;
220
221 if (!hold_button)
222 {
223 if (data & (1<<24))
224 btn |= BUTTON_PLAY;
225
226 if (!(data & (1<<13)))
227 btn |= BUTTON_ENTER;
228
229 if (!(data & (1<<9)))
230 btn |= BUTTON_MENU;
231 }
232
233 return btn;
234}