summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/i960/rxgen960/timer/timer.c
blob: eabb33d81ab2b338355b5f529601ada9955a1d73 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*  Timer_init()
 *
 *  This routine initializes the Z8536 timer on the SQSIO4 SQUALL
 *  board for the CVME961 board.  The timer is setup to provide a
 *  tick every 1 millisecond.
 *
 *  Input parameters:  NONE
 *
 *  Output parameters:  NONE
 *
 *  NOTE: This routine will not work if the optimizer is enabled
 *        for most compilers.  The multiple writes to the Z8536
 *        will be optimized away.
 *
 *        It is important that the timer start/stop overhead be
 *        determined when porting or modifying this code.
 *
 *  COPYRIGHT (c) 1989-1997.
 *  On-Line Applications Research Corporation (OAR).
 *  Copyright assigned to U.S. Government, 1994.
 *
 *  The license and distribution terms for this file may in
 *  the file LICENSE in this distribution or at
 *  http://www.OARcorp.com/rtems/license.html.
 *
 *  $Id$
 */


#include <bsp.h>
#include <stdlib.h>
#include <rtems/libio.h>


#define TIMER_VECTOR 34

int Ttimer_val;
rtems_boolean Timer_driver_Find_average_overhead = 0;

void flush_reg();
rtems_isr timerisr();

void Timer_initialize()
{
  volatile unsigned int *tmr1 = (unsigned int *) TMR1_ADDR;
  volatile unsigned int *trr1 = (unsigned int *) TRR1_ADDR;
  volatile unsigned int *tcr1 = (unsigned int *) TCR1_ADDR;
  volatile unsigned int *imsk = (unsigned int *) IMSK_ADDR;
  volatile unsigned int *icon = (unsigned int *) ICON_ADDR;
  volatile unsigned int *ipnd = (unsigned int *) IPND_ADDR;
  volatile unsigned int *imap2 = (unsigned int *) IMAP2_ADDR;

    #define BUS_CLOCK_1 0
    #define TMR_WRITE_CNTL 8
    #define TMR_AUTO_RELOAD 4
    #define TMR_ENABLE 2
    #define TMR_TERM_CNT_STAT 1
  
    *tmr1 = BUS_CLOCK_1 | TMR_AUTO_RELOAD; 
     *icon = 0x6000; 


    set_vector( (((unsigned int) timerisr) | 0x2), TIMER_VECTOR, 1 );

    *imap2 = (*imap2 & 0xff0fffff) | (((TIMER_VECTOR >> 4) & 0xf) << 20);

    /* initialize the i960RP timer 1 here */
    
    /* set the timer countdown */
    *trr1 = 33 * BSP_Configuration.microseconds_per_tick;
    *tcr1 = 33 * BSP_Configuration.microseconds_per_tick;
  
    *ipnd &= ~(1<<13);
    *imsk |= (1 << 13); 
    Ttimer_val = 0;
    *tmr1 = BUS_CLOCK_1 | TMR_AUTO_RELOAD | TMR_ENABLE;

}



rtems_isr timerisr(
  rtems_vector_number vector
)
{
  /* enable_tracing(); */
  Ttimer_val++;
  i960_clear_intr( 13 );
}

#define AVG_OVERHEAD      4 /* It typically takes 5.5 microseconds */
                             /* (11 countdowns) to start/stop the timer. */
#define LEAST_VALID       5 /* Don't trust a value lower than this */

int Read_timer()
{
  volatile unsigned int *tcr1 = (unsigned int *) TCR1_ADDR;
  volatile unsigned int *trr1 = (unsigned int *) TRR1_ADDR;
  rtems_unsigned32 remaining, total;

  /* this routine is supposed to count in 1/2 uSec units */
  /* pretty funny when using a 33MHz clock for the counter */
  remaining =  *tcr1;
  remaining =  *trr1 - remaining;
  total = (2 * ((Ttimer_val * *trr1) + remaining)) / 33;
/*
  putnum(remaining);
  console_sps_putc(':');
  putnum(total);
*/

  if ( Timer_driver_Find_average_overhead == 1 )
    return total;          /* in one-half microsecond units */
  else {
    if ( total < LEAST_VALID )
      return 0;            /* below timer resolution */
    return (total-AVG_OVERHEAD) >> 1;
  }
}

rtems_status_code Empty_function( void )
{
  return RTEMS_SUCCESSFUL;
}

void Set_find_average_overhead(
  rtems_boolean find_flag
)
{
  Timer_driver_Find_average_overhead = find_flag;
}