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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [arm/] [xscale/] [iq80310/] [v2_0/] [src/] [diag/] [external_timer.c] - Blame information for rev 565

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

Line No. Rev Author Line
1 27 unneback
//=============================================================================
2
//
3
//      external_timer.c - Cyclone Diagnostics
4
//
5
//=============================================================================
6
//####ECOSGPLCOPYRIGHTBEGIN####
7
// -------------------------------------------
8
// This file is part of eCos, the Embedded Configurable Operating System.
9
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
10
//
11
// eCos is free software; you can redistribute it and/or modify it under
12
// the terms of the GNU General Public License as published by the Free
13
// Software Foundation; either version 2 or (at your option) any later version.
14
//
15
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
16
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
17
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18
// for more details.
19
//
20
// You should have received a copy of the GNU General Public License along
21
// with eCos; if not, write to the Free Software Foundation, Inc.,
22
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
23
//
24
// As a special exception, if other files instantiate templates or use macros
25
// or inline functions from this file, or you compile this file and link it
26
// with other works to produce a work based on this file, this file does not
27
// by itself cause the resulting work to be covered by the GNU General Public
28
// License. However the source code for this file must still be made available
29
// in accordance with section (3) of the GNU General Public License.
30
//
31
// This exception does not invalidate any other reasons why a work based on
32
// this file might be covered by the GNU General Public License.
33
//
34
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
35
// at http://sources.redhat.com/ecos/ecos-license/
36
// -------------------------------------------
37
//####ECOSGPLCOPYRIGHTEND####
38
//=============================================================================
39
//#####DESCRIPTIONBEGIN####
40
//
41
// Author(s):   Scott Coulter, Jeff Frazier, Eric Breeden
42
// Contributors:
43
// Date:        2001-01-25
44
// Purpose:     
45
// Description: 
46
//
47
//####DESCRIPTIONEND####
48
//
49
//===========================================================================*/
50
 
51
#include <redboot.h>
52
#include <cyg/hal/hal_iop310.h>        // Hardware definitions
53
#include <cyg/hal/hal_intr.h>          // Interrupt names
54
#include "iq80310.h"
55
#include "test_menu.h"
56
 
57
extern int enable_external_interrupt (int int_id);
58
extern int disable_external_interrupt (int int_id);
59
extern int isr_connect(int int_num, void (*handler)(int), int arg);
60
extern int isr_disconnect(int int_num);
61
extern char xgetchar(void);
62
 
63
volatile int timer_ticks;
64
 
65
/* interrupt handler for the PAL-based external timer */
66
void ext_timer_handler (int arg)
67
{
68
    /* increment tick counter */
69
    timer_ticks++;
70
 
71
    /* to clear the timer interrupt, clear the timer interrupt
72
       enable, then re-set the int. enable bit */
73
    /* 01/05/01 jwf */
74
    /*  _restart_tmr(); */
75
 
76
    EXT_TIMER_INT_DISAB();
77
    EXT_TIMER_INT_ENAB();
78
 
79
    return;
80
}
81
 
82
 
83
/* timer count must be written 8 bits at a time */
84
void write_timer_count (UINT32 count)
85
{
86
    UINT8 cnt_word;
87
 
88
    /* first ensure that there are only 22 bits of count data */
89
    count &= 0x003fffff;
90
 
91
    /* grab least significant 8 bits of timer value */
92
    cnt_word = (UINT8)(count & 0xff);
93
    *TIMER_LA0_REG_ADDR = cnt_word;
94
 
95
    /* grab next 8 bits of timer value */
96
    count = (count >> 8);
97
    cnt_word = (UINT8)(count & 0xff);
98
    *TIMER_LA1_REG_ADDR = cnt_word;
99
 
100
    /* grab last 6 bits of timer value */
101
    count = (count >> 8);
102
    cnt_word = (UINT8)(count & 0x3f);
103
    *TIMER_LA2_REG_ADDR = cnt_word;
104
 
105
    return;
106
}
107
 
108
/* timer must be read 6 bits at a time */
109
UINT32 read_timer_count (void)
110
{
111
    UINT8 timer_cnt0, timer_cnt1, timer_cnt2, timer_cnt3;
112
    UINT8 timer_byte0, timer_byte1, timer_byte2;
113
    UINT32 count;
114
 
115
    /* first read latches the count */
116
    timer_cnt0 = (*TIMER_LA0_REG_ADDR & TIMER_COUNT_MASK);
117
    timer_cnt1 = (*TIMER_LA1_REG_ADDR & TIMER_COUNT_MASK);
118
    timer_cnt2 = (*TIMER_LA2_REG_ADDR & TIMER_COUNT_MASK);
119
    timer_cnt3 = (*TIMER_LA3_REG_ADDR & 0xf);   /* only 4 bits in most sig. */
120
 
121
    /* now build up the count value */
122
    timer_byte0 = (((timer_cnt0 & 0x20) >> 1) | (timer_cnt0 & 0x1f));
123
    timer_byte1 = (((timer_cnt1 & 0x20) >> 1) | (timer_cnt1 & 0x1f));
124
    timer_byte2 = (((timer_cnt2 & 0x20) >> 1) | (timer_cnt2 & 0x1f));
125
 
126
    count = ((timer_cnt3 << 18) | (timer_byte2 << 12) | (timer_byte1 << 6) |
127
             timer_byte0);
128
 
129
    return (count);
130
}
131
 
132
 
133
/* 12/18/00 jwf */
134
/* This test reads the timer la0-la3 registers on the fly while an up count is in progress. */
135
void counter_test (void)
136
{
137
    /* ff max, b0-b7, b0-b7 contain timer load data */
138
    unsigned char TmrLa0Write=0xff;
139
    /* ff max, b8-b15, b0-b7 contain timer load data  */
140
    unsigned char TmrLa1Write=0xff;
141
    /* 3f max, b16-b21, b0-b5 contain timer load data  */
142
    unsigned char TmrLa2Write=0x3f;
143
    unsigned char TmrLa3Write=0x00; /* x - don't care */
144
    unsigned long int TmrLa0Read=0;
145
    unsigned long int TmrLa1Read=0;
146
    unsigned long int TmrLa2Read=0;
147
    unsigned long int TmrLa3Read=0;
148
    unsigned long int temp3=0;
149
    unsigned long int temp4=0;
150
    unsigned long int CntInit=0;
151
    unsigned long int CurrentCount;
152
    unsigned long int LastCount = 0;
153
    unsigned long int LastLastCount = 0;
154
    char Error = FALSE;
155
    unsigned long int sample;
156
    unsigned long int index;
157
    const int MAX_N_PASSES = 10; /* N times the counter shall wrap around */
158
    /* N samples to cover the full range of count,
159
       0x3fffff/0x40 = 0xffff <--> 65535d, use 65536 to guarantee
160
       a counter wrap around occurs */
161
    const unsigned long int MAX_N_SAMPLES = 65536;
162
    /* allocate 4 bytes per sample for a 0x0 - 0x3fffff count range to
163
       hold contents of registers LA0-LA3 */
164
    unsigned long int MAX_N_SIZE = MAX_N_PASSES * MAX_N_SAMPLES * 4;
165
    unsigned char *data;
166
 
167
    // Arbitrarily pick a spot in memory.
168
    // RedBoot won't ever use more than 1MB.
169
    data = (unsigned char *) MEMBASE_DRAM + (1*1024*1024);
170
 
171
    if (data != NULL) {
172
        printf("Allocated %d bytes\n", MAX_N_SIZE);
173
 
174
        /* load control data to disable timer enable b0=0 and timer disable
175
           interrupt b1=0, write to timer enable port */
176
        EXT_TIMER_INT_DISAB();
177
        EXT_TIMER_CNT_DISAB();
178
 
179
        /* write timer la0 port count data */
180
        *TIMER_LA0_REG_ADDR = TmrLa0Write;
181
 
182
        /* write timer la1 port count data */
183
        *TIMER_LA1_REG_ADDR = TmrLa1Write;
184
 
185
        /*  write timer la2 port count data */
186
        *TIMER_LA2_REG_ADDR = TmrLa2Write;
187
 
188
        /*  write timer la3 port count data */
189
        *TIMER_LA3_REG_ADDR = TmrLa3Write;
190
 
191
        CntInit = TmrLa0Write + (TmrLa1Write << 8 ) + (TmrLa2Write << 16 );
192
 
193
        printf("Timer load data = 0x%x\n", CntInit );
194
 
195
        printf("Reading Timer registers LA0-LA3 on the fly...\n");
196
 
197
        /* load control data to enable timer counter and write control data
198
           to start the counter */
199
        EXT_TIMER_CNT_ENAB();
200
 
201
        /* sample the timer counter on the fly and store LA0-3 register
202
           contents in an array */
203
        /* read LSB register first to latch 22 bits data into four la
204
           registers */
205
        for (sample=0, index=0; sample < (MAX_N_PASSES * MAX_N_SAMPLES); sample++, index += 4) {
206
            /* bits 0 1 2 3 4 6 contain count data b0-b5 */
207
            data[index]   = *TIMER_LA0_REG_ADDR;
208
            /* bits 0 1 2 3 4 6 contain count data b6-b11 */
209
            data[index+1] = *TIMER_LA1_REG_ADDR;
210
            /* bits 0 1 2 3 4 6 contain count data b12-b17 */
211
            data[index+2] = *TIMER_LA2_REG_ADDR;
212
            /* bits 0 1 2 3 contain count data b18-b21 */
213
            data[index+3] = *TIMER_LA3_REG_ADDR;
214
        }
215
 
216
        printf("Checking for errors...\n" );
217
 
218
        /* Assemble and check recorded register data for errors */
219
        for (sample=0, index=0; sample < (MAX_N_PASSES * MAX_N_SAMPLES) ;sample++, index += 4) {
220
            /* Assembles counter data that was read on the fly */
221
            /* xbxbbbbb */
222
            /* 01000000 = 0x40 */
223
            /* 00011111 = 0x1F */
224
            data[index] &= 0x7f;        /* mask all unused bits */
225
            temp3=data[index];
226
            temp4=data[index];
227
            temp3 &= 0x40;              /* isolate bit 6 */
228
            temp3 = temp3 >> 1;         /* shift bit 6 to bit 5 */
229
            temp4 &= 0x1f;              /* isolate bits 0-4 */
230
            TmrLa0Read = temp3 + temp4;
231
 
232
            data[index+1] &= 0x7f;      /* mask all unused bits */
233
            temp3=data[index+1];
234
            temp4=data[index+1];
235
            temp3 &= 0x40;              /* isolate bit 6 */
236
            temp3 = temp3 >> 1;         /* shift bit 6 to bit 5 */
237
            temp4 &= 0x1f;              /* isolate bits 0-4 */
238
            TmrLa1Read = temp3 + temp4;
239
 
240
            data[index+2] &= 0x7f;      /* mask all unused bits */
241
            temp3=data[index+2];
242
            temp4=data[index+2];
243
            temp3 &= 0x40;              /* isolate bit 6 */
244
            temp3 = temp3 >> 1;         /* shift bit 6 to bit 5 */
245
            temp4 &= 0x1f;              /* isolate bits 0-4 */
246
            TmrLa2Read = temp3 + temp4;
247
 
248
            data[index+3] &= 0x0f;      /* mask all unused bits */
249
            TmrLa3Read = data[index+3];
250
 
251
            /* sum timer count data */
252
            CurrentCount = TmrLa0Read + (TmrLa1Read << 6)
253
                + (TmrLa2Read << 12) + (TmrLa3Read << 18);
254
 
255
            if (sample == 0) {
256
                LastLastCount = 0;
257
                LastCount = CurrentCount;
258
            }
259
 
260
            if (sample == 1) {
261
                LastLastCount = LastCount;
262
                LastCount = CurrentCount;
263
            }
264
 
265
            /* check for data anomaly, is count value read 2 samples ago
266
               greater than the count value read 1 sample ago */
267
            if (sample > 1) {
268
                /* print error value (LastCount) positioned in between the
269
                   previous and current values */
270
                if (LastLastCount > LastCount && CurrentCount > LastLastCount) {
271
                    /* show error only, do not show a counter wrap around
272
                       reading, print error value (LastCount) positioned in
273
                       between the previous and current values */
274
                    printf("0x%x 0x%x 0x%x \n", LastLastCount, LastCount, CurrentCount );
275
                    Error = TRUE;       /* set flag to error condition */
276
                }
277
                LastLastCount = LastCount;
278
                LastCount = CurrentCount;
279
            }
280
        }
281
        /* load control data to stop timer and reset timer interrupt */
282
        EXT_TIMER_CNT_DISAB();
283
    } else
284
        printf( "Cannot allocate memory.\n" );
285
 
286
    if (Error == TRUE)
287
        printf("Timer LA0-3 register read test FAILED.\n");
288
    else
289
        printf("Timer LA0-3 register read test PASSED.\n");
290
}
291
 
292
 
293
/* initialize timer for diagnostic use */
294
void init_external_timer(void)
295
{
296
#if 0
297
    /* disable timer in case it was running */
298
    EXT_TIMER_INT_DISAB();
299
    EXT_TIMER_CNT_DISAB();
300
 
301
    timer_ticks = 0;
302
 
303
    /* connect the timer ISR */
304
    isr_connect (TIMER_INT_ID, ext_timer_handler, 0);
305
 
306
    /* enable the external interrupt */
307
    if (enable_external_interrupt(TIMER_INT_ID) != OK)
308
        printf("ERROR enabling EXT TIMER interrupt!\n");
309
#else
310
    hal_clock_initialize(CYGNUM_HAL_RTC_PERIOD);
311
#endif
312
 
313
}
314
 
315
 
316
/* uninitialize timer after diagnostics */
317
void uninit_external_timer(void)
318
{
319
#if 0
320
    /* disable timer */
321
    EXT_TIMER_INT_DISAB();
322
    EXT_TIMER_CNT_DISAB();
323
 
324
    /* disable and disconnect timer interrupts */
325
    disable_external_interrupt(TIMER_INT_ID);
326
    isr_disconnect (TIMER_INT_ID);
327
#endif
328
}
329
 
330
 
331
/* 02/02/01 jwf */
332
/* delay_ms - delay specified number of milliseconds */
333
void delay_ms(int num_ms)
334
{
335
    HAL_DELAY_US(num_ms * 1000);
336
}
337
 
338
 
339
/* test the 32 bit timer inside the CPLD, U17 */
340
void timer_test (MENU_ARG arg)
341
{
342
    volatile int i;
343
    UINT32 count;
344
 
345
    /*****  Perform 10 second count at 100 ticks/sec ****/
346
 
347
    /* for the test we will setup the timer to generate a 10msec tick */
348
    count = EXT_TIMER_10MSEC_COUNT;
349
 
350
    /* write the initial count to the timer */
351
    write_timer_count (count);
352
 
353
    /* enable the interrupt at the timer */
354
    EXT_TIMER_INT_ENAB();
355
 
356
    /* enable the timer to count */
357
    EXT_TIMER_CNT_ENAB();
358
 
359
    printf ("Counting at %d Ticks Per Second.\n", TICKS_10MSEC);
360
    printf ("Numbers should appear on 1 second increments...\n");
361
 
362
    for (i = 0; i < 10; i++) {
363
        while (timer_ticks < TICKS_10MSEC)
364
            ;
365
        printf ("%d ", i);
366
        timer_ticks = 0;
367
    }
368
 
369
    printf ("\nDone\n\n");
370
 
371
    /* disable timer */
372
    EXT_TIMER_INT_DISAB();
373
    EXT_TIMER_CNT_DISAB();
374
 
375
 
376
    /*****  Perform 10 second count at 200 ticks/sec ****/
377
 
378
    count = EXT_TIMER_5MSEC_COUNT;
379
    write_timer_count (count);
380
 
381
    timer_ticks = 0;
382
 
383
    /* enable the interrupt at the timer */
384
    EXT_TIMER_INT_ENAB();
385
 
386
    /* enable the timer to count */
387
    EXT_TIMER_CNT_ENAB();
388
 
389
    printf ("Counting at %d Ticks Per Second.\n", TICKS_5MSEC);
390
    printf ("Numbers should appear on 1 second increments...\n");
391
 
392
    for (i = 0; i < 10; i++) {
393
        while (timer_ticks < TICKS_5MSEC)
394
            ;
395
        printf ("%d ", i);
396
        timer_ticks = 0;
397
    }
398
 
399
    printf ("\nDone\n\n");
400
 
401
    /* disable timer */
402
    EXT_TIMER_INT_DISAB();
403
    EXT_TIMER_CNT_DISAB();
404
 
405
    /* 12/18/00 jwf */
406
    uninit_external_timer();    /* disable interrupt */
407
    counter_test();
408
    init_external_timer();              /* enable interrupt */
409
 
410
    printf("\nExternal Timer Test Done\n");
411
 
412
    /* 12/18/00 jwf */
413
    printf("\n\nStrike <CR> to exit this test." );
414
    while (xgetchar() != 0x0d);
415
 
416
    return;
417
 
418
} /* end timer_test() */
419
 
420
 

powered by: WebSVN 2.1.0

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