mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-08 12:45:26 -05:00
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
This commit is contained in:
parent
f2f34881ec
commit
845af676f8
5 changed files with 68 additions and 25 deletions
|
|
@ -24,13 +24,6 @@
|
||||||
#include "panic.h"
|
#include "panic.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
|
||||||
#ifdef HAVE_SCROLLWHEEL
|
|
||||||
/* let the timer interrupt twice as often for the scrollwheel polling */
|
|
||||||
#define KERNEL_TIMER_FREQ (TIMER_FREQ/2)
|
|
||||||
#else
|
|
||||||
#define KERNEL_TIMER_FREQ TIMER_FREQ
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SCROLLWHEEL
|
#ifdef HAVE_SCROLLWHEEL
|
||||||
#include "button-target.h"
|
#include "button-target.h"
|
||||||
/* The scrollwheel is polled every 5 ms (the tick tasks only every 10) */
|
/* The scrollwheel is polled every 5 ms (the tick tasks only every 10) */
|
||||||
|
|
|
||||||
|
|
@ -58,29 +58,26 @@ void get_scrollwheel(void)
|
||||||
int button_read_device(void)
|
int button_read_device(void)
|
||||||
{
|
{
|
||||||
int btn = 0;
|
int btn = 0;
|
||||||
volatile int delay;
|
|
||||||
static bool hold_button_old = false;
|
static bool hold_button_old = false;
|
||||||
static long power_counter = 0;
|
static long power_counter = 0;
|
||||||
unsigned gpiod6;
|
unsigned gpiod6;
|
||||||
|
|
||||||
/* if we remove this delay, we see screen corruption (the higher the CPU
|
|
||||||
* frequency the higher the corruption) */
|
/* if we don't wait for the fifo to empty, we'll see screen corruption
|
||||||
for(delay = 1000; delay; delay--)
|
* (the higher the CPU frequency the higher the corruption) */
|
||||||
nop;
|
while ((DBOP_STAT & (1<<10)) == 0);
|
||||||
|
|
||||||
get_scrollwheel();
|
get_scrollwheel();
|
||||||
|
|
||||||
CCU_IO &= ~(1<<12);
|
CCU_IO &= ~(1<<12);
|
||||||
|
|
||||||
GPIOB_PIN(0) = 1<<0;
|
GPIOB_PIN(0) = 1<<0;
|
||||||
for(delay = 500; delay; delay--)
|
udelay(1);
|
||||||
nop;
|
|
||||||
|
|
||||||
gpiod6 = GPIOD_PIN(6);
|
gpiod6 = GPIOD_PIN(6);
|
||||||
|
|
||||||
GPIOB_PIN(0) = 0;
|
GPIOB_PIN(0) = 0;
|
||||||
for(delay = 240; delay; delay--)
|
udelay(1);
|
||||||
nop;
|
|
||||||
|
|
||||||
if (GPIOC_PIN(1) & 1<<1)
|
if (GPIOC_PIN(1) & 1<<1)
|
||||||
btn |= BUTTON_DOWN;
|
btn |= BUTTON_DOWN;
|
||||||
|
|
|
||||||
|
|
@ -141,13 +141,8 @@ static volatile unsigned int transfer_error[NUM_VOLUMES];
|
||||||
static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS* SD_BLOCK_SIZE] __attribute__((aligned(32))); /* align on cache line size */
|
static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS* SD_BLOCK_SIZE] __attribute__((aligned(32))); /* align on cache line size */
|
||||||
static unsigned char *uncached_buffer = UNCACHED_ADDR(&aligned_buffer[0]);
|
static unsigned char *uncached_buffer = UNCACHED_ADDR(&aligned_buffer[0]);
|
||||||
|
|
||||||
static inline void mci_delay(void)
|
|
||||||
{
|
static inline void mci_delay(void) { udelay(1000) ; }
|
||||||
int i = 0xffff;
|
|
||||||
do {
|
|
||||||
asm volatile("nop\n");
|
|
||||||
} while (--i);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline bool card_detect_target(void)
|
static inline bool card_detect_target(void)
|
||||||
|
|
@ -159,6 +154,7 @@ static inline bool card_detect_target(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_HOTSWAP
|
#ifdef HAVE_HOTSWAP
|
||||||
static int sd1_oneshot_callback(struct timeout *tmo)
|
static int sd1_oneshot_callback(struct timeout *tmo)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -344,7 +344,7 @@ static volatile bool retry;
|
||||||
int active_card = 0;
|
int active_card = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline void mci_delay(void) { int i = 0xffff; while(i--) ; }
|
static inline void mci_delay(void) { udelay(1000); }
|
||||||
|
|
||||||
void INT_NAND(void)
|
void INT_NAND(void)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -23,19 +23,76 @@
|
||||||
|
|
||||||
#include "system-arm.h"
|
#include "system-arm.h"
|
||||||
#include "mmu-arm.h"
|
#include "mmu-arm.h"
|
||||||
|
#include "panic.h"
|
||||||
|
|
||||||
#include "clock-target.h" /* CPUFREQ_* are defined here */
|
#include "clock-target.h" /* CPUFREQ_* are defined here */
|
||||||
|
|
||||||
|
#ifdef HAVE_SCROLLWHEEL
|
||||||
|
/* let the timer interrupt twice as often for the scrollwheel polling */
|
||||||
|
#define KERNEL_TIMER_FREQ (TIMER_FREQ/2)
|
||||||
|
#else
|
||||||
|
#define KERNEL_TIMER_FREQ TIMER_FREQ
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef BOOTLOADER
|
#ifdef BOOTLOADER
|
||||||
#define UNCACHED_ADDR(a) (a)
|
#define UNCACHED_ADDR(a) (a)
|
||||||
#else
|
#else
|
||||||
#define UNCACHED_ADDR(a) ((typeof(a)) ((uintptr_t)(a) + 0x10000000))
|
#define UNCACHED_ADDR(a) ((typeof(a)) ((uintptr_t)(a) + 0x10000000))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef SANSA_C200V2
|
#ifdef SANSA_C200V2
|
||||||
/* 0: Backlight on A5, 1: Backlight on A7 */
|
/* 0: Backlight on A5, 1: Backlight on A7 */
|
||||||
extern int c200v2_variant;
|
extern int c200v2_variant;
|
||||||
|
/* c200v2 changes the timer interval often due to software pwm */
|
||||||
|
#define TIMER_PERIOD TIMER2_BGLOAD
|
||||||
|
#else
|
||||||
|
#define TIMER_PERIOD (KERNEL_TIMER_FREQ/HZ)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function is not overly accurate, so rather call it with an usec more
|
||||||
|
* than less (see below comment)
|
||||||
|
*
|
||||||
|
* if inlined it expands to a really small and fast function if it's called
|
||||||
|
* with compile time constants */
|
||||||
|
static inline void udelay(unsigned usecs) __attribute__((always_inline));
|
||||||
|
static inline void udelay(unsigned usecs)
|
||||||
|
{
|
||||||
|
int now, end;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* we're limited to 1.5us multiplies due to the odd timer frequency (1.5MHz),
|
||||||
|
* to avoid calculating which is safer (need to round up for small values)
|
||||||
|
* and saves spending time in the divider we have a lut for
|
||||||
|
* small us values, it should be roughly us*2/3
|
||||||
|
**/
|
||||||
|
static const unsigned char udelay_lut[] =
|
||||||
|
{
|
||||||
|
0, 1, 2, 2, 3, 4, 4, 5, 6, 6,
|
||||||
|
7, 8, 8, 9, 10, 10, 11, 12, 12, 13,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
now = TIMER2_VALUE;
|
||||||
|
/* we don't want to handle multiple overflows, so limit the numbers
|
||||||
|
* (if you want to wait more than a tick just poll current_tick, or
|
||||||
|
* call sleep()) */
|
||||||
|
if (UNLIKELY(usecs >= TIMER_PERIOD))
|
||||||
|
panicf("%s(): %d too high!", __func__, usecs);
|
||||||
|
if (UNLIKELY(usecs <= 0))
|
||||||
|
return;
|
||||||
|
if (usecs < ARRAYLEN(udelay_lut))
|
||||||
|
{ /* the timer decrements */
|
||||||
|
end = now - udelay_lut[usecs];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* to usecs */
|
||||||
|
int delay = usecs * 2 / 3; /* us * 1.5 = us*timer_period */
|
||||||
|
end = now - delay;
|
||||||
|
}
|
||||||
|
/* underrun ? */
|
||||||
|
if (end < 0)
|
||||||
|
end += TIMER_PERIOD;
|
||||||
|
while(TIMER2_VALUE != (unsigned)end);
|
||||||
|
}
|
||||||
#endif /* SYSTEM_TARGET_H */
|
#endif /* SYSTEM_TARGET_H */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue