comparison packages/devs/eth/arm/ebsa285/current/tests/test_net_realtime.h @ 88:afdeb44241de ecos-sw-2000-05-12

Merge from eCos master repository on 2000-05-12-07:47:04-BST
author jlarmour
date Fri, 12 May 2000 17:53:32 +0000
parents
children 70190fa0fe10
comparison
equal deleted inserted replaced
87:008177d90c43 88:afdeb44241de
1 #ifndef CYGONCE_DEVS_ETH_ARM_EBSA285_TESTS_TEST_NET_REALTIME_H
2 #define CYGONCE_DEVS_ETH_ARM_EBSA285_TESTS_TEST_NET_REALTIME_H
3
4 /*==========================================================================
5 //
6 // test_net_realtime.h
7 //
8 // Auxiliary test header file
9 // Provide a thread that runs on EBSA only, which verifies that
10 // realtime characteristics are preserved.
11 //
12 //==========================================================================
13 //####COPYRIGHTBEGIN####
14 //
15 // -------------------------------------------
16 // The contents of this file are subject to the Red Hat eCos Public License
17 // Version 1.1 (the "License"); you may not use this file except in
18 // compliance with the License. You may obtain a copy of the License at
19 // http://www.redhat.com/
20 //
21 // Software distributed under the License is distributed on an "AS IS"
22 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
23 // License for the specific language governing rights and limitations under
24 // the License.
25 //
26 // The Original Code is eCos - Embedded Configurable Operating System,
27 // released September 30, 1998.
28 //
29 // The Initial Developer of the Original Code is Red Hat.
30 // Portions created by Red Hat are
31 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
32 // All Rights Reserved.
33 // -------------------------------------------
34 //
35 //####COPYRIGHTEND####
36 //==========================================================================
37 //#####DESCRIPTIONBEGIN####
38 //
39 // Author(s): hmt
40 // Contributors: hmt
41 // Date: 2000-05-03
42 // Description:
43 //
44 //####DESCRIPTIONEND####
45 */
46
47 // This file rather assumes that the network is in use, and that therefore
48 // there is also a kernel, and so on....
49
50 #include <cyg/kernel/kapi.h> // Thread API
51
52 #include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
53 #include <cyg/hal/hal_intr.h> // Interrupt names
54 #include <cyg/hal/hal_ebsa285.h> // Hardware definitions
55
56 // The EBSA has 4 hardware timers; timer 3 is the kernel's realtime clock
57 // because it is connected to a separate, indepenent 3.68MHz signal; timer
58 // 4 can be used as a watchdog. So we have timers 1 and 2 to use.
59 // Timers 1 and 2 have an input clock of 50MHz on fclk_in.
60 // Timer 2 should be initialized for periodic interrupts per 500uS.
61 // Timer 1 should be initialized for a one-shot interrupt after 1mS (1000uS).
62 //
63 // Timer 2's ISR examines the state of timer 1; if it has expired, the test
64 // has failed. 7 out of 8 hits, timer 1 is reinitialized for the 1mS; on
65 // the 8th event, timer1 is set for 2mS. The next timer 2 event calls its
66 // DSR, which in turn signals a semaphore which awakens a real task, which
67 // again checks and re-initializes timer1 in the same way.
68 //
69 // All this ensures that interrupts are never delayed by more than 500uS,
70 // and that signalling a real task always takes less than 1500uS.
71 //
72 // This system, once activated, will run non-intrusively along with all
73 // networking tests.
74 //
75 // Special care (aka a hack) may be needed to make it work with the
76 // diagnostic channel; that disables interrupts typically for
77 // 100[characters] * 8[bits/byte] / 38400[Baud] [Seconds] = 20mS.
78
79 // Use the fclk_in divided-by 256 mode:
80 #define TNR_TIMER1_PERIOD_1mS ((50 * 1000) >>8)
81 #define TNR_TIMER1_PERIOD_2mS ((50 * 1000 * 2) >>8)
82 #define TNR_TIMER2_PERIOD_500uS ((50 * 500) >>8)
83
84 #define TNR_TIMER1_INIT (0x88) // Enabled, free running, fclk_in/256
85 #define TNR_TIMER2_INIT (0xc8) // Enabled, periodic, fclk_in/256
86
87 // This way, if timer1 is > TNR_TIMER1_PERIOD_2mS, then we know it has
88 // wrapped; its full range is 85 seconds, one would hope to get back in
89 // that time!
90
91 static volatile int tnr_active = 0;
92 static volatile int tnr_t2_counter = 0;
93
94 static cyg_sem_t tnr_sema;
95
96 static char tnr_stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
97 static cyg_thread tnr_thread_data;
98 static cyg_handle_t tnr_thread_handle;
99
100 static cyg_interrupt tnr_t1_intr, tnr_t2_intr;
101 static cyg_handle_t tnr_t1_inth, tnr_t2_inth;
102
103
104
105 static cyg_uint32 tnr_timer1_isr(cyg_vector_t vector, cyg_addrword_t data)
106 {
107 if ( tnr_active )
108 CYG_TEST_FAIL( "test_net_realtime: Timer1 fired" );
109
110 *SA110_TIMER1_CLEAR = 0; // Clear any pending interrupt (Data: don't care)
111 HAL_INTERRUPT_ACKNOWLEDGE( CYGNUM_HAL_INTERRUPT_TIMER_1 );
112
113 return CYG_ISR_HANDLED;
114 }
115
116 static cyg_uint32 tnr_timer2_isr(cyg_vector_t vector, cyg_addrword_t data)
117 {
118 *SA110_TIMER2_CLEAR = 0; // Clear any pending interrupt (Data: don't care)
119 HAL_INTERRUPT_ACKNOWLEDGE( CYGNUM_HAL_INTERRUPT_TIMER_2 );
120
121 if ( tnr_active ) {
122 if ( (*SA110_TIMER1_VALUE) > (4 * TNR_TIMER1_PERIOD_1mS) ) {
123 // Then it has wrapped around, bad bad bad
124 CYG_TEST_FAIL( "tnr_timer2_isr: Timer1 wrapped" );
125 }
126 }
127 tnr_t2_counter++;
128 // We go though each of the following states in turn:
129 switch ( tnr_t2_counter & 7 ) {
130 case 0:
131 // Then this is an 8th event:
132 *SA110_TIMER1_LOAD = TNR_TIMER1_PERIOD_2mS;
133 return CYG_ISR_HANDLED;
134 case 1:
135 return CYG_ISR_CALL_DSR; // See how long to call a DSR &c..
136 // without resetting timer1: 1500uS left now
137 default:
138 // Reset timer1 again. By doing this in time every time it should
139 // never fire.
140 *SA110_TIMER1_LOAD = TNR_TIMER1_PERIOD_1mS;
141 }
142 return CYG_ISR_HANDLED;
143 }
144
145 static void tnr_timer2_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
146 {
147 if ( CYGNUM_HAL_INTERRUPT_TIMER_2 != vector )
148 CYG_TEST_FAIL( "tnr_timer2_dsr: Bad vector" );
149
150 cyg_semaphore_post( &tnr_sema );
151 }
152
153 static void tnr_timer2_service_thread( cyg_addrword_t param )
154 {
155 while (1) {
156 cyg_semaphore_wait( &tnr_sema );
157 if ( tnr_active ) {
158 if ( (*SA110_TIMER1_VALUE) > (4 * TNR_TIMER1_PERIOD_1mS) ) {
159 // Then it has wrapped around, bad bad bad
160 CYG_TEST_FAIL( "tnr_timer2_service_thread: Timer1 wrapped" );
161 }
162 }
163 // Reset timer1 again. By doing this in time every time it should
164 // never fire.
165 *SA110_TIMER1_LOAD = TNR_TIMER1_PERIOD_1mS;
166 }
167 }
168
169
170 static void tnr_init( void )
171 {
172 // init the semaphore
173 cyg_semaphore_init( &tnr_sema, 0 );
174
175 // create and start the thread
176 cyg_thread_create(2, // Priority - just a number
177 tnr_timer2_service_thread,
178 0, // entry parameter
179 "Test Net Realtime tnr_timer2_service_thread",
180 &tnr_stack[0], // Stack
181 sizeof(tnr_stack), // Size
182 &tnr_thread_handle, // Handle
183 &tnr_thread_data // Thread data structure
184 );
185 cyg_thread_resume( tnr_thread_handle );
186
187 // set up and attach the interrupts et al...
188 cyg_interrupt_create(
189 CYGNUM_HAL_INTERRUPT_TIMER_2, /* Vector to attach to */
190 0, /* Queue priority */
191 0, /* Data pointer */
192 tnr_timer2_isr, /* Interrupt Service Routine */
193 tnr_timer2_dsr, /* Deferred Service Routine */
194 &tnr_t2_inth, /* returned handle */
195 &tnr_t2_intr /* put interrupt here */
196 );
197
198 cyg_interrupt_create(
199 CYGNUM_HAL_INTERRUPT_TIMER_1, /* Vector to attach to */
200 0, /* Queue priority */
201 0, /* Data pointer */
202 tnr_timer1_isr, /* Interrupt Service Routine */
203 tnr_timer2_dsr, /* re-use! */ /* Deferred Service Routine */
204 &tnr_t1_inth, /* returned handle */
205 &tnr_t1_intr /* put interrupt here */
206 );
207
208 cyg_interrupt_attach( tnr_t1_inth );
209 cyg_interrupt_attach( tnr_t2_inth );
210
211 *SA110_TIMER1_CONTROL = 0; // Disable while we are setting up
212 *SA110_TIMER1_LOAD = TNR_TIMER1_PERIOD_2mS;
213 *SA110_TIMER1_CLEAR = 0; // Clear any pending interrupt
214 *SA110_TIMER1_CONTROL = TNR_TIMER1_INIT;
215 *SA110_TIMER1_CLEAR = 0; // Clear any pending interrupt again
216
217 *SA110_TIMER2_CONTROL = 0; // Disable while we are setting up
218 *SA110_TIMER2_LOAD = TNR_TIMER2_PERIOD_500uS;
219 *SA110_TIMER2_CLEAR = 0; // Clear any pending interrupt
220 *SA110_TIMER2_CONTROL = TNR_TIMER2_INIT;
221 *SA110_TIMER2_CLEAR = 0; // Clear any pending interrupt again
222
223 cyg_interrupt_unmask( CYGNUM_HAL_INTERRUPT_TIMER_2 );
224 cyg_interrupt_unmask( CYGNUM_HAL_INTERRUPT_TIMER_1 );
225 }
226
227 #endif /* ifndef CYGONCE_DEVS_ETH_ARM_EBSA285_TESTS_TEST_NET_REALTIME_H */
228
229 /* EOF test_net_realtime.h */