source: rtems/c/src/lib/libbsp/nios2/nios2_iss/timer/timer.c @ 783669fc

4.104.114.84.95
Last change on this file since 783669fc was 783669fc, checked in by Joel Sherrill <joel.sherrill@…>, on 08/09/06 at 20:57:11

2006-08-09 Kolja Waschk <waschk@…>

  • ChangeLog?, Makefile.am, README, acinclude.m4, configure.ac, nios2_iss/ChangeLog, nios2_iss/Makefile.am, nios2_iss/bsp_specs, nios2_iss/configure.ac, nios2_iss/nios2_iss.ptf, nios2_iss/nios2_iss.sh, nios2_iss/times, nios2_iss/console/console.c, nios2_iss/include/bsp.h, nios2_iss/include/bspopts.h.in, nios2_iss/include/coverhd.h, nios2_iss/include/tm27.h, nios2_iss/shmsupp/addrconv.c, nios2_iss/shmsupp/getcfg.c, nios2_iss/shmsupp/lock.c, nios2_iss/shmsupp/mpisr.c, nios2_iss/start/crtnn.s, nios2_iss/start/start.S, nios2_iss/startup/bspclean.c, nios2_iss/startup/bspstart.c, nios2_iss/startup/linkcmds, nios2_iss/startup/main.c, nios2_iss/startup/setvec.c, nios2_iss/timer/timer.c: New files.
  • Property mode set to 100644
File size: 4.1 KB
Line 
1/*  timer.c
2 *
3 *  This file manages the benchmark timer used by the RTEMS Timing Test
4 *  Suite.  Each measured time period is demarcated by calls to
5 *  Timer_initialize() and Read_timer().  Read_timer() usually returns
6 *  the number of microseconds since Timer_initialize() exitted.
7 *
8 *  NOTE: It is important that the timer start/stop overhead be
9 *        determined when porting or modifying this code.
10 *
11 *  COPYRIGHT (c) 2005-2006 Kolja Waschk rtemsdev/ixo.de
12 *  Derived from no_cpu/no_bsp/timer/timer.c 1.9,
13 *  COPYRIGHT (c) 1989-1999.
14 *  On-Line Applications Research Corporation (OAR).
15 *
16 *  The license and distribution terms for this file may be
17 *  found in the file LICENSE in this distribution or at
18 *  http://www.rtems.com/license/LICENSE.
19 *
20 *  $Id$
21 */
22
23#define TIMER_WRAPS_AFTER_1MS 0
24
25#include <rtems.h>
26#include <rtems/score/cpu.h>
27#include <bsp.h>
28
29volatile uint32_t Timer_interrupts;
30rtems_boolean    Timer_driver_Find_average_overhead;
31
32#define TIMER_REGS ((altera_avalon_timer_regs*)NIOS2_IO_BASE(TIMER_BASE))
33
34void timerisr( void )
35{
36  TIMER_REGS->status = 0;
37  Timer_interrupts++;
38}
39
40void Timer_initialize( void )
41{
42  uint32_t old_ie;
43
44  /* Disable timer interrupt, stop timer */
45
46  TIMER_REGS->control = ALTERA_AVALON_TIMER_CONTROL_STOP_MSK;
47
48  set_vector((nios2_isr_entry *)timerisr, TIMER_VECTOR, 1);
49
50  /* Enable interrupt processing */
51
52  NIOS2_IENABLE(1 << TIMER_VECTOR);
53
54#if TIMER_WRAPS_AFTER_1MS
55  /* Writing to periodl/h resets the counter and eventually
56     stops it. If the timer hasn't been configured with fixed
57     period, set it to 1 ms now */
58
59  TIMER_REGS->period_hi = (TIMER_FREQ/1000)>>16;
60  TIMER_REGS->period_lo = (TIMER_FREQ/1000)&0xFFFF;
61#else
62  /* Writing to periodl/h resets the counter and eventually
63     stops it. Set max period */
64
65  TIMER_REGS->period_hi = 0xFFFF;
66  TIMER_REGS->period_lo = 0xFFFF;
67#endif
68
69  /* For timers that can be stopped, writing to periodl/h
70     also stopped the timer and we have to manually start it. */
71
72  TIMER_REGS->control = ALTERA_AVALON_TIMER_CONTROL_ITO_MSK |
73                        ALTERA_AVALON_TIMER_CONTROL_CONT_MSK |
74                        ALTERA_AVALON_TIMER_CONTROL_START_MSK;
75
76  /* This is the most safe place for resetting the overflow
77     counter - just _after_ we reset the timer. Depending
78     on the SOPC configuration, the counter may not be
79     stoppable and it doesn't make sense to assume that
80     there is any "safe" period before resetting. */
81
82  Timer_interrupts = 0;
83}
84
85/*
86 *  The following controls the behavior of Read_timer().
87 *
88 *  AVG_OVEREHAD is the overhead for starting and stopping the timer.  It
89 *  is usually deducted from the number returned.
90 *
91 *  LEAST_VALID is the lowest number this routine should trust.  Numbers
92 *  below this are "noise" and zero is returned.
93 */
94
95#define AVG_OVERHEAD      2      /* It typically takes 2 microseconds */
96                                 /* to start/stop the timer. */
97
98#define LEAST_VALID AVG_OVERHEAD /* Don't trust a value lower than this */
99
100int Read_timer( void )
101{
102  uint32_t timer_wraps;
103  uint32_t timer_snap;
104  uint32_t timer_ticks;
105  uint32_t total;
106  uint32_t old_ie;
107
108  /* Hold timer */
109  TIMER_REGS->control = ALTERA_AVALON_TIMER_CONTROL_STOP_MSK;
110
111  /* Write to request snapshot of timer value */
112  TIMER_REGS->snap_lo = 0;
113  /* Get snapshot */
114  timer_snap = ((TIMER_REGS->snap_hi)<<16) | TIMER_REGS->snap_lo;
115  timer_wraps = Timer_interrupts;
116
117  /* Restart timer */
118  TIMER_REGS->control = ALTERA_AVALON_TIMER_CONTROL_START_MSK;
119
120#if TIMER_WRAPS_AFTER_1MS
121  timer_ticks = (TIMER_FREQ / 1000) - 1 - timer_snap;
122  total = timer_wraps * 1000;
123#else
124  timer_ticks = 0xFFFFFFFF - timer_snap;
125  total = timer_wraps * 0x80000000 / (TIMER_FREQ / 2000000L);
126#endif
127  total += timer_ticks / (TIMER_FREQ / 1000000L);
128
129  if(total < LEAST_VALID) return 0;
130
131  if(Timer_driver_Find_average_overhead != TRUE) total-= AVG_OVERHEAD;
132 
133  return total;
134}
135
136/*
137 *  Empty function call used in loops to measure basic cost of looping
138 *  in Timing Test Suite.
139 */
140
141rtems_status_code Empty_function( void )
142{
143  return RTEMS_SUCCESSFUL;
144}
145
146void Set_find_average_overhead(
147  rtems_boolean find_flag
148)
149{
150  Timer_driver_Find_average_overhead = find_flag;
151}
Note: See TracBrowser for help on using the repository browser.