Nut/OS  4.10.3
API Reference
ostimer_s3c4510b.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2001-2004 by egnite Software GmbH. All rights reserved.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the copyright holders nor the names of
00014  *    contributors may be used to endorse or promote products derived
00015  *    from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
00018  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00019  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00020  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
00021  * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00022  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00023  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00024  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00025  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00026  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00027  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00028  * SUCH DAMAGE.
00029  *
00030  * For additional information see http://www.ethernut.de/
00031  *
00032  */
00033 
00034 /*
00035  * $Log$
00036  * Revision 1.7  2008/08/22 09:25:34  haraldkipp
00037  * Clock value caching and new functions NutArchClockGet, NutClockGet and
00038  * NutClockSet added.
00039  *
00040  * Revision 1.6  2008/08/11 06:59:13  haraldkipp
00041  * BSD types replaced by stdint types (feature request #1282721).
00042  *
00043  * Revision 1.5  2008/07/08 08:25:04  haraldkipp
00044  * NutDelay is no more architecture specific.
00045  * Number of loops per millisecond is configurable or will be automatically
00046  * determined.
00047  * A new function NutMicroDelay provides shorter delays.
00048  *
00049  * Revision 1.4  2007/08/17 10:44:37  haraldkipp
00050  * Timer enable/disable macro replaces previous global interrupt
00051  * enable/disable or function calling.
00052  *
00053  * Revision 1.3  2006/10/08 16:48:07  haraldkipp
00054  * Documentation fixed
00055  *
00056  * Revision 1.2  2005/10/24 08:58:48  haraldkipp
00057  * Header file moved.
00058  *
00059  * Revision 1.1  2005/07/26 18:02:26  haraldkipp
00060  * Moved from dev.
00061  *
00062  * Revision 1.2  2005/07/20 09:17:26  haraldkipp
00063  * Default NUT_CPU_FREQ and NUT_TICK_FREQ added.
00064  * NutTimerIntr() removed, because we can use the hardware independent code.
00065  *
00066  * Revision 1.1  2005/05/27 17:16:40  drsung
00067  * Moved the file.
00068  *
00069  * Revision 1.5  2005/04/05 17:50:46  haraldkipp
00070  * Use register names in gba.h.
00071  *
00072  * Revision 1.4  2004/11/08 19:16:37  haraldkipp
00073  * Hacked in Gameboy timer support
00074  *
00075  * Revision 1.3  2004/10/03 18:42:21  haraldkipp
00076  * No GBA support yet, but let the compiler run through
00077  *
00078  * Revision 1.2  2004/09/08 10:19:39  haraldkipp
00079  * Running on AT91 and S3C, thanks to James Tyou
00080  *
00081  */
00082 
00083 #include <cfg/arch.h>
00084 #if defined(MCU_AT91R40008)
00085 #include <arch/arm/at91.h>
00086 
00087 #elif defined(MCU_S3C4510B)
00088 #include <arch/arm.h>
00089 #include <dev/s3c4510b_hw.h>
00090 #include <dev/s3c4510b_irqs.h>
00091 
00092 #elif defined(MCU_GBA)
00093 #include <arch/gba.h>
00094 #include <dev/irqreg.h>
00095 
00096 #endif
00097 
00098 #ifndef NUT_CPU_FREQ
00099 #define NUT_CPU_FREQ    1000000UL
00100 #endif
00101 
00102 #ifndef NUT_TICK_FREQ
00103 #define NUT_TICK_FREQ   1000UL
00104 #endif
00105 
00106 #if defined(MCU_AT91R40008)
00107 static int dummy;
00108 #endif
00109 
00110 static void (*os_handler) (void *);
00111 
00115 #if defined(MCU_AT91R40008)
00116 void Timer0Entry(void) __attribute__ ((naked));
00117 void Timer0Entry(void)
00118 {
00119     IRQ_ENTRY();
00120     dummy = inr(TC0_SR);
00121     os_handler(0);
00122     IRQ_EXIT();
00123 }
00124 
00125 #elif defined(MCU_GBA)
00126 
00127 void Timer3Entry(void *arg)
00128 {
00129     outw(REG_IF, INT_TMR3);
00130     os_handler(0);
00131 }
00132 
00133 #endif
00134 
00146 void NutRegisterTimer(void (*handler) (void *))
00147 {
00148     os_handler = handler;
00149 
00150 #if defined(MCU_AT91R40008)
00151 
00152     /* Disable the Clock Counter */
00153     outr(TC0_CCR, TC_CLKDIS);
00154     /* Disable all interrupts */
00155     outr(TC0_IDR, 0xFFFFFFFF);
00156     /* Clear the status register. */
00157     dummy = inr(TC0_SR);
00158     /* Select divider and compare trigger */
00159     outr(TC0_CMR, TC_CLKS_MCK32 | TC_CPCTRG);
00160     /* Enable the Clock counter */
00161     outr(TC0_CCR, TC_CLKEN);
00162     /* Validate the RC compare interrupt */
00163     outr(TC0_IER, TC_CPCS);
00164 
00165     /* Disable timer 0 interrupts. */
00166     outr(AIC_IDCR, _BV(TC0_ID));
00167     /* Set the TC0 IRQ handler address */
00168     outr(AIC_SVR(4), (unsigned int)Timer0Entry);
00169     /* Set the trigg and priority for timer 0 interrupt */
00170     /* Level 7 is highest, level 0 lowest. */
00171     outr(AIC_SMR(4), (AIC_SRCTYPE_INT_LEVEL_SENSITIVE | 0x4));
00172     /* Clear timer 0 interrupt */
00173     outr(AIC_ICCR, _BV(TC0_ID));
00174     /* Enable timer 0 interrupts */
00175     outr(AIC_IECR, _BV(TC0_ID));
00176 
00177     /* Set compare value for 1 ms. */
00178     outr(TC0_RC, 0x80F);
00179     /* Software trigger starts the clock. */
00180     outr(TC0_CCR, TC_SWTRG);
00181 
00182 #elif defined(MCU_S3C4510B)
00183 
00184     INT_DISABLE(IRQ_TIMER);
00185     CSR_WRITE(TCNT0, 0);
00186     CSR_WRITE(TDATA0, CLOCK_TICK_RATE);
00187     CSR_WRITE(TMOD, TMOD_TIMER0_VAL);
00188 
00189     CLEAR_PEND_INT(IRQ_TIMER);
00190 
00191     NutRegisterIrqHandler(
00192         &InterruptHandlers[IRQ_TIMER], handler, 0);
00193 
00194     INT_ENABLE(IRQ_TIMER);
00195 
00196 #elif defined(MCU_GBA)
00197 
00198     /* Disable master interrupt. */
00199     outw(REG_IME, 0);
00200 
00201     /* Set global interrupt vector. */
00202     NutRegisterIrqHandler(&sig_TMR3, Timer3Entry, 0);
00203 
00204     /* Enable timer and timer interrupts. */
00205     outdw(REG_TMR3CNT, TMR_IRQ_ENA | TMR_ENA | 48756);
00206 
00207     /* Enable timer 3 interrupts. */
00208     outw(REG_IE, inw(REG_IE) | INT_TMR3);
00209 
00210     /* Enable master interrupt. */
00211     outw(REG_IME, 1);
00212 
00213 #else
00214 #warning "MCU not defined"
00215 #endif
00216 }
00217 
00223 uint32_t NutArchClockGet(int idx)
00224 {
00225     return NUT_CPU_FREQ;
00226 }
00227 
00233 uint32_t NutGetTickClock(void)
00234 {
00235     return NUT_TICK_FREQ;
00236 }
00237 
00241 uint32_t NutTimerMillisToTicks(uint32_t ms)
00242 {
00243 #if (NUT_TICK_FREQ % 1000)
00244     if (ms >= 0x3E8000UL)
00245         return (ms / 1000UL) * NUT_TICK_FREQ;
00246     return (ms * NUT_TICK_FREQ + 999UL) / 1000UL;
00247 #else
00248     return ms * (NUT_TICK_FREQ / 1000UL);
00249 #endif
00250 }
00251 
00252