summaryrefslogtreecommitdiff
path: root/firmware/target/arm
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm')
-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 */