From b955dff268005d3d55ee3f38af0875718ab6021a Mon Sep 17 00:00:00 2001 From: Rafaël Carré Date: Mon, 29 Jun 2009 14:29:35 +0000 Subject: Move PP (last target) timer code in target tree Put warnings in timer.h for incomplete targets (TIMER_FREQ not defined and/or timer-target.h inexistant) Correct TIMER_STOP & TIMER_START macros arguments for target without timers TIMER_START takes an extra argument in multicore builds (macro in macro doesn't work fine..) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21557 a1c6a512-1295-4272-9138-f99709370657 --- firmware/SOURCES | 1 + firmware/export/timer.h | 10 ++--- firmware/target/arm/timer-pp.c | 87 ++++++++++++++++++++++++++++++++++++++ firmware/target/arm/timer-target.h | 52 +++++++++++++++++++++++ firmware/timer.c | 71 ++++--------------------------- 5 files changed, 154 insertions(+), 67 deletions(-) create mode 100644 firmware/target/arm/timer-pp.c create mode 100644 firmware/target/arm/timer-target.h (limited to 'firmware') diff --git a/firmware/SOURCES b/firmware/SOURCES index 239eb92a92..975e2b8688 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -394,6 +394,7 @@ target/arm/as3525/pcm-as3525.c #if defined(CPU_PP) target/arm/kernel-pp.c +target/arm/timer-pp.c #if CONFIG_CPU == PP5002 target/arm/system-pp5002.c #elif defined CPU_PP502x diff --git a/firmware/export/timer.h b/firmware/export/timer.h index f3faf0908e..678d9ad8c6 100644 --- a/firmware/export/timer.h +++ b/firmware/export/timer.h @@ -25,19 +25,19 @@ #include #include "config.h" -#if defined(CPU_PP) - /* Portalplayer chips use a microsecond timer. */ +#if defined(SIMULATOR) #define TIMER_FREQ 1000000 #elif CONFIG_CPU == S3C2440 || CONFIG_CPU == DM320 || CONFIG_CPU == TCC7801 \ || defined(CPU_TCC77X) || CONFIG_CPU == AS3525 || CONFIG_CPU == IMX31L \ || CONFIG_CPU == JZ4732 || CONFIG_CPU == PNX0101 \ - || defined(CPU_COLDFIRE) || CONFIG_CPU == SH7034 + || defined(CPU_COLDFIRE) || CONFIG_CPU == SH7034 || defined(CPU_PP) #include "timer-target.h" -#elif defined(SIMULATOR) - #define TIMER_FREQ 1000000 +#else + #warning "Target without timer-target.h" #endif #ifndef TIMER_FREQ + #warning "TIMER_FREQ not defined" #define TIMER_FREQ CPU_FREQ #endif bool timer_register(int reg_prio, void (*unregister_callback)(void), diff --git a/firmware/target/arm/timer-pp.c b/firmware/target/arm/timer-pp.c new file mode 100644 index 0000000000..01c691f79e --- /dev/null +++ b/firmware/target/arm/timer-pp.c @@ -0,0 +1,87 @@ +/*************************************************************************** +* __________ __ ___. +* Open \______ \ ____ ____ | | _\_ |__ _______ ___ +* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +* \/ \/ \/ \/ \/ +* $Id$ +* +* Copyright (C) 2006 Thom Johansen +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +* KIND, either express or implied. +* +****************************************************************************/ + +#include "cpu.h" +#include "system.h" +#include "timer.h" +#include "timer-target.h" + +static long SHAREDBSS_ATTR cycles_new = 0; + +void TIMER2(void) +{ + TIMER2_VAL; /* ACK interrupt */ + if (cycles_new > 0) + { + TIMER2_CFG = 0xc0000000 | (cycles_new - 1); + cycles_new = 0; + } + if (pfn_timer != NULL) + { + cycles_new = -1; + /* "lock" the variable, in case timer_set_period() + * is called within pfn_timer() */ + pfn_timer(); + cycles_new = 0; + } +} + +bool __timer_set(long cycles, bool start) +{ + if (cycles > 0x20000000 || cycles < 2) + return false; + + if (start) + { + if (pfn_unregister != NULL) + { + pfn_unregister(); + pfn_unregister = NULL; + } + CPU_INT_DIS = TIMER2_MASK; + COP_INT_DIS = TIMER2_MASK; + } + if (start || (cycles_new == -1)) /* within isr, cycles_new is "locked" */ + TIMER2_CFG = 0xc0000000 | (cycles - 1); /* enable timer */ + else + cycles_new = cycles; + + return true; +} + +bool __timer_start(IF_COP_VOID(int core)) +{ + /* unmask interrupt source */ +#if NUM_CORES > 1 + if (core == COP) + COP_INT_EN = TIMER2_MASK; + else +#endif + CPU_INT_EN = TIMER2_MASK; + return true; +} + +void __timer_stop(void) +{ + TIMER2_CFG = 0; /* stop timer 2 */ + CPU_INT_DIS = TIMER2_MASK; + COP_INT_DIS = TIMER2_MASK; +} diff --git a/firmware/target/arm/timer-target.h b/firmware/target/arm/timer-target.h new file mode 100644 index 0000000000..6801cfe783 --- /dev/null +++ b/firmware/target/arm/timer-target.h @@ -0,0 +1,52 @@ +/*************************************************************************** +* __________ __ ___. +* Open \______ \ ____ ____ | | _\_ |__ _______ ___ +* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +* \/ \/ \/ \/ \/ +* $Id$ +* +* Copyright (C) 2006 Thom Johansen +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +* KIND, either express or implied. +* +****************************************************************************/ +#ifndef TIMER_TARGET_H +#define TIMER_TARGET_H + +#include "config.h" + +/* FIXME : this header is PP specific */ +#ifndef CPU_PP +#error "PP specific header" +#endif + +bool __timer_set(long cycles, bool start); +bool __timer_start(IF_COP_VOID(int core)); +void __timer_stop(void); + +/* Portalplayer chips use a microsecond timer. */ +#define TIMER_FREQ 1000000 + +#define __TIMER_SET(cycles, set) \ + __timer_set(cycles, set) + +#if NUM_CORES > 1 +#define __TIMER_START(int_prio, core) \ + __timer_start(core) +#else +#define __TIMER_START(int_prio) \ + __timer_start() +#endif + +#define __TIMER_STOP(...) \ + __timer_stop() + +#endif /* TIMER_TARGET_H */ diff --git a/firmware/timer.c b/firmware/timer.c index 044b871b3f..8cd165bd35 100644 --- a/firmware/timer.c +++ b/firmware/timer.c @@ -29,64 +29,22 @@ static int timer_prio = -1; void SHAREDBSS_ATTR (*pfn_timer)(void) = NULL; /* timer callback */ void SHAREDBSS_ATTR (*pfn_unregister)(void) = NULL; /* unregister callback */ -#if defined CPU_PP -static long SHAREDBSS_ATTR cycles_new = 0; -#endif #ifndef __TIMER_SET /* Define these if not defined by target to make the #else cases compile * even if the target doesn't have them implemented. */ #define __TIMER_SET(cycles, set) false -#define __TIMER_START() false -#define __TIMER_STOP(...) +#if NUM_CORES > 1 +#define __TIMER_START(int_prio, core) false +#else +#define __TIMER_START(int_prio) false +#endif +#define __TIMER_STOP() #endif - -/* interrupt handler */ -#if defined(CPU_PP) -void TIMER2(void) -{ - TIMER2_VAL; /* ACK interrupt */ - if (cycles_new > 0) - { - TIMER2_CFG = 0xc0000000 | (cycles_new - 1); - cycles_new = 0; - } - if (pfn_timer != NULL) - { - cycles_new = -1; - /* "lock" the variable, in case timer_set_period() - * is called within pfn_timer() */ - pfn_timer(); - cycles_new = 0; - } -} -#endif /* CONFIG_CPU */ static bool timer_set(long cycles, bool start) { -#if defined(CPU_PP) - if (cycles > 0x20000000 || cycles < 2) - return false; - - if (start) - { - if (pfn_unregister != NULL) - { - pfn_unregister(); - pfn_unregister = NULL; - } - CPU_INT_DIS = TIMER2_MASK; - COP_INT_DIS = TIMER2_MASK; - } - if (start || (cycles_new == -1)) /* within isr, cycles_new is "locked" */ - TIMER2_CFG = 0xc0000000 | (cycles - 1); /* enable timer */ - else - cycles_new = cycles; - - return true; -#else return __TIMER_SET(cycles, start); -#endif /* CONFIG_CPU */ } /* Register a user timer, called every TIMER_FREQ cycles */ @@ -109,18 +67,12 @@ bool timer_register(int reg_prio, void (*unregister_callback)(void), pfn_unregister = unregister_callback; timer_prio = reg_prio; -#if defined(CPU_PP) - /* unmask interrupt source */ #if NUM_CORES > 1 - if (core == COP) - COP_INT_EN = TIMER2_MASK; - else -#endif - CPU_INT_EN = TIMER2_MASK; - return true; + return __TIMER_START(int_prio, core); #else return __TIMER_START(int_prio); #endif + /* Cover for targets that don't use all these */ (void)reg_prio; (void)unregister_callback; @@ -137,13 +89,8 @@ bool timer_set_period(long cycles) void timer_unregister(void) { -#if defined(CPU_PP) - TIMER2_CFG = 0; /* stop timer 2 */ - CPU_INT_DIS = TIMER2_MASK; - COP_INT_DIS = TIMER2_MASK; -#else __TIMER_STOP(); -#endif + pfn_timer = NULL; pfn_unregister = NULL; timer_prio = -1; -- cgit v1.2.3