summaryrefslogtreecommitdiff
path: root/firmware/target/arm/as3525/sansa-fuzev2/button-fuzev2.c
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2012-01-08 22:29:25 +0000
committerMichael Sevakis <jethead71@rockbox.org>2012-01-08 22:29:25 +0000
commit307cb049485cc20140b85aa78f8e2677e8df5851 (patch)
treeeaadfd7266e4e97e69bccd68655140dd9f1ef061 /firmware/target/arm/as3525/sansa-fuzev2/button-fuzev2.c
parent5e21bbf5757163725f4bd2909fc7aaa548f61fc3 (diff)
downloadrockbox-307cb049485cc20140b85aa78f8e2677e8df5851.tar.gz
rockbox-307cb049485cc20140b85aa78f8e2677e8df5851.zip
AS3525v1/2: Enable nested handling of interrupts
Mostly for the sake of reducing latency for audio servicing where other service routines can take a long time to complete, leading to occasional drops of a few samples, especially in recording, where they are fairly frequent. One mystery that remains is GPIOA IRQ being interrupted causes strange undefined instruction exceptions, most easily produced on my Fuze V2 with a scrollwheel. Making GPIOA the top ISR for now, thus not interruptible, cures it. SVC mode is used during the actual calls. Hopefully the SVC stack size is sufficient. Prologue and epilogue code only uses the IRQ stack and is large enough. Any routine code that should not be interrupted should disable IRQ itself from here on in. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31642 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/as3525/sansa-fuzev2/button-fuzev2.c')
-rw-r--r--firmware/target/arm/as3525/sansa-fuzev2/button-fuzev2.c34
1 files changed, 21 insertions, 13 deletions
diff --git a/firmware/target/arm/as3525/sansa-fuzev2/button-fuzev2.c b/firmware/target/arm/as3525/sansa-fuzev2/button-fuzev2.c
index 7f82b692c7..8244c475fa 100644
--- a/firmware/target/arm/as3525/sansa-fuzev2/button-fuzev2.c
+++ b/firmware/target/arm/as3525/sansa-fuzev2/button-fuzev2.c
@@ -30,6 +30,7 @@ static bool hold_button = false;
30 30
31#ifdef HAVE_SCROLLWHEEL 31#ifdef HAVE_SCROLLWHEEL
32#define SCROLLWHEEL_BITS (1<<7|1<<6) 32#define SCROLLWHEEL_BITS (1<<7|1<<6)
33#define SCROLLWHEEL_BITS_POS 6
33 /* TIMER units */ 34 /* TIMER units */
34#define TIMER_TICK (KERNEL_TIMER_FREQ/HZ)/* how long a tick lasts */ 35#define TIMER_TICK (KERNEL_TIMER_FREQ/HZ)/* how long a tick lasts */
35#define TIMER_MS (TIMER_TICK/(1000/HZ))/* how long a ms lasts */ 36#define TIMER_MS (TIMER_TICK/(1000/HZ))/* how long a ms lasts */
@@ -78,10 +79,17 @@ static void scrollwheel(unsigned int wheel_value)
78 79
79 unsigned int btn = BUTTON_NONE; 80 unsigned int btn = BUTTON_NONE;
80 81
81 if (old_wheel_value == wheel_tbl[0][wheel_value]) 82 if (hold_button)
83 {
84 }
85 else if (old_wheel_value == wheel_tbl[0][wheel_value])
86 {
82 btn = BUTTON_SCROLL_FWD; 87 btn = BUTTON_SCROLL_FWD;
88 }
83 else if (old_wheel_value == wheel_tbl[1][wheel_value]) 89 else if (old_wheel_value == wheel_tbl[1][wheel_value])
90 {
84 btn = BUTTON_SCROLL_BACK; 91 btn = BUTTON_SCROLL_BACK;
92 }
85 93
86 if (btn == BUTTON_NONE) 94 if (btn == BUTTON_NONE)
87 { 95 {
@@ -200,11 +208,13 @@ void button_gpioa_isr(void)
200{ 208{
201#if defined(HAVE_SCROLLWHEEL) 209#if defined(HAVE_SCROLLWHEEL)
202 /* scroll wheel handling */ 210 /* scroll wheel handling */
203 if (GPIOA_MIS & SCROLLWHEEL_BITS) 211 unsigned long bits = GPIOA_MIS & SCROLLWHEEL_BITS;
204 scrollwheel(GPIOA_PIN_MASK(0xc0) >> 6);
205 212
206 /* ack interrupt */ 213 if (bits)
207 GPIOA_IC = SCROLLWHEEL_BITS; 214 {
215 scrollwheel(GPIOA_PIN_MASK(SCROLLWHEEL_BITS) >> SCROLLWHEEL_BITS_POS);
216 GPIOA_IC = bits; /* ack interrupt */
217 }
208#endif 218#endif
209} 219}
210 220
@@ -225,8 +235,10 @@ int button_read_device(void)
225 int delay = 30; 235 int delay = 30;
226 while(delay--) nop; 236 while(delay--) nop;
227 237
238 disable_irq();
239
228 bool ccu_io_bit12 = CCU_IO & (1<<12); 240 bool ccu_io_bit12 = CCU_IO & (1<<12);
229 bitclr32(&CCU_IO, 1<<12); 241 CCU_IO &= ~(1<<12);
230 242
231 /* B1 is shared with FM i2c */ 243 /* B1 is shared with FM i2c */
232 bool gpiob_pin0_dir = GPIOB_DIR & (1<<1); 244 bool gpiob_pin0_dir = GPIOB_DIR & (1<<1);
@@ -256,7 +268,9 @@ int button_read_device(void)
256 GPIOB_DIR |= 1<<1; 268 GPIOB_DIR |= 1<<1;
257 269
258 if(ccu_io_bit12) 270 if(ccu_io_bit12)
259 bitset32(&CCU_IO, 1<<12); 271 CCU_IO |= (1<<12);
272
273 enable_irq();
260 274
261#ifdef HAS_BUTTON_HOLD 275#ifdef HAS_BUTTON_HOLD
262#ifndef BOOTLOADER 276#ifndef BOOTLOADER
@@ -265,12 +279,6 @@ int button_read_device(void)
265 { 279 {
266 hold_button = hold; 280 hold_button = hold;
267 backlight_hold_changed(hold); 281 backlight_hold_changed(hold);
268 /* mask scrollwheel irq so we don't need to check for
269 * the hold button in the isr */
270 if (hold)
271 GPIOA_IE &= ~SCROLLWHEEL_BITS;
272 else
273 GPIOA_IE |= SCROLLWHEEL_BITS;
274 } 282 }
275#else 283#else
276 hold_button = hold; 284 hold_button = hold;