summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/sparc/erc32/clock/ckinit.c
blob: 21c82de152d5324a15b8d2afb4c92a8e9f8d9839 (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
132
133
/*
 *  This routine initializes the Real Time Clock Counter Timer which is
 *  part of the MEC on the ERC32 CPU.
 *
 *  The tick frequency is directly programmed to the configured number of
 *  microseconds per tick.
 */

/*
 *  COPYRIGHT (c) 1989-2008.
 *  On-Line Applications Research Corporation (OAR).
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.rtems.org/license/LICENSE.
 *
 *  Ported to ERC32 implementation of the SPARC by On-Line Applications
 *  Research Corporation (OAR) under contract to the European Space
 *  Agency (ESA).
 *
 *  ERC32 modifications of respective RTEMS file: COPYRIGHT (c) 1995.
 *  European Space Agency.
 */

#include <bsp.h>
#include <bspopts.h>
#include <rtems/counter.h>
#include <rtems/timecounter.h>
#include <rtems/score/sparcimpl.h>

/*
 *  The Real Time Clock Counter Timer uses this trap type.
 */
#define CLOCK_VECTOR ERC32_TRAP_TYPE( ERC32_INTERRUPT_REAL_TIME_CLOCK )

#define Clock_driver_support_install_isr( _new, _old ) \
  do { \
    _old = set_vector( _new, CLOCK_VECTOR, 1 ); \
  } while(0)

#define Clock_driver_support_set_interrupt_affinity( _online_processors ) \
  do { \
    (void) _online_processors; \
  } while (0)

extern int CLOCK_SPEED;

static rtems_timecounter_simple erc32_tc;

static uint32_t erc32_tc_get( rtems_timecounter_simple *tc )
{
  return ERC32_MEC.Real_Time_Clock_Counter;
}

static bool erc32_tc_is_pending( rtems_timecounter_simple *tc )
{
  return ERC32_Is_interrupt_pending( ERC32_INTERRUPT_REAL_TIME_CLOCK );
}

static uint32_t erc32_tc_get_timecount( struct timecounter *tc )
{
  return rtems_timecounter_simple_downcounter_get(
    tc,
    erc32_tc_get,
    erc32_tc_is_pending
  );
}

static void erc32_tc_at_tick( rtems_timecounter_simple *tc )
{
  /* Nothing to do */
}

static void erc32_tc_tick( void )
{
  rtems_timecounter_simple_downcounter_tick(
    &erc32_tc,
    erc32_tc_get,
    erc32_tc_at_tick
  );
}

static void erc32_counter_initialize( uint32_t frequency )
{
  _SPARC_Counter_initialize(
    _SPARC_Counter_read_address,
    _SPARC_Counter_difference_clock_period,
    &ERC32_MEC.Real_Time_Clock_Counter
  );
  rtems_counter_initialize_converter( frequency );
}

#define Clock_driver_support_initialize_hardware() \
  do { \
    uint32_t frequency = 1000000; \
    /* approximately 1 us per countdown */ \
    ERC32_MEC.Real_Time_Clock_Scalar  = CLOCK_SPEED - 1; \
    ERC32_MEC.Real_Time_Clock_Counter = \
      rtems_configuration_get_microseconds_per_tick(); \
    \
    ERC32_MEC_Set_Real_Time_Clock_Timer_Control( \
        ERC32_MEC_TIMER_COUNTER_ENABLE_COUNTING | \
        ERC32_MEC_TIMER_COUNTER_LOAD_SCALER | \
        ERC32_MEC_TIMER_COUNTER_LOAD_COUNTER \
    ); \
    \
    ERC32_MEC_Set_Real_Time_Clock_Timer_Control( \
        ERC32_MEC_TIMER_COUNTER_ENABLE_COUNTING | \
        ERC32_MEC_TIMER_COUNTER_RELOAD_AT_ZERO \
    );  \
    rtems_timecounter_simple_install( \
        &erc32_tc, \
        frequency, \
        rtems_configuration_get_microseconds_per_tick(), \
        erc32_tc_get_timecount \
    ); \
    erc32_counter_initialize( frequency ); \
  } while (0)

#define Clock_driver_timecounter_tick() erc32_tc_tick()

#define Clock_driver_support_shutdown_hardware() \
  do { \
    ERC32_Mask_interrupt( ERC32_INTERRUPT_REAL_TIME_CLOCK ); \
     \
    ERC32_MEC_Set_Real_Time_Clock_Timer_Control( \
      ERC32_MEC_TIMER_COUNTER_DISABLE_COUNTING \
    ); \
  } while (0)

#include "../../../shared/clockdrv_shell.h"

SPARC_COUNTER_DEFINITION;