![]() |
|
|||
File indexing completed on 2025-05-11 08:23:48
0001 /* 0002 * This port does not allow the application to select which timer on the 0003 * MVME167 to use for the clock, nor does it allow the application to 0004 * configure the clock. The clock uses the VMEchip2 Tick Timer #2. This 0005 * timer is set up to raise a MC680x0 level-6 interrupt every 1 ms. The 0006 * interrupt vector is 0x69. 0007 * 0008 * All page references are to the MVME166/MVME167/MVME187 Single Board 0009 * Computer Programmer's Reference Guide (MVME187PG/D2) with the April 0010 * 1993 supplements/addenda (MVME187PG/D2A1). 0011 */ 0012 0013 /* 0014 * COPYRIGHT (c) 1989-1999. 0015 * On-Line Applications Research Corporation (OAR). 0016 * 0017 * The license and distribution terms for this file may be 0018 * found in the file LICENSE in this distribution or at 0019 * http://www.rtems.org/license/LICENSE. 0020 * 0021 * Modifications of respective RTEMS files: 0022 * Copyright (c) 1998, National Research Council of Canada 0023 */ 0024 0025 #include <stdlib.h> 0026 #include <bsp.h> 0027 #include <rtems/clockdrv.h> 0028 0029 #define MS_COUNT 1000 /* T2's countdown constant (1 ms) */ 0030 #define CLOCK_INT_LEVEL 6 /* T2's interrupt level */ 0031 #define CLOCK_VECTOR (VBR0 * 0x10 + 0x9) /* T2 is vector $X9 (p. 2-71)*/ 0032 0033 /* 0034 * Clock_driver_ticks is a monotonically increasing counter of the number of 0035 * VMEchip2 timer #2 ticks since the driver was initialized. 0036 */ 0037 volatile uint32_t Clock_driver_ticks; 0038 0039 /* 0040 * Clock_isrs is the number of clock ISRs until the next invocation of the 0041 * RTEMS clock tick routine. This clock tick device driver gets an interrupt 0042 * once a millisecond and counts down until the length of time between the 0043 * user configured microseconds per tick has passed. This allows the clock 0044 * device to "tick" faster than the kernel clock. Of course, the kernel clock 0045 * cannot tick faster than the hardware clock. Therefore, the kernel clock 0046 * ticks cannot occur more frequently than every 1 millisecond. 0047 */ 0048 uint32_t Clock_isrs; 0049 0050 /* 0051 * Records the previous clock ISR (should be NULL) 0052 */ 0053 rtems_isr_entry Old_ticker; 0054 0055 /* 0056 * Called when the kernel exits. 0057 */ 0058 void clock_exit( void ); 0059 0060 /* 0061 * VMEchip2_T2_isr 0062 * 0063 * C ISR Handler. Increment the number of internal ticks. If it is time for a 0064 * kernel clock tick (if Clock_isrs == 1), call rtems_clock_tick() to signal 0065 * the event and reset the Clock_isrs counter; else, just decrement it. 0066 */ 0067 static rtems_isr VMEchip2_T2_isr( 0068 rtems_vector_number vector 0069 ) 0070 { 0071 char overflow; /* Content of overflow counter */ 0072 long i; 0073 long ct; /* Number of T2 ticks per RTEMS ticks */ 0074 0075 ct = rtems_configuration_get_microseconds_per_tick() / 1000; 0076 0077 /* 0078 * May have missed interrupts, so should look at the overflow counter. 0079 */ 0080 lcsr->intr_clear |= 0x02000000; /* Clear the interrupt */ 0081 overflow = (lcsr->board_ctl >> 12) & 0xF; 0082 lcsr->board_ctl |= 0x400; /* Reset overflow counter */ 0083 0084 /* Attempt to protect against one more period */ 0085 if ( overflow == 0 ) 0086 overflow = 16; 0087 0088 Clock_driver_ticks += overflow; /* One or more internal ticks */ 0089 0090 if ( Clock_isrs <= overflow ) { 0091 /* If its time for kernel clock ticks, signal the events to RTEMS */ 0092 for( i = overflow - Clock_isrs; i >= 0; i -= ct ) { 0093 rtems_clock_tick(); 0094 } 0095 /* Reset the counter */ 0096 Clock_isrs = (uint32_t)-i; 0097 } 0098 else 0099 Clock_isrs -= overflow; 0100 } 0101 0102 /* 0103 * VMEchip2_T2_initialize 0104 * 0105 * Initialize the VMEchip2 Tick Timer #2. 0106 * 0107 * THE VMECHIP2 PRESCALER REGISTER IS ASSUMED TO BE SET! 0108 * The prescaler is used by all VMEchip2 timers, including the VMEbus grant 0109 * timeout counter, the DMAC time off timer, the DMAC timer on timer, and the 0110 * VMEbus global timeout timer. The prescaler value is normally set by the 0111 * boot ROM to provide a 1 MHz clock to the timers. For a 25 MHz MVME167, the 0112 * prescaler value should be 0xE7 (page 2-63). 0113 */ 0114 static void VMEchip2_T2_initialize( void ) 0115 { 0116 Clock_driver_ticks = 0; 0117 Clock_isrs = rtems_configuration_get_microseconds_per_tick() / 1000; 0118 0119 lcsr->intr_ena &= 0xFDFFFFFF; /* Disable tick timer 2 interrupt */ 0120 lcsr->intr_clear = 0x02000000; /* Clear tick timer 2 interrupt */ 0121 lcsr->intr_level[0] = /* Set tick timer 2 interrupt level */ 0122 (lcsr->intr_level[0] & 0xFFFFFF0F ) | (CLOCK_INT_LEVEL << 4); 0123 lcsr->timer_cmp_2 = MS_COUNT; /* Period in compare register */ 0124 lcsr->timer_cnt_2 = 0; /* Clear tick timer 2 counter */ 0125 Old_ticker = /* Install C ISR */ 0126 (rtems_isr_entry) set_vector( VMEchip2_T2_isr, CLOCK_VECTOR, 1 ); 0127 lcsr->board_ctl |= 0x700; /* Start tick timer 2, reset-on-compare, */ 0128 /* and clear tick timer 2 overflow counter */ 0129 lcsr->intr_ena |= 0x02000000; /* Enable tick timer 2 interrupt */ 0130 lcsr->vector_base |= 0x00800000;/* Unmask VMEchip2 interrupts */ 0131 atexit( clock_exit ); /* Turn off T2 interrupts when we exit */ 0132 } 0133 0134 /* 0135 * This routine stops the VMEchip2 T2 timer, disables its interrupt, and 0136 * re-install the old interrupt vectors. 0137 */ 0138 void clock_exit( void ) 0139 { 0140 lcsr->board_ctl &= 0xFFFFFEFF; /* Stop tick timer 2 */ 0141 lcsr->intr_ena &= 0xFDFFFFFF; /* Disable tick timer 2 interrupt */ 0142 lcsr->intr_clear = 0x02000000; /* Clear tick timer 2 interrupt */ 0143 0144 set_vector( Old_ticker, CLOCK_VECTOR, 1 ); 0145 } 0146 0147 void _Clock_Initialize( void ) 0148 { 0149 VMEchip2_T2_initialize(); 0150 }
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |