comparison packages/hal/mn10300/stb/current/src/hal_diag.c @ 76:435cced73e2f ecos-v1_3_1-release

eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
author jlarmour
date Tue, 28 Mar 2000 14:10:45 +0000
parents
children 391299f9e541
comparison
equal deleted inserted replaced
75:41bf073c0c32 76:435cced73e2f
1 /*=============================================================================
2 //
3 // hal_diag.c
4 //
5 // HAL diagnostic output code
6 //
7 //=============================================================================
8 //####COPYRIGHTBEGIN####
9 //
10 // -------------------------------------------
11 // The contents of this file are subject to the Red Hat eCos Public License
12 // Version 1.1 (the "License"); you may not use this file except in
13 // compliance with the License. You may obtain a copy of the License at
14 // http://www.redhat.com/
15 //
16 // Software distributed under the License is distributed on an "AS IS"
17 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
18 // License for the specific language governing rights and limitations under
19 // the License.
20 //
21 // The Original Code is eCos - Embedded Configurable Operating System,
22 // released September 30, 1998.
23 //
24 // The Initial Developer of the Original Code is Red Hat.
25 // Portions created by Red Hat are
26 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
27 // All Rights Reserved.
28 // -------------------------------------------
29 //
30 //####COPYRIGHTEND####
31 //=============================================================================
32 //#####DESCRIPTIONBEGIN####
33 //
34 // Author(s): nickg
35 // Contributors: nickg
36 // Date: 1998-03-02
37 // Purpose: HAL diagnostic output
38 // Description: Implementations of HAL diagnostic output support.
39 //
40 //####DESCRIPTIONEND####
41 //
42 //===========================================================================*/
43
44 #include <pkgconf/hal.h>
45
46 #include <cyg/infra/cyg_type.h> // base types
47 #include <cyg/infra/cyg_trac.h> // tracing macros
48 #include <cyg/infra/cyg_ass.h> // assertion macros
49
50 #include <cyg/hal/hal_diag.h>
51 #include <cyg/hal/hal_intr.h>
52
53 /*---------------------------------------------------------------------------*/
54 /* Select default diag channel to use */
55
56 //#define CYG_KERNEL_DIAG_ROMART
57 //#define CYG_KERNEL_DIAG_SERIAL0
58 //#define CYG_KERNEL_DIAG_SERIAL1
59 //#define CYG_KERNEL_DIAG_SERIAL2
60 //#define CYG_KERNEL_DIAG_BUFFER
61 //#define CYG_KERNEL_DIAG_GDB
62
63 #if !defined(CYG_KERNEL_DIAG_SERIAL0) && \
64 !defined(CYG_KERNEL_DIAG_SERIAL1) && \
65 !defined(CYG_KERNEL_DIAG_SERIAL2) && \
66 !defined(CYG_KERNEL_DIAG_ROMART)
67
68 #if defined(CYGSEM_HAL_USE_ROM_MONITOR_GDB_stubs)
69
70 #define CYG_KERNEL_DIAG_SERIAL0
71 #define CYG_KERNEL_DIAG_GDB
72
73 #else
74
75 #define CYG_KERNEL_DIAG_SERIAL0
76
77 #endif
78
79 #endif
80
81 //#define CYG_HAL_MN10300_STB_SERIAL2
82
83 /*---------------------------------------------------------------------------*/
84 // MN10300 Serial line
85
86 #if defined(CYG_HAL_MN10300_STB_SERIAL0) || defined(CYG_KERNEL_DIAG_SERIAL0)
87
88 // We use serial0 on AM33
89 #define SERIAL0_CR ((volatile cyg_uint16 *)0xd4002000)
90 #define SERIAL0_ICR ((volatile cyg_uint8 *) 0xd4002004)
91 #define SERIAL0_TXR ((volatile cyg_uint8 *) 0xd4002008)
92 #define SERIAL0_RXR ((volatile cyg_uint8 *) 0xd4002009)
93 #define SERIAL0_SR ((volatile cyg_uint16 *)0xd400200c)
94
95 // Timer 2 provides baud rate divisor
96 #define TIMER0_MD ((volatile cyg_uint8 *)0xd4003002)
97 #define TIMER0_BR ((volatile cyg_uint8 *)0xd4003012)
98 #define TIMER0_CR ((volatile cyg_uint8 *)0xd4003022)
99
100 // Timer 0 provides a prescaler for lower baud rates
101 #define HW_TIMER0_MD ((volatile cyg_uint8 *)0xd4003000)
102 #define HW_TIMER0_BR ((volatile cyg_uint8 *)0xd4003010)
103 #define HW_TIMER0_CR ((volatile cyg_uint8 *)0xd4003020)
104
105 #define SIO_LSTAT_TRDY 0x20
106 #define SIO_LSTAT_RRDY 0x10
107
108 #define SERIAL_CR_TXE 0x8000
109
110 void hal_diag_init_serial0(void)
111 {
112 #if 1
113 // 99 translates to 38400 baud.
114 *TIMER0_BR = 99;
115 // Timer0 sourced from IOCLK
116 *TIMER0_MD = 0x80;
117 #else
118 // 1 and 198 translate into 9800 baud
119 *TIMER0_BR = 1;
120 *TIMER0_MD = 0x84; // source = timer 0 overflow
121 *HW_TIMER0_BR = 198; // timer 0 base register
122 *HW_TIMER0_CR = 0x80; // source from ioclk
123 #endif
124
125 // No interrupts for now.
126 *SERIAL0_ICR = 0x00;
127
128 // Source from timer 1, 8bit chars, enable tx and rx
129 *SERIAL0_CR = 0xc085;
130 }
131
132 void hal_diag_write_char_serial0(char c)
133 {
134 register volatile cyg_uint16 *volatile tty_status = SERIAL0_SR;
135 register volatile cyg_uint8 *volatile tty_tx = SERIAL0_TXR;
136
137 while( (*tty_status & SIO_LSTAT_TRDY) != 0 ) continue;
138
139 *tty_tx = c;
140 }
141
142 void hal_diag_drain_serial0(void)
143 {
144 register volatile cyg_uint16 *volatile tty_status = SERIAL0_SR;
145
146 while( (*tty_status & SIO_LSTAT_TRDY) != 0 ) continue;
147 }
148
149 void hal_diag_read_char_serial0(char *c)
150 {
151 register volatile cyg_uint16 *volatile tty_status = SERIAL0_SR;
152 register volatile cyg_uint8 *volatile tty_rx = SERIAL0_RXR;
153
154 while( (*tty_status & SIO_LSTAT_RRDY) == 0 ) continue;
155
156 *c = *tty_rx;
157
158 // We must ack the interrupt caused by that read to avoid
159 // confusing the GDB stub ROM.
160 HAL_INTERRUPT_ACKNOWLEDGE( CYGNUM_HAL_INTERRUPT_SERIAL_0_RX );
161 }
162
163 #if defined(CYG_KERNEL_DIAG_SERIAL0)
164
165 #define hal_diag_init_serial hal_diag_init_serial0
166 #define hal_diag_write_char_serial hal_diag_write_char_serial0
167 #define hal_diag_drain_serial hal_diag_drain_serial0
168 #define hal_diag_read_char_serial hal_diag_read_char_serial0
169
170 #endif
171
172 #endif
173
174 /*---------------------------------------------------------------------------*/
175 // MN10300 Serial line
176
177 #if defined(CYG_HAL_MN10300_STB_SERIAL1) || defined(CYG_KERNEL_DIAG_SERIAL1)
178
179 // We use serial1 on MN103002
180 #define SERIAL1_CR ((volatile cyg_uint16 *)0xd4002010)
181 #define SERIAL1_ICR ((volatile cyg_uint8 *) 0xd4002014)
182 #define SERIAL1_TXR ((volatile cyg_uint8 *) 0xd4002018)
183 #define SERIAL1_RXR ((volatile cyg_uint8 *) 0xd4002019)
184 #define SERIAL1_SR ((volatile cyg_uint16 *)0xd400201c)
185
186 // Timer 1 provided baud rate divisor
187 #define TIMER1_MD ((volatile cyg_uint8 *)0xd4003001)
188 #define TIMER1_BR ((volatile cyg_uint8 *)0xd4003011)
189 #define TIMER1_CR ((volatile cyg_uint8 *)0xd4003021)
190
191 // Timer 0 provides a prescaler for lower baud rates
192 #define HW_TIMER0_MD ((volatile cyg_uint8 *)0xd4003000)
193 #define HW_TIMER0_BR ((volatile cyg_uint8 *)0xd4003010)
194 #define HW_TIMER0_CR ((volatile cyg_uint8 *)0xd4003020)
195
196 #define SIO1_LSTAT_TRDY 0x20
197 #define SIO1_LSTAT_RRDY 0x10
198
199 #define SERIAL_CR_TXE 0x8000
200
201 void hal_diag_init_serial1(void)
202 {
203 #if 1
204 // 99 translates to 38400 baud.
205 *TIMER1_BR = 99;
206
207 // Timer1 sourced from IOCLK
208 *TIMER1_MD = 0x80;
209
210 #else
211
212 // 1 and 198 translate into 9800 baud
213 *TIMER1_BR = 1;
214 *TIMER1_MD = 0x84; // source = timer 0 overflow
215 *HW_TIMER0_BR = 198; // timer 0 base register
216 *HW_TIMER0_CR = 0x80; // source from ioclk
217 #endif
218
219 // No interrupts for now.
220 *SERIAL1_ICR = 0x00;
221
222 // Source from timer 1, 8bit chars, enable tx and rx
223 *SERIAL1_CR = 0xc084;
224 }
225
226 void hal_diag_write_char_serial1(char c)
227 {
228 register volatile cyg_uint16 *volatile tty_status = SERIAL1_SR;
229 register volatile cyg_uint8 *volatile tty_tx = SERIAL1_TXR;
230
231 while( (*tty_status & SIO1_LSTAT_TRDY) != 0 ) continue;
232
233 *tty_tx = c;
234 }
235
236 void hal_diag_drain_serial1(void)
237 {
238 register volatile cyg_uint16 *volatile tty_status = SERIAL1_SR;
239
240 while( (*tty_status & SIO1_LSTAT_TRDY) != 0 ) continue;
241 }
242
243 void hal_diag_read_char_serial1(char *c)
244 {
245 register volatile cyg_uint16 *volatile tty_status = SERIAL1_SR;
246 register volatile cyg_uint8 *volatile tty_rx = SERIAL1_RXR;
247
248 while( (*tty_status & SIO1_LSTAT_RRDY) == 0 ) continue;
249
250 *c = *tty_rx;
251
252 // We must ack the interrupt caused by that read to avoid
253 // confusing the GDB stub ROM.
254 HAL_INTERRUPT_ACKNOWLEDGE( CYGNUM_HAL_INTERRUPT_SERIAL_1_RX );
255 }
256
257 #if defined(CYG_KERNEL_DIAG_SERIAL1)
258
259 #define hal_diag_init_serial hal_diag_init_serial1
260 #define hal_diag_write_char_serial hal_diag_write_char_serial1
261 #define hal_diag_drain_serial hal_diag_drain_serial1
262 #define hal_diag_read_char_serial hal_diag_read_char_serial1
263
264 #endif
265
266 #endif
267
268 /*---------------------------------------------------------------------------*/
269
270 #if defined(CYG_HAL_MN10300_STB_SERIAL2) || defined(CYG_KERNEL_DIAG_SERIAL2)
271
272 // We use serial2 on MN103002
273 #define SERIAL2_CR ((volatile cyg_uint16 *)0xd4002020)
274 #define SERIAL2_ICR ((volatile cyg_uint8 *) 0xd4002024)
275 #define SERIAL2_TXR ((volatile cyg_uint8 *) 0xd4002028)
276 #define SERIAL2_RXR ((volatile cyg_uint8 *) 0xd4002029)
277 #define SERIAL2_SR ((volatile cyg_uint8 *) 0xd400202c)
278 #define SERIAL2_TR ((volatile cyg_uint8 *) 0xd400202d)
279
280 // Timer 3 provides baud rate divisor
281 #define TIMER2_MD ((volatile cyg_uint8 *)0xd4003003)
282 #define TIMER2_BR ((volatile cyg_uint8 *)0xd4003013)
283 #define TIMER2_CR ((volatile cyg_uint8 *)0xd4003023)
284
285 #define SIO2_LSTAT_TRDY 0x20
286 #define SIO2_LSTAT_RRDY 0x10
287
288 void hal_diag_init_serial2(void)
289 {
290 #if 0
291 {
292 int i,j;
293 for( j = 1; j < 255; j++ )
294 {
295 for(i = 1; i < 127; i++)
296 {
297 *TIMER2_BR = j;
298 *SERIAL2_TR = i;
299
300 // Timer2 sourced from IOCLK
301 *TIMER2_MD = 0x80;
302
303 // No interrupts for now.
304 *SERIAL2_ICR = 0x00;
305
306 // Source from timer 2, 8bit chars, enable tx and rx
307 *SERIAL2_CR = 0xc081;
308
309 diag_printf("\r\n<%03d,%03d>1234567890abcdefgh<%03d,%03d>\r\n",j,i,j,i);
310 }
311 }
312 }
313 #endif
314
315 // 7 and 102 translate to 38400 baud.
316 // The AM33 documentation says that these values should be 7 and 113.
317 // I have no explanation as to why there is such a discrepancy between the
318 // documentation and the hardware.
319
320 *TIMER2_BR = 7;
321 *SERIAL2_TR = 102;
322
323 // Timer2 sourced from IOCLK
324 *TIMER2_MD = 0x80;
325
326 // No interrupts for now.
327 *SERIAL2_ICR = 0x00;
328
329 // Source from timer 3, 8bit chars, enable tx and rx
330 *SERIAL2_CR = 0xc083;
331
332 }
333
334 void hal_diag_write_char_serial2(char c)
335 {
336 register volatile cyg_uint8 *volatile tty_status = SERIAL2_SR;
337 register volatile cyg_uint8 *volatile tty_tx = SERIAL2_TXR;
338
339 while( (*tty_status & SIO2_LSTAT_TRDY) != 0 ) continue;
340
341 *tty_tx = c;
342 }
343
344 void hal_diag_drain_serial2(void)
345 {
346 register volatile cyg_uint8 *volatile tty_status = SERIAL2_SR;
347
348 while( (*tty_status & SIO2_LSTAT_TRDY) != 0 ) continue;
349 }
350
351 void hal_diag_read_char_serial2(char *c)
352 {
353 register volatile cyg_uint8 *volatile tty_status = SERIAL2_SR;
354 register volatile cyg_uint8 *volatile tty_rx = SERIAL2_RXR;
355
356 while( (*tty_status & SIO2_LSTAT_RRDY) == 0 ) continue;
357
358 *c = *tty_rx;
359
360 // We must ack the interrupt caused by that read to avoid
361 // confusing the GDB stub ROM.
362 HAL_INTERRUPT_ACKNOWLEDGE( CYGNUM_HAL_INTERRUPT_SERIAL_2_RX );
363
364
365 }
366
367 #if defined(CYG_KERNEL_DIAG_SERIAL2)
368
369 #define hal_diag_init_serial hal_diag_init_serial2
370 #define hal_diag_write_char_serial hal_diag_write_char_serial2
371 #define hal_diag_drain_serial hal_diag_drain_serial2
372 #define hal_diag_read_char_serial hal_diag_read_char_serial2
373
374 #endif
375
376 #endif
377
378 /*---------------------------------------------------------------------------*/
379
380
381 #if defined(CYG_KERNEL_DIAG_BUFFER)
382
383 char hal_diag_buffer[10000];
384 int hal_diag_buffer_pos;
385
386 void hal_diag_init_buffer(void)
387 {
388 hal_diag_buffer_pos = 0;
389 }
390
391 void hal_diag_write_char_buffer(char c)
392 {
393 hal_diag_buffer[hal_diag_buffer_pos++] = c;
394 if (hal_diag_buffer_pos >= sizeof(hal_diag_buffer) )
395 hal_diag_buffer_pos = 0;
396 }
397
398 void hal_diag_drain_buffer(void)
399 {
400 }
401
402 void hal_diag_read_char_buffer(char *c)
403 {
404 *c = '\n';
405 }
406
407 #define hal_diag_init_serial hal_diag_init_buffer
408 #define hal_diag_write_char_serial hal_diag_write_char_buffer
409 #define hal_diag_drain_serial hal_diag_drain_buffer
410 #define hal_diag_read_char_serial hal_diag_read_char_buffer
411
412 #endif
413
414
415 /*---------------------------------------------------------------------------*/
416
417 void hal_diag_init(void)
418 {
419 hal_diag_init_serial();
420 }
421
422 void hal_diag_write_char(char c)
423 {
424 #ifdef CYG_KERNEL_DIAG_GDB
425
426 static char line[100];
427 static int pos = 0;
428
429 // No need to send CRs
430 if( c == '\r' ) return;
431
432 line[pos++] = c;
433
434 if( c == '\n' || pos == sizeof(line) )
435 {
436 // Disable interrupts. This prevents GDB trying to interrupt us
437 // while we are in the middle of sending a packet. The serial
438 // receive interrupt will be seen when we re-enable interrupts
439 // later.
440
441 CYG_INTERRUPT_STATE oldstate;
442 CYG_BYTE wdcr;
443 HAL_DISABLE_INTERRUPTS(oldstate);
444
445 // Beacuse of problems with NT on the testfarm, we also have
446 // to disable the watchdog here. This only matters in the
447 // watchdog tests. And yes, this sends my irony meter off the
448 // scale too.
449
450 HAL_READ_UINT8( 0xC0001002, wdcr );
451 HAL_WRITE_UINT8( 0xC0001002, wdcr&0x3F );
452
453 while(1)
454 {
455 static char hex[] = "0123456789ABCDEF";
456 cyg_uint8 csum = 0;
457 int i;
458
459 hal_diag_write_char_serial('$');
460 hal_diag_write_char_serial('O');
461 csum += 'O';
462 for( i = 0; i < pos; i++ )
463 {
464 char ch = line[i];
465 char h = hex[(ch>>4)&0xF];
466 char l = hex[ch&0xF];
467 hal_diag_write_char_serial(h);
468 hal_diag_write_char_serial(l);
469 csum += h;
470 csum += l;
471 }
472 hal_diag_write_char_serial('#');
473 hal_diag_write_char_serial(hex[(csum>>4)&0xF]);
474 hal_diag_write_char_serial(hex[csum&0xF]);
475
476
477 {
478 char c1;
479
480 hal_diag_read_char_serial( &c1 );
481
482 if( c1 == '+' ) break;
483
484
485 if( cyg_hal_is_break( &c1, 1 ) )
486 cyg_hal_user_break( NULL );
487
488 }
489 }
490
491 pos = 0;
492
493 // Wait for tx buffer to drain
494 hal_diag_drain_serial();
495
496 // And re-enable interrupts
497 HAL_RESTORE_INTERRUPTS(oldstate);
498 HAL_WRITE_UINT8( 0xC0001002, wdcr );
499 }
500
501 #else
502 hal_diag_write_char_serial(c);
503 #endif
504 }
505
506
507
508
509 void hal_diag_read_char(char *c)
510 {
511 hal_diag_read_char_serial(c);
512 }
513
514
515 /*---------------------------------------------------------------------------*/
516 /* End of hal_diag.c */