Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:44

0001 /*
0002  *  Clock Driver for MCF5272 CPU
0003  *
0004  *  This driver initailizes timer1 on the MCF5272 as the
0005  *  main system clock
0006  */
0007 
0008 /*
0009  *  Copyright 2004 Cogent Computer Systems
0010  *  Author: Jay Monkman <jtm@lopingdog.com>
0011  *
0012  *  Based on MCF5206 clock driver by
0013  *    Victor V. Vengerov <vvv@oktet.ru>
0014  *
0015  *  Based on work:
0016  *    David Fiddes, D.J@fiddes.surfaid.org
0017  *    http://www.calm.hw.ac.uk/davidf/coldfire/
0018  *
0019  *  COPYRIGHT (c) 1989-1998.
0020  *  On-Line Applications Research Corporation (OAR).
0021  *
0022  *  The license and distribution terms for this file may be
0023  *  found in the file LICENSE in this distribution or at
0024  *  http://www.rtems.org/license/LICENSE.
0025  */
0026 
0027 #include <stdlib.h>
0028 #include <bsp.h>
0029 #include <rtems/libio.h>
0030 #include <mcf5272/mcf5272.h>
0031 #include <rtems/clockdrv.h>
0032 
0033 /*
0034  * Clock_driver_ticks is a monotonically increasing counter of the
0035  * number of clock ticks since the driver was initialized.
0036  */
0037 volatile uint32_t Clock_driver_ticks;
0038 
0039 rtems_isr (*rtems_clock_hook)(rtems_vector_number) = NULL;
0040 
0041 static rtems_isr
0042 Clock_isr (rtems_vector_number vector)
0043 {
0044   /* Clear pending interrupt... */
0045   g_timer_regs->ter1 = MCF5272_TER_REF | MCF5272_TER_CAP;
0046 
0047   /* Announce the clock tick */
0048   Clock_driver_ticks++;
0049   rtems_clock_tick();
0050   if (rtems_clock_hook != NULL) {
0051       rtems_clock_hook(vector);
0052   }
0053 }
0054 
0055 static void
0056 Clock_exit(void)
0057 {
0058   uint32_t icr;
0059 
0060   /* disable all timer1 interrupts */
0061   icr = g_intctrl_regs->icr1;
0062   icr = icr & ~(MCF5272_ICR1_TMR1_MASK | MCF5272_ICR1_TMR1_PI);
0063   icr |= (MCF5272_ICR1_TMR1_IPL(0) | MCF5272_ICR1_TMR1_PI);
0064   g_intctrl_regs->icr1 = icr;
0065 
0066   /* reset timer1 */
0067   g_timer_regs->tmr1 = MCF5272_TMR_CLK_STOP;
0068 
0069   /* clear pending */
0070   g_timer_regs->ter1 = MCF5272_TER_REF | MCF5272_TER_CAP;
0071 }
0072 
0073 static void
0074 Install_clock(rtems_isr_entry clock_isr)
0075 {
0076   uint32_t icr;
0077 
0078   Clock_driver_ticks = 0;
0079 
0080   /* Register the interrupt handler */
0081   set_vector(clock_isr, BSP_INTVEC_TMR1, 1);
0082 
0083   /* Reset timer 1 */
0084   g_timer_regs->tmr1 = MCF5272_TMR_RST;
0085   g_timer_regs->tmr1 = MCF5272_TMR_CLK_STOP;
0086   g_timer_regs->tmr1 = MCF5272_TMR_RST;
0087   g_timer_regs->tcn1 = 0;  /* reset counter */
0088   g_timer_regs->ter1 = MCF5272_TER_REF | MCF5272_TER_CAP;
0089 
0090   /* Set Timer 1 prescaler so that it counts in microseconds */
0091   g_timer_regs->tmr1 = (
0092       ((((BSP_SYSTEM_FREQUENCY / 1000000) - 1) << MCF5272_TMR_PS_SHIFT) |
0093        MCF5272_TMR_CE_DISABLE                                      |
0094        MCF5272_TMR_ORI                                             |
0095        MCF5272_TMR_FRR                                             |
0096        MCF5272_TMR_CLK_MSTR                                        |
0097        MCF5272_TMR_RST));
0098 
0099   /* Set the timer timeout value from the BSP config */
0100   g_timer_regs->trr1 = rtems_configuration_get_microseconds_per_tick() - 1;
0101 
0102   /* Feed system frequency to the timer */
0103   g_timer_regs->tmr1 |= MCF5272_TMR_CLK_MSTR;
0104 
0105   /* Configure timer1 interrupts */
0106   icr = g_intctrl_regs->icr1;
0107   icr = icr & ~(MCF5272_ICR1_TMR1_MASK | MCF5272_ICR1_TMR1_PI);
0108   icr |= (MCF5272_ICR1_TMR1_IPL(BSP_INTLVL_TMR1) | MCF5272_ICR1_TMR1_PI);
0109   g_intctrl_regs->icr1 = icr;
0110 
0111   /* Register the driver exit procedure so we can shutdown */
0112   atexit(Clock_exit);
0113 }
0114 
0115 void _Clock_Initialize( void )
0116 {
0117   Install_clock (Clock_isr);
0118 }