forked from len0rd/rockbox
Coldfire: New timer handling on CPU frequency change, adjusting the prescaler on the fly, for both tick and user timer. Precondition is that the higher frequencies are integer multiples of the base: now NORMAL is 45 MHz and MAX is 124 MHz. Removes the need for applications with longer timer periods (>= 10 ms) to boost the CPU all the time, e.g. the grayscale lib. Timer counts are now always based on the base frequency (CPU_FREQ). * Adjusted the RAM refresh timers to the new frequencies (all frequencies for H100) * All: Fixed the tick timer count being off by one.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7576 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
7190cf2ed9
commit
cfb073c452
10 changed files with 98 additions and 59 deletions
|
@ -271,7 +271,8 @@ bool dbg_audio_thread(void)
|
||||||
snprintf(buf, sizeof(buf), "track count: %d", track_count);
|
snprintf(buf, sizeof(buf), "track count: %d", track_count);
|
||||||
lcd_puts(0, line++, buf);
|
lcd_puts(0, line++, buf);
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "cpu freq: %dMHz", (int)FREQ/1000000+1);
|
snprintf(buf, sizeof(buf), "cpu freq: %dMHz",
|
||||||
|
(int)((FREQ + 500000) / 1000000));
|
||||||
lcd_puts(0, line++, buf);
|
lcd_puts(0, line++, buf);
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "boost ratio: %d%%",
|
snprintf(buf, sizeof(buf), "boost ratio: %d%%",
|
||||||
|
@ -682,7 +683,7 @@ bool dbg_spdif(void)
|
||||||
valnogood = (interruptstat & 0x01000000)?true:false;
|
valnogood = (interruptstat & 0x01000000)?true:false;
|
||||||
symbolerr = (interruptstat & 0x00800000)?true:false;
|
symbolerr = (interruptstat & 0x00800000)?true:false;
|
||||||
parityerr = (interruptstat & 0x00400000)?true:false;
|
parityerr = (interruptstat & 0x00400000)?true:false;
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "Val: %s Sym: %s Par: %s",
|
snprintf(buf, sizeof(buf), "Val: %s Sym: %s Par: %s",
|
||||||
valnogood?"--":"OK",
|
valnogood?"--":"OK",
|
||||||
symbolerr?"--":"OK",
|
symbolerr?"--":"OK",
|
||||||
|
|
|
@ -164,6 +164,9 @@ int main(void)
|
||||||
rb->lcd_puts(0, 0, pbuf);
|
rb->lcd_puts(0, 0, pbuf);
|
||||||
rb->lcd_update();
|
rb->lcd_update();
|
||||||
|
|
||||||
|
#if !defined(SIMULATOR) && defined(HAVE_ADJUSTABLE_CPU_FREQ)
|
||||||
|
rb->cpu_boost(true);
|
||||||
|
#endif
|
||||||
gray_show(true); /* switch on greyscale overlay */
|
gray_show(true); /* switch on greyscale overlay */
|
||||||
|
|
||||||
time = *rb->current_tick; /* start time measurement */
|
time = *rb->current_tick; /* start time measurement */
|
||||||
|
@ -223,6 +226,9 @@ int main(void)
|
||||||
time / 100, time % 100);
|
time / 100, time % 100);
|
||||||
rb->lcd_puts(0, 0, pbuf);
|
rb->lcd_puts(0, 0, pbuf);
|
||||||
gray_deferred_lcd_update(); /* schedule an lcd_update() */
|
gray_deferred_lcd_update(); /* schedule an lcd_update() */
|
||||||
|
#if !defined(SIMULATOR) && defined(HAVE_ADJUSTABLE_CPU_FREQ)
|
||||||
|
rb->cpu_boost(false);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* drawing is now finished, play around with scrolling
|
/* drawing is now finished, play around with scrolling
|
||||||
* until you press OFF or connect USB
|
* until you press OFF or connect USB
|
||||||
|
|
|
@ -226,38 +226,23 @@ void gray_release(void)
|
||||||
lcd_set_invert_display(), lcd_set_flip(), lcd_roll() */
|
lcd_set_invert_display(), lcd_set_flip(), lcd_roll() */
|
||||||
void gray_show(bool enable)
|
void gray_show(bool enable)
|
||||||
{
|
{
|
||||||
#if (CONFIG_CPU == SH7034) && (CONFIG_LCD == LCD_SSD1815)
|
|
||||||
if (enable)
|
|
||||||
{
|
|
||||||
_gray_info.flags |= _GRAY_RUNNING;
|
|
||||||
_gray_rb->timer_register(1, NULL, FREQ / 67, 1, _timer_isr);
|
|
||||||
_gray_rb->screen_dump_set_hook(gray_screendump_hook);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_gray_rb->timer_unregister();
|
|
||||||
_gray_info.flags &= ~_GRAY_RUNNING;
|
|
||||||
_gray_rb->screen_dump_set_hook(NULL);
|
|
||||||
_gray_rb->lcd_update(); /* restore whatever there was before */
|
|
||||||
}
|
|
||||||
#elif defined(CPU_COLDFIRE) && (CONFIG_LCD == LCD_S1D15E06)
|
|
||||||
if (enable && !(_gray_info.flags & _GRAY_RUNNING))
|
if (enable && !(_gray_info.flags & _GRAY_RUNNING))
|
||||||
{
|
{
|
||||||
_gray_info.flags |= _GRAY_RUNNING;
|
_gray_info.flags |= _GRAY_RUNNING;
|
||||||
_gray_rb->cpu_boost(true); /* run at 120 MHz to avoid freq changes */
|
#if CONFIG_LCD == LCD_SSD1815
|
||||||
_gray_rb->timer_register(1, NULL, *_gray_rb->cpu_frequency / 70, 1,
|
_gray_rb->timer_register(1, NULL, CPU_FREQ / 67, 1, _timer_isr);
|
||||||
_timer_isr);
|
#elif CONFIG_LCD == LCD_S1D15E06
|
||||||
|
_gray_rb->timer_register(1, NULL, CPU_FREQ / 70, 1, _timer_isr);
|
||||||
|
#endif
|
||||||
_gray_rb->screen_dump_set_hook(gray_screendump_hook);
|
_gray_rb->screen_dump_set_hook(gray_screendump_hook);
|
||||||
}
|
}
|
||||||
else if (!enable && (_gray_info.flags & _GRAY_RUNNING))
|
else if (!enable && (_gray_info.flags & _GRAY_RUNNING))
|
||||||
{
|
{
|
||||||
_gray_rb->timer_unregister();
|
_gray_rb->timer_unregister();
|
||||||
_gray_rb->cpu_boost(false);
|
|
||||||
_gray_info.flags &= ~_GRAY_RUNNING;
|
_gray_info.flags &= ~_GRAY_RUNNING;
|
||||||
_gray_rb->screen_dump_set_hook(NULL);
|
_gray_rb->screen_dump_set_hook(NULL);
|
||||||
_gray_rb->lcd_update(); /* restore whatever there was before */
|
_gray_rb->lcd_update(); /* restore whatever there was before */
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update a rectangular area of the greyscale overlay */
|
/* Update a rectangular area of the greyscale overlay */
|
||||||
|
|
|
@ -370,6 +370,9 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
|
||||||
/* main loop */
|
/* main loop */
|
||||||
while (true) {
|
while (true) {
|
||||||
if (redraw > REDRAW_NONE) {
|
if (redraw > REDRAW_NONE) {
|
||||||
|
#if !defined(SIMULATOR) && defined(HAVE_ADJUSTABLE_CPU_FREQ)
|
||||||
|
rb->cpu_boost(true);
|
||||||
|
#endif
|
||||||
if (redraw == REDRAW_FULL)
|
if (redraw == REDRAW_FULL)
|
||||||
gray_ub_clear_display();
|
gray_ub_clear_display();
|
||||||
|
|
||||||
|
@ -378,6 +381,9 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
|
||||||
else
|
else
|
||||||
calc_mandelbrot_32();
|
calc_mandelbrot_32();
|
||||||
|
|
||||||
|
#if !defined(SIMULATOR) && defined(HAVE_ADJUSTABLE_CPU_FREQ)
|
||||||
|
rb->cpu_boost(false);
|
||||||
|
#endif
|
||||||
px_min = 0;
|
px_min = 0;
|
||||||
px_max = LCD_WIDTH;
|
px_max = LCD_WIDTH;
|
||||||
py_min = 0;
|
py_min = 0;
|
||||||
|
|
|
@ -81,7 +81,7 @@ static void backlight_isr(void)
|
||||||
int timer_period;
|
int timer_period;
|
||||||
bool idle = false;
|
bool idle = false;
|
||||||
|
|
||||||
timer_period = FREQ / 1000 * BL_PWM_INTERVAL / 1000;
|
timer_period = CPU_FREQ / 1000 * BL_PWM_INTERVAL / 1000;
|
||||||
switch (bl_dim_state)
|
switch (bl_dim_state)
|
||||||
{
|
{
|
||||||
/* New cycle */
|
/* New cycle */
|
||||||
|
|
|
@ -257,14 +257,17 @@ static inline unsigned long SWAB32(unsigned long value)
|
||||||
static inline void invalidate_icache(void)
|
static inline void invalidate_icache(void)
|
||||||
{
|
{
|
||||||
asm volatile ("move.l #0x01000000,%d0\n"
|
asm volatile ("move.l #0x01000000,%d0\n"
|
||||||
"movec.l %d0,%cacr\n"
|
"movec.l %d0,%cacr\n"
|
||||||
"move.l #0x80000000,%d0\n"
|
"move.l #0x80000000,%d0\n"
|
||||||
"movec.l %d0,%cacr");
|
"movec.l %d0,%cacr");
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CPUFREQ_DEFAULT CPU_FREQ
|
#define CPUFREQ_DEFAULT_MULT 1
|
||||||
#define CPUFREQ_NORMAL 47980800
|
#define CPUFREQ_DEFAULT (CPUFREQ_DEFAULT_MULT * CPU_FREQ)
|
||||||
#define CPUFREQ_MAX 119952000
|
#define CPUFREQ_NORMAL_MULT 4
|
||||||
|
#define CPUFREQ_NORMAL (CPUFREQ_NORMAL_MULT * CPU_FREQ)
|
||||||
|
#define CPUFREQ_MAX_MULT 11
|
||||||
|
#define CPUFREQ_MAX (CPUFREQ_MAX_MULT * CPU_FREQ)
|
||||||
|
|
||||||
#elif CONFIG_CPU == TCC730
|
#elif CONFIG_CPU == TCC730
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,9 @@
|
||||||
bool timer_register(int reg_prio, void (*unregister_callback)(void),
|
bool timer_register(int reg_prio, void (*unregister_callback)(void),
|
||||||
long cycles, int int_prio, void (*timer_callback)(void));
|
long cycles, int int_prio, void (*timer_callback)(void));
|
||||||
bool timer_set_period(long cycles);
|
bool timer_set_period(long cycles);
|
||||||
|
#ifdef CPU_COLDFIRE
|
||||||
|
void timers_adjust_prescale(int multiplier, bool enable_irq);
|
||||||
|
#endif
|
||||||
void timer_unregister(void);
|
void timer_unregister(void);
|
||||||
|
|
||||||
#endif /* !SIMULATOR */
|
#endif /* !SIMULATOR */
|
||||||
|
|
|
@ -156,11 +156,11 @@ int queue_broadcast(long id, void *data)
|
||||||
#if CONFIG_CPU == SH7034
|
#if CONFIG_CPU == SH7034
|
||||||
void tick_start(unsigned int interval_in_ms)
|
void tick_start(unsigned int interval_in_ms)
|
||||||
{
|
{
|
||||||
unsigned int count;
|
unsigned long count;
|
||||||
|
|
||||||
count = FREQ * interval_in_ms / 1000 / 8;
|
count = CPU_FREQ * interval_in_ms / 1000 / 8;
|
||||||
|
|
||||||
if(count > 0xffff)
|
if(count > 0x10000)
|
||||||
{
|
{
|
||||||
panicf("Error! The tick interval is too long (%d ms)\n",
|
panicf("Error! The tick interval is too long (%d ms)\n",
|
||||||
interval_in_ms);
|
interval_in_ms);
|
||||||
|
@ -174,7 +174,7 @@ void tick_start(unsigned int interval_in_ms)
|
||||||
TMDR &= ~0x01; /* Operate normally */
|
TMDR &= ~0x01; /* Operate normally */
|
||||||
|
|
||||||
TCNT0 = 0; /* Start counting at 0 */
|
TCNT0 = 0; /* Start counting at 0 */
|
||||||
GRA0 = count;
|
GRA0 = (unsigned short)(count - 1);
|
||||||
TCR0 = 0x23; /* Clear at GRA match, sysclock/8 */
|
TCR0 = 0x23; /* Clear at GRA match, sysclock/8 */
|
||||||
|
|
||||||
/* Enable interrupt on level 1 */
|
/* Enable interrupt on level 1 */
|
||||||
|
@ -186,7 +186,7 @@ void tick_start(unsigned int interval_in_ms)
|
||||||
TSTR |= 0x01; /* Start timer 1 */
|
TSTR |= 0x01; /* Start timer 1 */
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma interrupt
|
void IMIA0(void) __attribute__ ((interrupt_handler));
|
||||||
void IMIA0(void)
|
void IMIA0(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -208,22 +208,28 @@ void IMIA0(void)
|
||||||
#elif defined(CPU_COLDFIRE)
|
#elif defined(CPU_COLDFIRE)
|
||||||
void tick_start(unsigned int interval_in_ms)
|
void tick_start(unsigned int interval_in_ms)
|
||||||
{
|
{
|
||||||
unsigned int count;
|
unsigned long count;
|
||||||
|
int prescale;
|
||||||
|
|
||||||
count = FREQ/2 * interval_in_ms / 1000 / 16;
|
count = CPU_FREQ/2 * interval_in_ms / 1000 / 16;
|
||||||
|
|
||||||
if(count > 0xffff)
|
if(count > 0x10000)
|
||||||
{
|
{
|
||||||
panicf("Error! The tick interval is too long (%d ms)\n",
|
panicf("Error! The tick interval is too long (%d ms)\n",
|
||||||
interval_in_ms);
|
interval_in_ms);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prescale = cpu_frequency / CPU_FREQ;
|
||||||
|
/* Note: The prescaler is later adjusted on-the-fly on CPU frequency
|
||||||
|
changes within timer.c */
|
||||||
|
|
||||||
/* We are using timer 0 */
|
/* We are using timer 0 */
|
||||||
|
|
||||||
TRR0 = count; /* The reference count */
|
TRR0 = (unsigned short)(count - 1); /* The reference count */
|
||||||
TCN0 = 0; /* reset the timer */
|
TCN0 = 0; /* reset the timer */
|
||||||
TMR0 = 0x001d; /* no prescaler, restart, CLK/16, enabled */
|
TMR0 = 0x001d | ((unsigned short)(prescale - 1) << 8);
|
||||||
|
/* restart, CLK/16, enabled, prescaler */
|
||||||
|
|
||||||
TER0 = 0xff; /* Clear all events */
|
TER0 = 0xff; /* Clear all events */
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
|
#include "timer.h"
|
||||||
|
|
||||||
#ifndef SIMULATOR
|
#ifndef SIMULATOR
|
||||||
long cpu_frequency = CPU_FREQ;
|
long cpu_frequency = CPU_FREQ;
|
||||||
|
@ -503,11 +504,13 @@ void system_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef IRIVER_H100
|
#ifdef IRIVER_H100
|
||||||
#define MAX_REFRESH_TIMER 56
|
#define MAX_REFRESH_TIMER 59
|
||||||
#define NORMAL_REFRESH_TIMER 20
|
#define NORMAL_REFRESH_TIMER 21
|
||||||
|
#define DEFAULT_REFRESH_TIMER 4
|
||||||
#else
|
#else
|
||||||
#define MAX_REFRESH_TIMER 28
|
#define MAX_REFRESH_TIMER 29
|
||||||
#define NORMAL_REFRESH_TIMER 10
|
#define NORMAL_REFRESH_TIMER 10
|
||||||
|
#define DEFAULT_REFRESH_TIMER 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void set_cpu_frequency (long) __attribute__ ((section (".icode")));
|
void set_cpu_frequency (long) __attribute__ ((section (".icode")));
|
||||||
|
@ -516,44 +519,46 @@ void set_cpu_frequency(long frequency)
|
||||||
switch(frequency)
|
switch(frequency)
|
||||||
{
|
{
|
||||||
case CPUFREQ_MAX:
|
case CPUFREQ_MAX:
|
||||||
DCR = (DCR & ~0x01ff) | 1; /* Refresh timer for bypass
|
DCR = (DCR & ~0x01ff) | DEFAULT_REFRESH_TIMER;
|
||||||
frequency */
|
/* Refresh timer for bypass frequency */
|
||||||
PLLCR &= ~1; /* Bypass mode */
|
PLLCR &= ~1; /* Bypass mode */
|
||||||
PLLCR = 0x11853005;
|
timers_adjust_prescale(CPUFREQ_DEFAULT_MULT, false);
|
||||||
|
PLLCR = 0x11856005;
|
||||||
CSCR0 = 0x00000980; /* Flash: 2 wait state */
|
CSCR0 = 0x00000980; /* Flash: 2 wait state */
|
||||||
CSCR1 = 0x00000980; /* LCD: 2 wait states */
|
CSCR1 = 0x00000980; /* LCD: 2 wait states */
|
||||||
while(!(PLLCR & 0x80000000)) {}; /* Wait until the PLL has locked.
|
while(!(PLLCR & 0x80000000)) {}; /* Wait until the PLL has locked.
|
||||||
This may take up to 10ms! */
|
This may take up to 10ms! */
|
||||||
|
timers_adjust_prescale(CPUFREQ_MAX_MULT, true);
|
||||||
DCR = (DCR & ~0x01ff) | MAX_REFRESH_TIMER; /* Refresh timer */
|
DCR = (DCR & ~0x01ff) | MAX_REFRESH_TIMER; /* Refresh timer */
|
||||||
cpu_frequency = CPUFREQ_MAX;
|
cpu_frequency = CPUFREQ_MAX;
|
||||||
tick_start(1000/HZ);
|
|
||||||
IDECONFIG1 = 0x106000 | (5 << 10); /* BUFEN2 enable + CS2Pre/CS2Post */
|
IDECONFIG1 = 0x106000 | (5 << 10); /* BUFEN2 enable + CS2Pre/CS2Post */
|
||||||
IDECONFIG2 = 0x40000 | (1 << 8); /* TA enable + CS2wait */
|
IDECONFIG2 = 0x40000 | (1 << 8); /* TA enable + CS2wait */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CPUFREQ_NORMAL:
|
case CPUFREQ_NORMAL:
|
||||||
DCR = (DCR & ~0x01ff) | 1; /* Refresh timer for bypass
|
DCR = (DCR & ~0x01ff) | DEFAULT_REFRESH_TIMER;
|
||||||
frequency */
|
/* Refresh timer for bypass frequency */
|
||||||
PLLCR &= ~1; /* Bypass mode */
|
PLLCR &= ~1; /* Bypass mode */
|
||||||
PLLCR = 0x10886001;
|
timers_adjust_prescale(CPUFREQ_DEFAULT_MULT, false);
|
||||||
|
PLLCR = 0x1385e005;
|
||||||
CSCR0 = 0x00000180; /* Flash: 0 wait states */
|
CSCR0 = 0x00000180; /* Flash: 0 wait states */
|
||||||
CSCR1 = 0x00000180; /* LCD: 0 wait states */
|
CSCR1 = 0x00000180; /* LCD: 0 wait states */
|
||||||
while(!(PLLCR & 0x80000000)) {}; /* Wait until the PLL has locked.
|
while(!(PLLCR & 0x80000000)) {}; /* Wait until the PLL has locked.
|
||||||
This may take up to 10ms! */
|
This may take up to 10ms! */
|
||||||
|
timers_adjust_prescale(CPUFREQ_NORMAL_MULT, true);
|
||||||
DCR = (DCR & ~0x01ff) | NORMAL_REFRESH_TIMER; /* Refresh timer */
|
DCR = (DCR & ~0x01ff) | NORMAL_REFRESH_TIMER; /* Refresh timer */
|
||||||
cpu_frequency = CPUFREQ_NORMAL;
|
cpu_frequency = CPUFREQ_NORMAL;
|
||||||
tick_start(1000/HZ);
|
|
||||||
IDECONFIG1 = 0x106000 | (5 << 10); /* BUFEN2 enable + CS2Pre/CS2Post */
|
IDECONFIG1 = 0x106000 | (5 << 10); /* BUFEN2 enable + CS2Pre/CS2Post */
|
||||||
IDECONFIG2 = 0x40000 | (0 << 8); /* TA enable + CS2wait */
|
IDECONFIG2 = 0x40000 | (0 << 8); /* TA enable + CS2wait */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DCR = (DCR & ~0x01ff) | 1; /* Refresh timer for bypass
|
DCR = (DCR & ~0x01ff) | DEFAULT_REFRESH_TIMER;
|
||||||
frequency */
|
/* Refresh timer for bypass frequency */
|
||||||
PLLCR = 0x00000000; /* Bypass mode */
|
PLLCR = 0x00000000; /* Bypass mode */
|
||||||
|
timers_adjust_prescale(CPUFREQ_DEFAULT_MULT, true);
|
||||||
CSCR0 = 0x00000180; /* Flash: 0 wait states */
|
CSCR0 = 0x00000180; /* Flash: 0 wait states */
|
||||||
CSCR1 = 0x00000180; /* LCD: 0 wait states */
|
CSCR1 = 0x00000180; /* LCD: 0 wait states */
|
||||||
cpu_frequency = CPU_FREQ;
|
cpu_frequency = CPUFREQ_DEFAULT;
|
||||||
tick_start(1000/HZ);
|
|
||||||
IDECONFIG1 = 0x106000 | (1 << 10); /* BUFEN2 enable + CS2Pre/CS2Post */
|
IDECONFIG1 = 0x106000 | (1 << 10); /* BUFEN2 enable + CS2Pre/CS2Post */
|
||||||
IDECONFIG2 = 0x40000 | (0 << 8); /* TA enable + CS2wait */
|
IDECONFIG2 = 0x40000 | (0 << 8); /* TA enable + CS2wait */
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -28,7 +28,9 @@
|
||||||
static int timer_prio = -1;
|
static int timer_prio = -1;
|
||||||
static void (*pfn_timer)(void) = NULL; /* timer callback */
|
static void (*pfn_timer)(void) = NULL; /* timer callback */
|
||||||
static void (*pfn_unregister)(void) = NULL; /* unregister callback */
|
static void (*pfn_unregister)(void) = NULL; /* unregister callback */
|
||||||
|
#ifdef CPU_COLDFIRE
|
||||||
|
static int base_prescale;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* interrupt handler */
|
/* interrupt handler */
|
||||||
#if CONFIG_CPU == SH7034
|
#if CONFIG_CPU == SH7034
|
||||||
|
@ -93,16 +95,19 @@ static bool timer_set(long cycles, bool start)
|
||||||
and_b(~0x01, &TSR4); /* clear an eventual interrupt */
|
and_b(~0x01, &TSR4); /* clear an eventual interrupt */
|
||||||
|
|
||||||
#elif defined CPU_COLDFIRE
|
#elif defined CPU_COLDFIRE
|
||||||
if (prescale > 4096)
|
if (prescale > 4096/CPUFREQ_MAX_MULT)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (prescale > 256)
|
if (prescale > 256/CPUFREQ_MAX_MULT)
|
||||||
{
|
{
|
||||||
phi = 0x05; /* prescale sysclk/16, timer enabled */
|
phi = 0x05; /* prescale sysclk/16, timer enabled */
|
||||||
prescale >>= 4;
|
prescale >>= 4;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
phi = 0x03; /* prescale sysclk, timer enabled */
|
phi = 0x03; /* prescale sysclk, timer enabled */
|
||||||
|
|
||||||
|
base_prescale = prescale;
|
||||||
|
prescale *= (cpu_frequency / CPU_FREQ);
|
||||||
|
|
||||||
if (start)
|
if (start)
|
||||||
{
|
{
|
||||||
|
@ -125,7 +130,26 @@ static bool timer_set(long cycles, bool start)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register a user timer, called every <count> CPU cycles */
|
#ifdef CPU_COLDFIRE
|
||||||
|
void timers_adjust_prescale(int multiplier, bool enable_irq)
|
||||||
|
{
|
||||||
|
/* tick timer */
|
||||||
|
TMR0 = (TMR0 & 0x00ef)
|
||||||
|
| ((unsigned short)(multiplier - 1) << 8)
|
||||||
|
| (enable_irq ? 0x10 : 0);
|
||||||
|
|
||||||
|
if (pfn_timer)
|
||||||
|
{
|
||||||
|
/* user timer */
|
||||||
|
int prescale = base_prescale * multiplier;
|
||||||
|
TMR1 = (TMR1 & 0x00ef)
|
||||||
|
| ((unsigned short)(prescale - 1) << 8)
|
||||||
|
| (enable_irq ? 0x10 : 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Register a user timer, called every <cycles> CPU_FREQ cycles */
|
||||||
bool timer_register(int reg_prio, void (*unregister_callback)(void),
|
bool timer_register(int reg_prio, void (*unregister_callback)(void),
|
||||||
long cycles, int int_prio, void (*timer_callback)(void))
|
long cycles, int int_prio, void (*timer_callback)(void))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue