summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2010-04-27 09:34:29 +0000
committerThomas Martitz <kugel@rockbox.org>2010-04-27 09:34:29 +0000
commit845af676f8a37910613e7ce6b59dc229bb1a89c1 (patch)
tree0cc577ce1f31aea64a70b83f9323512da56912d4
parentf2f34881ec84fb18020ae9a492f347e87c36359c (diff)
downloadrockbox-845af676f8a37910613e7ce6b59dc229bb1a89c1.tar.gz
rockbox-845af676f8a37910613e7ce6b59dc229bb1a89c1.zip
as3525(v2): Add a somewhat inaccurate udelay (-0.5/+1.0µs). It should work good for some huge delays.
Use it in fuzev2 to improve some big delays (correct the biggest one to actually wait for the fifo to empty), and use it in the sd drivers. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25734 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/arm/as3525/kernel-as3525.c7
-rw-r--r--firmware/target/arm/as3525/sansa-fuzev2/button-fuzev2.c15
-rw-r--r--firmware/target/arm/as3525/sd-as3525.c10
-rw-r--r--firmware/target/arm/as3525/sd-as3525v2.c2
-rw-r--r--firmware/target/arm/as3525/system-target.h59
5 files changed, 68 insertions, 25 deletions
diff --git a/firmware/target/arm/as3525/kernel-as3525.c b/firmware/target/arm/as3525/kernel-as3525.c
index ebaef71c99..4ae1a03809 100644
--- a/firmware/target/arm/as3525/kernel-as3525.c
+++ b/firmware/target/arm/as3525/kernel-as3525.c
@@ -25,13 +25,6 @@
25#include "timer.h" 25#include "timer.h"
26 26
27#ifdef HAVE_SCROLLWHEEL 27#ifdef HAVE_SCROLLWHEEL
28/* let the timer interrupt twice as often for the scrollwheel polling */
29#define KERNEL_TIMER_FREQ (TIMER_FREQ/2)
30#else
31#define KERNEL_TIMER_FREQ TIMER_FREQ
32#endif
33
34#ifdef HAVE_SCROLLWHEEL
35#include "button-target.h" 28#include "button-target.h"
36/* The scrollwheel is polled every 5 ms (the tick tasks only every 10) */ 29/* The scrollwheel is polled every 5 ms (the tick tasks only every 10) */
37static int poll_scrollwheel = 0; 30static int poll_scrollwheel = 0;
diff --git a/firmware/target/arm/as3525/sansa-fuzev2/button-fuzev2.c b/firmware/target/arm/as3525/sansa-fuzev2/button-fuzev2.c
index d50df9f1c6..db08414ae5 100644
--- a/firmware/target/arm/as3525/sansa-fuzev2/button-fuzev2.c
+++ b/firmware/target/arm/as3525/sansa-fuzev2/button-fuzev2.c
@@ -58,29 +58,26 @@ void get_scrollwheel(void)
58int button_read_device(void) 58int button_read_device(void)
59{ 59{
60 int btn = 0; 60 int btn = 0;
61 volatile int delay;
62 static bool hold_button_old = false; 61 static bool hold_button_old = false;
63 static long power_counter = 0; 62 static long power_counter = 0;
64 unsigned gpiod6; 63 unsigned gpiod6;
65 64
66 /* if we remove this delay, we see screen corruption (the higher the CPU 65
67 * frequency the higher the corruption) */ 66 /* if we don't wait for the fifo to empty, we'll see screen corruption
68 for(delay = 1000; delay; delay--) 67 * (the higher the CPU frequency the higher the corruption) */
69 nop; 68 while ((DBOP_STAT & (1<<10)) == 0);
70 69
71 get_scrollwheel(); 70 get_scrollwheel();
72 71
73 CCU_IO &= ~(1<<12); 72 CCU_IO &= ~(1<<12);
74 73
75 GPIOB_PIN(0) = 1<<0; 74 GPIOB_PIN(0) = 1<<0;
76 for(delay = 500; delay; delay--) 75 udelay(1);
77 nop;
78 76
79 gpiod6 = GPIOD_PIN(6); 77 gpiod6 = GPIOD_PIN(6);
80 78
81 GPIOB_PIN(0) = 0; 79 GPIOB_PIN(0) = 0;
82 for(delay = 240; delay; delay--) 80 udelay(1);
83 nop;
84 81
85 if (GPIOC_PIN(1) & 1<<1) 82 if (GPIOC_PIN(1) & 1<<1)
86 btn |= BUTTON_DOWN; 83 btn |= BUTTON_DOWN;
diff --git a/firmware/target/arm/as3525/sd-as3525.c b/firmware/target/arm/as3525/sd-as3525.c
index 5ccb659e00..1cf7e51cf8 100644
--- a/firmware/target/arm/as3525/sd-as3525.c
+++ b/firmware/target/arm/as3525/sd-as3525.c
@@ -141,13 +141,8 @@ static volatile unsigned int transfer_error[NUM_VOLUMES];
141static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS* SD_BLOCK_SIZE] __attribute__((aligned(32))); /* align on cache line size */ 141static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS* SD_BLOCK_SIZE] __attribute__((aligned(32))); /* align on cache line size */
142static unsigned char *uncached_buffer = UNCACHED_ADDR(&aligned_buffer[0]); 142static unsigned char *uncached_buffer = UNCACHED_ADDR(&aligned_buffer[0]);
143 143
144static inline void mci_delay(void) 144
145{ 145static inline void mci_delay(void) { udelay(1000) ; }
146 int i = 0xffff;
147 do {
148 asm volatile("nop\n");
149 } while (--i);
150}
151 146
152 147
153static inline bool card_detect_target(void) 148static inline bool card_detect_target(void)
@@ -159,6 +154,7 @@ static inline bool card_detect_target(void)
159#endif 154#endif
160} 155}
161 156
157
162#ifdef HAVE_HOTSWAP 158#ifdef HAVE_HOTSWAP
163static int sd1_oneshot_callback(struct timeout *tmo) 159static int sd1_oneshot_callback(struct timeout *tmo)
164{ 160{
diff --git a/firmware/target/arm/as3525/sd-as3525v2.c b/firmware/target/arm/as3525/sd-as3525v2.c
index baf69760ab..2f263f7378 100644
--- a/firmware/target/arm/as3525/sd-as3525v2.c
+++ b/firmware/target/arm/as3525/sd-as3525v2.c
@@ -344,7 +344,7 @@ static volatile bool retry;
344int active_card = 0; 344int active_card = 0;
345#endif 345#endif
346 346
347static inline void mci_delay(void) { int i = 0xffff; while(i--) ; } 347static inline void mci_delay(void) { udelay(1000); }
348 348
349void INT_NAND(void) 349void INT_NAND(void)
350{ 350{
diff --git a/firmware/target/arm/as3525/system-target.h b/firmware/target/arm/as3525/system-target.h
index 1173515ebb..1ccd3282db 100644
--- a/firmware/target/arm/as3525/system-target.h
+++ b/firmware/target/arm/as3525/system-target.h
@@ -23,19 +23,76 @@
23 23
24#include "system-arm.h" 24#include "system-arm.h"
25#include "mmu-arm.h" 25#include "mmu-arm.h"
26#include "panic.h"
26 27
27#include "clock-target.h" /* CPUFREQ_* are defined here */ 28#include "clock-target.h" /* CPUFREQ_* are defined here */
28 29
30#ifdef HAVE_SCROLLWHEEL
31/* let the timer interrupt twice as often for the scrollwheel polling */
32#define KERNEL_TIMER_FREQ (TIMER_FREQ/2)
33#else
34#define KERNEL_TIMER_FREQ TIMER_FREQ
35#endif
36
29#ifdef BOOTLOADER 37#ifdef BOOTLOADER
30#define UNCACHED_ADDR(a) (a) 38#define UNCACHED_ADDR(a) (a)
31#else 39#else
32#define UNCACHED_ADDR(a) ((typeof(a)) ((uintptr_t)(a) + 0x10000000)) 40#define UNCACHED_ADDR(a) ((typeof(a)) ((uintptr_t)(a) + 0x10000000))
33#endif 41#endif
34 42
35
36#ifdef SANSA_C200V2 43#ifdef SANSA_C200V2
37/* 0: Backlight on A5, 1: Backlight on A7 */ 44/* 0: Backlight on A5, 1: Backlight on A7 */
38extern int c200v2_variant; 45extern int c200v2_variant;
46/* c200v2 changes the timer interval often due to software pwm */
47#define TIMER_PERIOD TIMER2_BGLOAD
48#else
49#define TIMER_PERIOD (KERNEL_TIMER_FREQ/HZ)
39#endif 50#endif
40 51
52/*
53 * This function is not overly accurate, so rather call it with an usec more
54 * than less (see below comment)
55 *
56 * if inlined it expands to a really small and fast function if it's called
57 * with compile time constants */
58static inline void udelay(unsigned usecs) __attribute__((always_inline));
59static inline void udelay(unsigned usecs)
60{
61 int now, end;
62
63 /**
64 * we're limited to 1.5us multiplies due to the odd timer frequency (1.5MHz),
65 * to avoid calculating which is safer (need to round up for small values)
66 * and saves spending time in the divider we have a lut for
67 * small us values, it should be roughly us*2/3
68 **/
69 static const unsigned char udelay_lut[] =
70 {
71 0, 1, 2, 2, 3, 4, 4, 5, 6, 6,
72 7, 8, 8, 9, 10, 10, 11, 12, 12, 13,
73 };
74
75
76 now = TIMER2_VALUE;
77 /* we don't want to handle multiple overflows, so limit the numbers
78 * (if you want to wait more than a tick just poll current_tick, or
79 * call sleep()) */
80 if (UNLIKELY(usecs >= TIMER_PERIOD))
81 panicf("%s(): %d too high!", __func__, usecs);
82 if (UNLIKELY(usecs <= 0))
83 return;
84 if (usecs < ARRAYLEN(udelay_lut))
85 { /* the timer decrements */
86 end = now - udelay_lut[usecs];
87 }
88 else
89 { /* to usecs */
90 int delay = usecs * 2 / 3; /* us * 1.5 = us*timer_period */
91 end = now - delay;
92 }
93 /* underrun ? */
94 if (end < 0)
95 end += TIMER_PERIOD;
96 while(TIMER2_VALUE != (unsigned)end);
97}
41#endif /* SYSTEM_TARGET_H */ 98#endif /* SYSTEM_TARGET_H */