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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [kernel/] [v2_0/] [tests/] [clockcnv.cxx] - Blame information for rev 27

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//        clockcnv.cxx
4
//
5
//        Clock Converter test
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 Red Hat, Inc.
12
// Copyright (C) 2003 Gary Thomas
13
//
14
// eCos is free software; you can redistribute it and/or modify it under
15
// the terms of the GNU General Public License as published by the Free
16
// Software Foundation; either version 2 or (at your option) any later version.
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19
// 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 along
24
// with eCos; if not, write to the Free Software Foundation, Inc.,
25
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26
//
27
// As a special exception, if other files instantiate templates or use macros
28
// or inline functions from this file, or you compile this file and link it
29
// with other works to produce a work based on this file, this file does not
30
// by itself cause the resulting work to be covered by the GNU General Public
31
// License. However the source code for this file must still be made available
32
// in accordance with section (3) of the GNU General Public License.
33
//
34
// This exception does not invalidate any other reasons why a work based on
35
// this file might be covered by the GNU General Public License.
36
//
37
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
38
// at http://sources.redhat.com/ecos/ecos-license/
39
// -------------------------------------------
40
//####ECOSGPLCOPYRIGHTEND####
41
//==========================================================================
42
//#####DESCRIPTIONBEGIN####
43
//
44
// Author(s):     hmt
45
// Contributors:  hmt
46
// Date:          2000-01-24
47
// Description:   Tests the Kernel Real Time Clock Converter subsystem
48
// 
49
//####DESCRIPTIONEND####
50
 
51
#include <pkgconf/kernel.h>
52
 
53
#include <cyg/kernel/clock.hxx>
54
#include <cyg/kernel/thread.hxx>
55
 
56
#include <cyg/infra/testcase.h>
57
 
58
#include <cyg/kernel/clock.inl>
59
#include <cyg/kernel/thread.inl>
60
 
61
#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
62
 
63
#include <cyg/infra/diag.h>
64
 
65
static void null_printf(const char *, ...)
66
{ /* nothing */ }
67
 
68
#define PRINTF0 diag_printf
69
#define nPRINTF0 null_printf
70
 
71
#define nPRINTF1 diag_printf
72
#define PRINTF1 null_printf
73
 
74
#define nPRINTF2 diag_printf
75
#define PRINTF2 null_printf
76
 
77
 
78
#define NTHREADS 1
79
#include "testaux.hxx"
80
 
81
static struct { cyg_uint32 ns; double scale; } ns_tickers[] = {
82
    { 70000000, 7.0 },                  // 7cS
83
    { 50000000, 5.0 },                  // 5cS
84
    { 45000000, 4.5 },                  // 4.5cS
85
    { 30000000, 3.0 },                  // 3cS
86
    { 20000000, 2.0 },                  // 2cS
87
    { 10000000, 1.0 },                  // 1cS - no change
88
    {  5000000, 0.5 },                  // 1/2 a cS
89
    {  4900000, 0.49 },                 // a bit below
90
    {  3333333, 0.3333333 },            // 1/3 cS
91
    {  1250000, 0.125 },                // 800Hz
92
    {  1000000, 0.1 },                  // 1000Hz
93
    {   909090, 0.0909090 },            // 1100Hz
94
    {   490000, 0.049 },                // 490uS
95
    {   333333, 0.0333333 },            // 1/30 cS, 1/3mS
96
    {    49000, 0.0049 },               // 49uS
97
    {    33333, 0.0033333 },            // 1/30 mS
98
    {     4900, 0.00049 },              // 4.9uS
99
    // now some outlandish ones
100
    {      170, 0.000017 },             // 170nS
101
    {       11, 0.0000011 },            // 11nS
102
    { 1000000000u, 100.0 },             // one second
103
    { 1234567777u, 123.4567777 },       // 1.234... seconds
104
    { 4294967291u, 429.4967291 },       // 4.3 seconds, nearly maxint.
105
    // now some which are prime in the nS per tick field
106
    {   909091, 0.0909091 },            // also 1100Hz - but 909091 is a prime!
107
    // and some eye-pleasing primes from the www - if they're not actually
108
    // prime, don't blame me.   http://www.rsok.com/~jrm/printprimes.html
109
    {  1000003, 0.1000003 },
110
    {  1477771, 0.1477771 },
111
    {  2000003, 0.2000003 },
112
    {  2382001, 0.2382001 },
113
    {  3333133, 0.3333133 },
114
    {  3999971, 0.3999971 },
115
    {  5555591, 0.5555591 },
116
    {  6013919, 0.6013919 },
117
    // That's enough
118
};
119
 
120
static void entry0( CYG_ADDRWORD data )
121
{
122
    // First just try it with the clock as default:
123
    Cyg_Clock *rtc = Cyg_Clock::real_time_clock;
124
 
125
    Cyg_Clock::converter cv, rcv;
126
    Cyg_Clock::cyg_resolution res;
127
 
128
    unsigned int counter = 0;
129
    unsigned int skipped = 0;
130
 
131
    unsigned int i;
132
    for ( i = 0; i < sizeof( ns_tickers )/sizeof( ns_tickers[0] ); i++ ) {
133
 
134
        unsigned int lcounter = 0;
135
        unsigned int lskipped = 0;
136
 
137
        rtc->get_other_to_clock_converter( ns_tickers[i].ns, &cv );
138
        rtc->get_clock_to_other_converter( ns_tickers[i].ns, &rcv );
139
 
140
        PRINTF1( "ns per tick: %d\n", ns_tickers[i].ns );
141
        PRINTF1( "  converter: * %d / %d * %d / %d\n",
142
                     (int)cv.mul1, (int)cv.div1, (int)cv.mul2,(int) cv.div2 );
143
        PRINTF1( "   reverser: * %d / %d * %d / %d\n",
144
                     (int)rcv.mul1, (int)rcv.div1, (int)rcv.mul2, (int)rcv.div2 );
145
 
146
        double d = 1.0;
147
        d *= (double)cv.mul1;
148
        d /= (double)cv.div1;
149
        d *= (double)cv.mul2;
150
        d /= (double)cv.div2;
151
        d *= (double)rcv.mul1;
152
        d /= (double)rcv.div1;
153
        d *= (double)rcv.mul2;
154
        d /= (double)rcv.div2;
155
        PRINTF1( "       composite product %d.%d\n",
156
                     (int)d, ((int)(d * 1000000) % 1000000 ) );
157
        d -= 1.0;
158
        CYG_TEST_CHECK( d < +0.0001, "Overflow in composite product" );
159
        CYG_TEST_CHECK( d > -0.0001, "Underflow in composite product" );
160
 
161
        res = rtc->get_resolution();
162
 
163
        double factor_other_to_clock;
164
        double factor_clock_to_other;
165
 
166
        // res.dividend/res.divisor is the number of nS in a system
167
        // clock tick.  So:
168
        d = (double)res.dividend/(double)res.divisor;
169
 
170
        factor_other_to_clock = ns_tickers[i].scale * 1.0e7 / d ;
171
        factor_clock_to_other = d / (ns_tickers[i].scale * 1.0e7);
172
 
173
        unsigned int j;
174
        for ( j = 1; j < 100; j++ ) {
175
            cyg_uint64 delay;
176
            if (cyg_test_is_simulator)
177
                j += 30;                // test fewer values
178
                                   /* tr.b..m..k.. */
179
 
180
#ifdef CYGPKG_HAL_V85X_V850_CEB
181
            j += 30;                    // test fewer values
182
#endif
183
 
184
            for ( delay = j; delay < 1000000000000ll; delay *= 10 ) {
185
                // get the converted result
186
                cyg_uint64 result = Cyg_Clock::convert( delay, &cv );
187
 
188
                counter++; lcounter++;
189
                if ( (double)delay * (double)cv.mul1 > 1.6e+19 ||
190
                     (double)delay * (double)rcv.mul1 > 1.6e+19 ) {
191
                    // in silly territory now, give up.
192
                    // (that's MAXINT squared, approx.)
193
                    skipped++; lskipped++;
194
                    continue; // so the counter is accurate
195
                }
196
 
197
                PRINTF2( "delay %x%08x to result %x%08x\n",
198
                             (int)(delay >> 32), (int)delay,
199
                             (int)(result >> 32), (int)result );
200
 
201
                // get what it should be in double maths
202
                double delta = factor_other_to_clock * (double)delay;
203
                if ( delta > 1000.0 ) {
204
                    delta = (double)result - delta;
205
                    delta /= (double)result;
206
                    CYG_TEST_CHECK( delta <= +0.01,
207
                          "Proportional overflow in conversion to" );
208
                    CYG_TEST_CHECK( delta >= -0.01,
209
                          "Proportional underflow in conversion to" );
210
                }
211
                else {
212
                    cyg_uint64 lo = (cyg_uint64)(delta); // assume TRUNCATION
213
                    cyg_uint64 hi = lo + 1;
214
                    CYG_TEST_CHECK( hi >= result,
215
                                    "Range overflow in conversion to" );
216
                    CYG_TEST_CHECK( lo <= result,
217
                                    "Range underflow in conversion to" );
218
                }
219
 
220
                // get the converted result
221
                result = Cyg_Clock::convert( delay, &rcv );
222
 
223
                PRINTF2( "delay %x%08x from result %x%08x\n",
224
                             (int)(delay >> 32), (int)delay,
225
                             (int)(result >> 32), (int)result );
226
 
227
                // get what it should be in double maths
228
                delta = factor_clock_to_other * (double)delay;
229
                if ( delta > 1000.0 ) {
230
                    delta = (double)result - delta;
231
                    delta /= (double)result;
232
                    CYG_TEST_CHECK( delta <= +0.01,
233
                          "Proportional overflow in conversion from" );
234
                    CYG_TEST_CHECK( delta >= -0.01,
235
                          "Proportional underflow in conversion from" );
236
                }
237
                else {
238
                    cyg_uint64 lo = (cyg_uint64)(delta); // assume TRUNCATION
239
                    cyg_uint64 hi = lo + 1;
240
                    CYG_TEST_CHECK( hi >= result,
241
                                    "Range overflow in conversion from" );
242
                    CYG_TEST_CHECK( lo <= result,
243
                                    "Range underflow in conversion from" );
244
                }
245
 
246
                if (cyg_test_is_simulator)
247
                    break;
248
            }
249
        }
250
        PRINTF0( "INFO:<%d nS/tick: tested %d values, skipped %d because of overflow>\n",
251
                 ns_tickers[i].ns, lcounter, lskipped );
252
    }
253
 
254
    PRINTF0( "INFO:<tested %d values, total skipped %d because of overflow>\n",
255
             counter, skipped );
256
 
257
    CYG_TEST_PASS_FINISH("ClockCnv OK");
258
}
259
 
260
void clockcnv_main( void )
261
{
262
    CYG_TEST_INIT();
263
    new_thread(entry0, (CYG_ADDRWORD)&thread_obj[0]);
264
    Cyg_Scheduler::start();
265
}
266
 
267
externC void
268
cyg_start( void )
269
{
270
#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
271
    cyg_hal_invoke_constructors();
272
#endif
273
    clockcnv_main();
274
}
275
 
276
#else // def CYGVAR_KERNEL_COUNTERS_CLOCK
277
 
278
externC void
279
cyg_start( void )
280
{
281
    CYG_TEST_INIT();
282
    CYG_TEST_NA( "Kernel real-time clock disabled");
283
}
284
 
285
#endif // def CYGVAR_KERNEL_COUNTERS_CLOCK
286
 
287
// EOF clockcnv.cxx

powered by: WebSVN 2.1.0

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