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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [cortexm/] [stm32/] [var/] [current/] [tests/] [timers.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
/*=============================================================================
2
//
3
//      timers.c
4
//
5
//      Test for STM32 Timers
6
//
7
//=============================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####
9
// -------------------------------------------
10
// This file is part of eCos, the Embedded Configurable Operating System.
11
// Copyright (C) 2008 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):    nickg
43
// Date:         2008-09-11
44
//
45
//####DESCRIPTIONEND####
46
//
47
//===========================================================================*/
48
 
49
#include <pkgconf/system.h>
50
#include <pkgconf/hal.h>
51
 
52
#if defined(CYGPKG_KERNEL)
53
#include <pkgconf/kernel.h>
54
#endif
55
 
56
#include <cyg/infra/testcase.h>
57
 
58
//=============================================================================
59
// Check all required packages and components are present
60
 
61
#if !defined(CYGPKG_KERNEL) || !defined(CYGPKG_KERNEL_API)
62
 
63
#define NA_MSG  "Configuration insufficient"
64
 
65
#endif
66
 
67
//=============================================================================
68
// If everything is present, compile the full test.
69
 
70
#ifndef NA_MSG
71
 
72
#include <cyg/hal/hal_arch.h>
73
#include <cyg/hal/hal_io.h>
74
#include <cyg/hal/hal_if.h>
75
 
76
#include <cyg/kernel/kapi.h>
77
#include <cyg/infra/diag.h>
78
#include <string.h>
79
 
80
//=============================================================================
81
 
82
#define LOOPS      24           // == 2 minutes
83
 
84
#define STACK_SIZE 8000
85
 
86
static int test_stack[(STACK_SIZE/sizeof(int))];
87
static cyg_thread test_thread;
88
static cyg_handle_t main_thread;
89
 
90
//=============================================================================
91
 
92
struct timer
93
{
94
    cyg_uint32          timer;
95
    cyg_uint32          base;
96
    cyg_uint32          vector;
97
    cyg_uint32          priority;
98
    cyg_uint32          interval;
99
 
100
    cyg_uint32          ticks;
101
 
102
    cyg_uint32          preempt[10];
103
 
104
    cyg_uint32          preempt_dsr[10];
105
    cyg_uint32          dsr_count[10];
106
 
107
    cyg_interrupt       interrupt_object;
108
    cyg_handle_t        interrupt_handle;
109
};
110
 
111
struct timer timers[] =
112
{
113
#if 0
114
    { 1, CYGHWR_HAL_STM32_TIM1, CYGNUM_HAL_INTERRUPT_TIM1_UP, 0x20,    1000 },
115
#elif 1
116
    { 1, CYGHWR_HAL_STM32_TIM1, CYGNUM_HAL_INTERRUPT_TIM1_UP, 0x20,     127 },
117
    { 2, CYGHWR_HAL_STM32_TIM2, CYGNUM_HAL_INTERRUPT_TIM2,    0x30,     355 },
118
    { 3, CYGHWR_HAL_STM32_TIM3, CYGNUM_HAL_INTERRUPT_TIM3,    0x40,     731 },
119
    { 4, CYGHWR_HAL_STM32_TIM4, CYGNUM_HAL_INTERRUPT_TIM4,    0x50,     999 },
120
    { 5, CYGHWR_HAL_STM32_TIM5, CYGNUM_HAL_INTERRUPT_TIM5,    0x60,    1453 },
121
    { 6, CYGHWR_HAL_STM32_TIM6, CYGNUM_HAL_INTERRUPT_TIM6,    0x70,    1931 },
122
    { 7, CYGHWR_HAL_STM32_TIM7, CYGNUM_HAL_INTERRUPT_TIM7,    0x80,    2011 },
123
    { 8, CYGHWR_HAL_STM32_TIM8, CYGNUM_HAL_INTERRUPT_TIM8_UP, 0x90,    2345 },
124
#endif
125
    { 0, 0, 0, 0 }
126
};
127
 
128
//=============================================================================
129
 
130
volatile cyg_uint32 ticks = 0;
131
volatile cyg_uint32 nesting = 0;
132
volatile cyg_uint32 max_nesting = 0;
133
volatile cyg_uint32 max_nesting_seen = 0;
134
volatile cyg_uint32 current = 0;
135
volatile cyg_uint32 in_dsr = 0;
136
 
137
//=============================================================================
138
 
139
__externC cyg_uint32 hal_stm32_pclk1;
140
__externC cyg_uint32 hal_stm32_pclk2;
141
 
142
void init_timer( cyg_uint32 base, cyg_uint32 interval )
143
{
144
    cyg_uint32 period = hal_stm32_pclk1;
145
 
146
    if( base == CYGHWR_HAL_STM32_TIM1 || base == CYGHWR_HAL_STM32_TIM8 )
147
    {
148
        period = hal_stm32_pclk2;
149
        if( CYGHWR_HAL_CORTEXM_STM32_CLOCK_PCLK2_DIV != 1 )
150
            period *= 2;
151
    }
152
    else
153
    {
154
        if( CYGHWR_HAL_CORTEXM_STM32_CLOCK_PCLK1_DIV != 1 )
155
            period *= 2;
156
    }
157
 
158
    period = period / 1000000;
159
 
160
    HAL_WRITE_UINT32(base+CYGHWR_HAL_STM32_TIM_PSC, period-1 );
161
 
162
    HAL_WRITE_UINT32(base+CYGHWR_HAL_STM32_TIM_CR2, 0 );
163
 
164
    HAL_WRITE_UINT32(base+CYGHWR_HAL_STM32_TIM_DIER, CYGHWR_HAL_STM32_TIM_DIER_UIE );
165
 
166
    HAL_WRITE_UINT32(base+CYGHWR_HAL_STM32_TIM_ARR, interval );
167
 
168
    HAL_WRITE_UINT32(base+CYGHWR_HAL_STM32_TIM_CR1, CYGHWR_HAL_STM32_TIM_CR1_CEN);
169
}
170
 
171
//=============================================================================
172
 
173
cyg_uint32 timer_isr( cyg_uint32 vector, CYG_ADDRWORD data )
174
{
175
    struct timer *t = (struct timer *)data;
176
    cyg_uint32 preempt = current;
177
    CYG_ADDRWORD base = t->base;
178
    cyg_uint32 cnt;
179
 
180
    current = t->timer;
181
    t->ticks++;
182
    ticks++;
183
    t->preempt[preempt]++;
184
    nesting++;
185
 
186
    // Count only first ISR to preempt a DSR
187
    if( preempt == 0 )
188
        t->preempt_dsr[in_dsr]++;
189
 
190
    HAL_WRITE_UINT32(t->base+CYGHWR_HAL_STM32_TIM_SR, 0 );
191
 
192
    if( nesting > max_nesting )
193
        max_nesting = nesting;
194
 
195
    // Loiter here for a proportion of the timer interval to give
196
    // other timers the chance to preempt us.
197
    do
198
    {
199
        HAL_READ_UINT32( base+CYGHWR_HAL_STM32_TIM_CNT, cnt );
200
    } while( cnt < t->interval/10 );
201
 
202
    nesting--;
203
    current = preempt;
204
 
205
    if( (t->ticks % 10) == 0 )
206
        return 3;
207
    else
208
        return 1;
209
}
210
 
211
//=============================================================================
212
 
213
void timer_dsr( cyg_uint32 vector, cyg_uint32 count, CYG_ADDRWORD data )
214
{
215
    struct timer *t = (struct timer *)data;
216
    int i;
217
 
218
    in_dsr = t->timer;
219
 
220
    if( count >= 8 )
221
        count = 8;
222
 
223
    t->dsr_count[count]++;
224
 
225
    // Loiter for a while
226
    for( i = 0; i < t->interval/10; i++)
227
        continue;
228
 
229
    in_dsr = 0;
230
}
231
 
232
//=============================================================================
233
 
234
void
235
timers_test(cyg_addrword_t data)
236
{
237
    int loops = LOOPS;
238
    int i;
239
    CYG_INTERRUPT_STATE istate;
240
 
241
    CYG_TEST_INIT();
242
 
243
    CYG_TEST_INFO("Start Timers test");
244
 
245
    for( i = 0; timers[i].timer != 0; i++ )
246
    {
247
        struct timer *t = &timers[i];
248
 
249
        init_timer( t->base, t->interval );
250
 
251
        cyg_interrupt_create( t->vector,
252
                              t->priority,
253
                              (cyg_addrword_t)t,
254
                              timer_isr,
255
                              timer_dsr,
256
                              &t->interrupt_handle,
257
                              &t->interrupt_object
258
            );
259
 
260
        cyg_interrupt_attach( t->interrupt_handle );
261
        cyg_interrupt_unmask( t->vector );
262
 
263
    }
264
 
265
    while( loops-- )
266
    {
267
        int j;
268
 
269
        // 5 second delay
270
        cyg_thread_delay( 5*100 );
271
 
272
        // Disable interrupts while we print details, otherwise it
273
        // comes out very slowly.
274
        HAL_DISABLE_INTERRUPTS( istate );
275
 
276
        if( max_nesting > max_nesting_seen )
277
            max_nesting_seen = max_nesting;
278
 
279
        diag_printf("\nISRs max_nesting %d max_nesting_seen %d\n", max_nesting, max_nesting_seen );
280
        max_nesting = 0;
281
 
282
        diag_printf(" T      Ticks ");
283
 
284
        for( j = 0; j < 9; j++ )
285
            diag_printf("%9d ", j );
286
        diag_printf("\n");
287
 
288
        for( i = 0; timers[i].timer != 0; i++ )
289
        {
290
            struct timer *t = &timers[i];
291
 
292
            diag_printf("%2d: %9d ", t->timer, t->ticks );
293
 
294
            for( j = 0; j < 9; j++ )
295
                diag_printf("%9d ", t->preempt[j] );
296
            diag_printf("\n");
297
 
298
        }
299
 
300
        diag_printf("DSRs\n");
301
 
302
        diag_printf(" T:           ");
303
 
304
        for( j = 0; j < 9; j++ )
305
            diag_printf("%9d ", j );
306
        diag_printf("\n");
307
 
308
        for( i = 0; timers[i].timer != 0; i++ )
309
        {
310
            struct timer *t = &timers[i];
311
 
312
            diag_printf("%2d:  preempt: ", t->timer);
313
 
314
            for( j = 0; j < 9; j++ )
315
                diag_printf("%9d ", t->preempt_dsr[j] );
316
            diag_printf("\n");
317
 
318
            diag_printf("       count: ");
319
 
320
            for( j = 0; j < 9; j++ )
321
                diag_printf("%9d ", t->dsr_count[j] );
322
            diag_printf("\n");
323
        }
324
 
325
        HAL_RESTORE_INTERRUPTS( istate );
326
    }
327
 
328
    CYG_TEST_PASS_FINISH("Timers test");
329
}
330
 
331
//=============================================================================
332
 
333
void cyg_user_start(void)
334
{
335
    cyg_thread_create(0,                // Priority
336
                      timers_test,
337
                      0,
338
                      "timers test",    // Name
339
                      test_stack,       // Stack
340
                      STACK_SIZE,       // Size
341
                      &main_thread,     // Handle
342
                      &test_thread // Thread data structure
343
        );
344
    cyg_thread_resume( main_thread);
345
}
346
 
347
//=============================================================================
348
// Print a message if we cannot run
349
 
350
#else // NA_MSG
351
 
352
void cyg_user_start(void)
353
{
354
    CYG_TEST_NA(NA_MSG);
355
}
356
 
357
#endif // NA_MSG
358
 
359
//=============================================================================
360
/* EOF timers.c */

powered by: WebSVN 2.1.0

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