OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [arm/] [at91/] [var/] [current/] [src/] [timer_tc.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
/*==========================================================================
2
//
3
//      timer_tc.c
4
//
5
//      HAL timer code using the Timer Counter
6
//
7
//==========================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####
9
// -------------------------------------------
10
// This file is part of eCos, the Embedded Configurable Operating System.
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2010 Free Software Foundation, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under
14
// the terms of the GNU General Public License as published by the Free
15
// Software Foundation; either version 2 or (at your option) any later
16
// version.
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
21
// for more details.
22
//
23
// You should have received a copy of the GNU General Public License
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
26
//
27
// As a special exception, if other files instantiate templates or use
28
// macros or inline functions from this file, or you compile this file
29
// and link it with other works to produce a work based on this file,
30
// this file does not by itself cause the resulting work to be covered by
31
// the GNU General Public License. However the source code for this file
32
// must still be made available in accordance with section (3) of the GNU
33
// General Public License v2.
34
//
35
// This exception does not invalidate any other reasons why a work based
36
// on this file might be covered by the GNU General Public License.
37
// -------------------------------------------
38
// ####ECOSGPLCOPYRIGHTEND####
39
//==========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):    gthomas
43
// Contributors: gthomas, jskov, nickg, tkoeller, jld
44
// Date:         2001-07-12
45
// Purpose:      HAL board support
46
// Description:  Implementations of HAL board interfaces
47
//
48
//####DESCRIPTIONEND####
49
//
50
//========================================================================*/
51
 
52
#include <pkgconf/hal.h>
53
 
54
#include <cyg/infra/cyg_type.h>         // base types
55
#include <cyg/infra/cyg_ass.h>          // assertion macros
56
 
57
#include <cyg/hal/hal_io.h>             // IO macros
58
#include <cyg/hal/hal_arch.h>           // Register state info
59
#include <cyg/hal/hal_intr.h>           // necessary?
60
 
61
#ifdef CYGFUN_HAL_ARM_AT91_PROFILE_TIMER
62
#include <cyg/hal/drv_api.h>            // CYG_ISR_HANDLED
63
#include <cyg/profile/profile.h>        // __profile_hit()
64
#endif
65
 
66
// -------------------------------------------------------------------------
67
// Clock support
68
 
69
static cyg_uint32 _period;
70
 
71
void hal_clock_initialize(cyg_uint32 period)
72
{
73
    CYG_ADDRESS timer = AT91_TC+AT91_TC_TC0;
74
 
75
    CYG_ASSERT(period < 0x10000, "Invalid clock period");
76
 
77
    // Disable counter
78
    HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_CLKDIS);
79
 
80
    // Set registers
81
    HAL_WRITE_UINT32(timer+AT91_TC_CMR, AT91_TC_CMR_CPCTRG |        // Reset counter on CPC
82
                                        AT91_TC_CMR_CLKS_MCK32);    // 1 MHz
83
    HAL_WRITE_UINT32(timer+AT91_TC_RC, period);
84
 
85
    // Start timer
86
    HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_TRIG | AT91_TC_CCR_CLKEN);
87
 
88
    // Enable timer 0 interrupt    
89
    HAL_WRITE_UINT32(timer+AT91_TC_IER, AT91_TC_IER_CPC);
90
}
91
 
92
void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period)
93
{
94
    CYG_ADDRESS timer = AT91_TC+AT91_TC_TC0;
95
    cyg_uint32 sr;
96
 
97
    CYG_ASSERT(period < 0x10000, "Invalid clock period");
98
 
99
    HAL_READ_UINT32(timer+AT91_TC_SR, sr);  // Clear interrupt
100
 
101
    if (period != _period) {
102
        hal_clock_initialize(period);
103
    }
104
    _period = period;
105
 
106
}
107
 
108
void hal_clock_read(cyg_uint32 *pvalue)
109
{
110
    CYG_ADDRESS timer = AT91_TC+AT91_TC_TC0;
111
    cyg_uint32 val;
112
 
113
    HAL_READ_UINT32(timer+AT91_TC_CV, val);
114
    *pvalue = val;
115
}
116
 
117
// -------------------------------------------------------------------------
118
//
119
// Delay for some number of micro-seconds
120
//   Use timer #2 in MCLOCK/32 mode.
121
//
122
void hal_delay_us(cyg_int32 usecs)
123
{
124
    cyg_uint32 stat;
125
    cyg_uint64 ticks;
126
#if defined(CYGHWR_HAL_ARM_AT91_JTST)
127
    // TC2 is reserved for AD/DA. Use TC1 instead. 
128
    CYG_ADDRESS timer = AT91_TC+AT91_TC_TC1;
129
#else
130
    CYG_ADDRESS timer = AT91_TC+AT91_TC_TC2;
131
#endif
132
    // Calculate how many timer ticks the required number of
133
    // microseconds equate to. We do this calculation in 64 bit
134
    // arithmetic to avoid overflow.
135
    ticks = (((cyg_uint64)usecs) *
136
             ((cyg_uint64)CYGNUM_HAL_ARM_AT91_CLOCK_SPEED))/32000000LL;
137
 
138
    //    CYG_ASSERT(ticks < (1 << 16), "Timer overflow");
139
 
140
    if (ticks > (1 << 16))
141
      ticks = (1 << 16) - 1;
142
 
143
    if (ticks == 0)
144
      return;
145
 
146
    // Disable counter
147
    HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_CLKDIS);
148
 
149
    // Set registers
150
    HAL_WRITE_UINT32(timer+AT91_TC_CMR, AT91_TC_CMR_CLKS_MCK32);  // 1MHz
151
    HAL_WRITE_UINT32(timer+AT91_TC_RA, 0);
152
    HAL_WRITE_UINT32(timer+AT91_TC_RC, ticks);
153
 
154
    // Clear status flags
155
    HAL_READ_UINT32(timer+AT91_TC_SR, stat);
156
 
157
    // Start timer
158
    HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_TRIG | AT91_TC_CCR_CLKEN);
159
 
160
    // Wait for the compare
161
    do {
162
      HAL_READ_UINT32(timer+AT91_TC_SR, stat);
163
    } while ((stat & AT91_TC_SR_CPC) == 0);
164
}
165
 
166
#ifdef CYGFUN_HAL_ARM_AT91_PROFILE_TIMER
167
 
168
// Use TC1 for profiling
169
#define AT91_TC_PROFILE AT91_TC_TC1
170
#define HAL_INTERRUPT_PROFILE CYGNUM_HAL_INTERRUPT_TIMER1
171
 
172
// Profiling timer ISR
173
static cyg_uint32 profile_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data, HAL_SavedRegisters *regs)
174
{
175
    cyg_uint32 status;
176
 
177
    HAL_READ_UINT32(AT91_TC+AT91_TC_PROFILE+AT91_TC_SR, status); // Clear interrupt
178
    HAL_INTERRUPT_ACKNOWLEDGE(HAL_INTERRUPT_PROFILE);
179
    __profile_hit(regs->pc);
180
    return CYG_ISR_HANDLED;
181
}
182
 
183
// Profiling timer setup
184
int hal_enable_profile_timer(int resolution)
185
{
186
    cyg_uint32 period;
187
 
188
    // Calculate how many timer ticks the requested resolution in
189
    // microseconds equates to. We do this calculation in 64 bit
190
    // arithmetic to avoid overflow.
191
    period = (cyg_uint32)((((cyg_uint64)resolution) *
192
        ((cyg_uint64)CYGNUM_HAL_ARM_AT91_CLOCK_SPEED))/32000000LL);
193
 
194
    CYG_ASSERT(period < 0x10000, "Invalid profile timer resolution"); // 16 bits only
195
 
196
    // Attach ISR
197
    HAL_INTERRUPT_ATTACH(HAL_INTERRUPT_PROFILE, &profile_isr, 0x1111, 0);
198
    HAL_INTERRUPT_UNMASK(HAL_INTERRUPT_PROFILE);
199
 
200
    // Disable counter
201
    HAL_WRITE_UINT32(AT91_TC+AT91_TC_PROFILE+AT91_TC_CCR, AT91_TC_CCR_CLKDIS);
202
 
203
    // Set registers
204
    HAL_WRITE_UINT32(AT91_TC+AT91_TC_PROFILE+AT91_TC_CMR, AT91_TC_CMR_CPCTRG | // Reset counter on CPC
205
                                                          AT91_TC_CMR_CLKS_MCK32); // Use MCLK/32
206
    HAL_WRITE_UINT32(AT91_TC+AT91_TC_PROFILE+AT91_TC_RC, period);
207
 
208
    // Start timer
209
    HAL_WRITE_UINT32(AT91_TC+AT91_TC_PROFILE+AT91_TC_CCR, AT91_TC_CCR_TRIG | AT91_TC_CCR_CLKEN);
210
 
211
    // Enable timer interrupt
212
    HAL_WRITE_UINT32(AT91_TC+AT91_TC_PROFILE+AT91_TC_IER, AT91_TC_IER_CPC);
213
 
214
    return resolution;
215
}
216
 
217
#endif // CYGFUN_HAL_ARM_AT91_PROFILE_TIMER
218
 
219
// timer_tc.c

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.