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/] [cycduart.c] - Blame information for rev 174

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//=============================================================================
2
//
3
//      cycduart.c - Cyclone UART 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
#include <redboot.h>
51
#include <cyg/hal/hal_iop310.h>        // Hardware definitions
52
#include "cycduart.h"
53
#include "iq80310.h"
54
#include "test_menu.h"
55
 
56
#define DFLTLOOPERMS 500
57
 
58
//extern int printf(char*,...);
59
extern long hexIn(void);
60
 
61
int break_flag = 0;
62
unsigned long baud_rate = 0;
63
 
64
static int duart_already_init = FALSE;
65
static unsigned int uart_unit = DFLTPORT;
66
static int looperms;
67
 
68
static int calc_looperms(void);
69
void serial_init(void);
70
int inreg(int);
71
void outreg(int, unsigned char);
72
void serial_set(unsigned long);
73
void serial_loopback(int);
74
int serial_getc(void);
75
void serial_putc(int);
76
int serial_write(int, const unsigned char *, int);
77
int serial_read(int, unsigned char *, int, int);
78
 
79
extern int enable_external_interrupt (int int_id);
80
extern int disable_external_interrupt (int int_id);
81
 
82
extern int isr_connect(int int_num, void (*handler)(int), int arg);
83
extern int isr_disconnect(int int_num);
84
 
85
 
86
void duart_initialize(void)
87
{
88
    if (duart_already_init == FALSE) {
89
        /* Calculate the time constant for timeouts on serial_read. */
90
        if ((looperms = calc_looperms()) <= 0)
91
            looperms = DFLTLOOPERMS;
92
    }
93
 
94
    /* Initialize the serial port and set the baud rate.
95
     * The baud rate is set here for sanity only; the autobaud
96
     * mechanism will change it as required when the host connects.
97
     */
98
 
99
    serial_init();
100
    serial_set(baud_rate?baud_rate:9600L);
101
 
102
    duart_already_init = TRUE;
103
}
104
 
105
 
106
/* Establish the loop/time constant to be used in the timing loop in
107
 * serial_read.  This is done by putting the UART into loopback mode.
108
 * After transmitting a character at 300 baud, we wait for the character
109
 * to be received.  Then divide the number of loops waited by the number
110
 * of milliseconds it takes to transmit 10 bits at 300 baud.
111
 * If your transmitter doesn't have a loopback mode, this value can be
112
 * calculated using a timer or some other facility, or an approximate
113
 * constant can be used.
114
 */
115
 
116
#define TESTBAUD 300L
117
#define NBYTES   10
118
#define BITS_PER_BYTE 10        /* 1 start bit, 8 data bits, 1 stop bit */
119
#define TOTAL_MS (NBYTES*BITS_PER_BYTE*1000/TESTBAUD)
120
 
121
static int
122
calc_looperms(void)
123
{
124
    int i, count, c;
125
    int totalloops = 0;
126
 
127
    serial_init();
128
    serial_set(TESTBAUD);               /* set 300 baud */
129
    serial_loopback(1);         /* enable loop back mode */
130
 
131
    for (i=0; i < NBYTES; i++) {
132
        count = 1;
133
        serial_putc(0xaa);      /* xmit character */
134
 
135
        /*
136
         * The timing loop is the same as the loops in serial_read.
137
         * Any changes to the loops in serial_read should be reflected
138
         * here.
139
         */
140
        do {
141
            c = serial_getc();
142
        } while (c < 0 && count++ > 0);
143
 
144
        totalloops += count;
145
    }
146
 
147
    serial_loopback(0);
148
 
149
    return(totalloops/TOTAL_MS);
150
}
151
 
152
/*
153
 * Initialize the device driver.
154
 */
155
void serial_init(void)
156
{
157
    /* If the serial port has been init'd before, there may be data in it  */
158
    /* Wait for the transmit FIFO to empty out before resetting anything   */
159
    if (duart_already_init == TRUE)     {
160
        while (!(inreg(LSR) & LSR_TSRE));
161
    }
162
 
163
    /*
164
     * Configure active port, (uart_unit already set.)
165
     *
166
     * Set 8 bits, 1 stop bit, no parity.
167
     *
168
     * LCR<7>       0       divisor latch access bit
169
     * LCR<6>       0       break control (1=send break)
170
     * LCR<5>       0       stick parity (0=space, 1=mark)
171
     * LCR<4>       0       parity even (0=odd, 1=even)
172
     * LCR<3>       0       parity enable (1=enabled)
173
     * LCR<2>       0       # stop bits (0=1, 1=1.5)
174
     * LCR<1:0>     11      bits per character(00=5, 01=6, 10=7, 11=8)
175
     */
176
 
177
    outreg(LCR, 0x3);
178
 
179
    /* Assert DTR and RTS to prevent hardware handshake problems with
180
       serial terminals, etc. which can be connected to the serial port */
181
    outreg(MCR, MCR_DTR | MCR_RTS);
182
 
183
    outreg(FCR, FIFO_ENABLE);   /* Enable the FIFO                 */
184
    outreg(IER, INT_ENABLE);    /* Enable appropriate interrupts   */
185
 
186
}
187
 
188
/* Read a received character if one is available.  Return -1 otherwise. */
189
int serial_getc(void)
190
{
191
    if (inreg(LSR) & LSR_DR)
192
         return inreg(DataIn);
193
 
194
    return -1;
195
}
196
 
197
/* Transmit a character. */
198
void serial_putc(int c)
199
{
200
    while ((inreg(LSR) & LSR_THRE) == 0)
201
        ;
202
    outreg(DataOut, c);
203
}
204
 
205
/*
206
 * Set the baud rate.
207
 */
208
void serial_set(unsigned long baud)
209
{
210
    unsigned char sav_lcr;
211
 
212
    if(baud == 0)
213
        baud = 9600L;
214
 
215
    /*
216
     * Enable access to the divisor latches by setting DLAB in LCR.
217
     *
218
     */
219
    sav_lcr = inreg(LCR);
220
    outreg(LCR, LCR_DLAB | sav_lcr);
221
 
222
    /*
223
     * Set divisor latches.
224
     */
225
    outreg(BaudLsb, XTAL/(16*baud));
226
    outreg(BaudMsb, (XTAL/(16*baud)) >> 8);
227
 
228
    /*
229
     * Restore line control register
230
     */
231
    outreg(LCR, sav_lcr);
232
}
233
 
234
/*
235
 * This routine is used by calc_looperms to put the UART in loopback mode.
236
 */
237
 
238
void serial_loopback(int flag)
239
{
240
    if (flag)
241
        outreg(MCR, inreg(MCR) | MCR_LOOP);             /* enable loop back mode */
242
    else
243
        outreg(MCR, inreg(MCR) & ~MCR_LOOP);    /* disable loop back mode */
244
}
245
 
246
/*
247
 * These routines are used to read and write to the registers of the
248
 * 16552.  The delay routine guarantees the required recovery time between
249
 * cycles to the 16552.
250
 * DUART is the base address of the 16552.
251
 * DUART_DELTA gives the spacing between adjacent registers of the 16552.
252
 * For example, if A0,A1,A2 of the 16552 are connected to A2,A3,A4 of
253
 * the processor, DUART_DELTA must be 4.
254
 */
255
 
256
int inreg(int reg)
257
{
258
    int val;
259
    val = *((volatile unsigned char *)TERMINAL + (uart_unit * SCALE + reg));
260
 
261
    return val;
262
}
263
 
264
void outreg(int reg, unsigned char val)
265
{
266
    *((volatile unsigned char *)TERMINAL + (uart_unit * SCALE + reg)) = val;
267
}
268
 
269
 
270
 
271
/****************************************************************/
272
/* The following functions are all part of the Breeze UART test */
273
/****************************************************************/
274
 
275
 
276
static volatile int uart_int;
277
 
278
 
279
/************************************************/
280
/* BUS_TEST                                                                             */
281
/* This routine performs a walking ones test    */
282
/* on the given uart chip to test it's bus              */
283
/* interface.  It writes to the scratchpad reg. */
284
/* then reads it back.  During                                  */
285
/* this test all 8 data lines from the chip             */
286
/* get written with both 1 and 0.                               */
287
/************************************************/
288
static int bus_test (void)
289
{
290
    unsigned char       out, in;
291
    int                 bitpos;
292
    volatile int        junk;
293
 
294
    junk = (int) &junk; /* Don't let compiler optimize or "registerize" */
295
 
296
    outreg(SCR,0);               /* Clear scratchpad register */
297
 
298
    for (bitpos = 0; bitpos < 8; bitpos++) {
299
        out = 1 << bitpos;
300
 
301
        outreg(SCR,out);        /* Write data to scratchpad reg. */
302
 
303
        junk = ~0;                       /* Force data lines high */
304
 
305
        in = inreg(SCR);        /* Read data */
306
 
307
        printf ("%02X ", in);
308
 
309
        /* make sure it's what we wrote */
310
        if (in != out)
311
            return (0);
312
    }
313
    outreg(SCR,0);       /* Clear scratchpad register */
314
    printf ("\n");
315
 
316
    return (1);
317
}
318
 
319
/************************************************/
320
/* DISABLE_UART_INTS                                                    */
321
/* This routine disables uart interrupts                */
322
/************************************************/
323
static void disable_uart_ints (void)
324
{
325
    outreg(IER,0);               /* Make the uart shut up */
326
}
327
 
328
/************************************************/
329
/* UART_ISR                                                                             */
330
/* This routine responds to uart interrupts             */
331
/* must return 1 to indicate that an interrupt  */
332
/* was serviced.                                                                */
333
/************************************************/
334
static void uart_isr (int unused)
335
{
336
    unsigned char iir;
337
 
338
    disable_uart_ints ();
339
    uart_int = 1;
340
 
341
    /* read the IIR to clear the interrupt */
342
    iir = inreg(IIR);
343
 
344
    return ;
345
}
346
 
347
/************************************************/
348
/* INIT_UART                                                                    */
349
/* This routine initializes the 16550 interrupt */
350
/* and uart registers and initializes the uart  */
351
/* count.                                                                               */
352
/************************************************/
353
static void init_uart (void)
354
{
355
    outreg(IER,0x02);           /* Enable Tx Empty interrupt -
356
                                   should generate an interrupt since Tx is
357
                                   empty to begin with */
358
}
359
 
360
 
361
/****************************************/
362
/* UART DIAGNOSTIC TEST                                 */
363
/****************************************/
364
void uart_test (MENU_ARG arg)
365
{
366
    volatile int loop;
367
    int looplim;
368
    int int_id;
369
    int i, baud;
370
 
371
    /*11/01/00 */
372
    char info[] = {"Move Console Cable back to Connector J9 and hit <CR> to exit test"};
373
    int index;
374
 
375
    looplim = 400000;
376
 
377
    /* perform tests on both UARTs */
378
    for (uart_unit = 0; uart_unit < 2; uart_unit++)      {
379
 
380
        if (uart_unit == 0)
381
            int_id = UART1_INT_ID;
382
        else
383
            int_id = UART2_INT_ID;
384
 
385
        if (!bus_test ())
386
            printf ("\nERROR:  bus_test for UART Unit %d failed\n", uart_unit);
387
        else {
388
            printf ("\nbus_test for UART Unit %d passed\n", uart_unit);
389
 
390
            uart_int = 0;
391
 
392
            isr_connect (int_id, uart_isr, 0);
393
 
394
            if (enable_external_interrupt(int_id) != OK)
395
                printf("ERROR enabling UART UINT %d interrupt!\n", uart_unit);
396
 
397
            init_uart ();
398
 
399
            loop = 0;
400
 
401
            while (!uart_int && (loop < looplim))
402
                loop++;
403
            if (!uart_int)
404
                printf ("UART Unit %d INTERRUPT test failed %X\n", uart_unit, loop) ;
405
            else
406
                printf ("UART Unit %d INTERRUPT test passed\n", uart_unit);
407
 
408
            serial_putc(' ');
409
        }
410
 
411
        /* disable UART interrupt */
412
        if (disable_external_interrupt(int_id)!= OK)
413
            printf("ERROR disabling UART UNIT %d interrupt!\n", uart_unit);
414
 
415
        /* disconnect test handler */
416
        isr_disconnect (int_id);
417
 
418
    }
419
 
420
    /* 11/01/00 */
421
    /* #if 0 */  /* writing to port 2 doesnt work yet... */
422
#if 1 /* writing to port 2 doesnt work yet... */
423
 
424
/*
425
        printf ("\nMove the Console Cable to the 2nd Serial Port,\n");
426
        printf ("Connector J10,\n");
427
    printf ("and Hit <CR> when the cable is connected.\n\n");
428
        printf ("After alphabet prints, move Console Cable back to 1st Serial Port,\n");
429
        printf ("Connector J9,\n");
430
        printf ("and hit <CR> to exit test\n");
431
*/
432
 
433
/* 10/30/00 */
434
    uart_unit = DFLTPORT;       /* test J10, the PCI-700 GDB port */
435
 
436
    printf ("\nMove the Console Cable to the 2nd Serial Port, Connector J10,\n");
437
    printf ("and Hit <CR> when the cable is connected.\n");
438
    printf ("The alphabet should print on the screen.\n\n");
439
 
440
/* 11/01/00 */
441
/*
442
        printf ("After alphabet prints, move Console Cable back to 1st Serial Port,\n");
443
        printf ("Connector J9,\n");
444
        printf ("and hit <CR> to exit test\n");
445
*/
446
    baud = 115200;
447
    serial_init();
448
    serial_set(baud?baud:115200L);
449
 
450
/*      while (serial_getc() == -1); */
451
    while (serial_getc() != 0x0d);      /* wait for a carriage return character to start test */
452
 
453
/*
454
        while (1)
455
        {
456
                for ( i = 65; i <= 90; i++ )
457
                        serial_putc(i);
458
        }
459
*/
460
    for ( i = 65; i <= 90; i++ )        /* transmit the alphabet */
461
        serial_putc(i);
462
 
463
    serial_putc(10);    /* transmit a New Line */
464
    serial_putc(13);    /* transmit a Carriage Return */
465
    serial_putc(10);    /* transmit a New Line */
466
 
467
    for (index=0; info[index] != '\0'; index++)  /* transmit some instructions to the user */
468
        serial_putc(info[index]);
469
 
470
    /* point at default port before returning */
471
    /*  uart_unit = DFLTPORT; */
472
 
473
    (void)hexIn();
474
 
475
#endif
476
 
477
    printf ("\n\nUART tests done.\n");
478
    printf ("Press return to continue.\n");
479
    (void) hexIn();
480
}
481
 
482
 
483
 
484
 

powered by: WebSVN 2.1.0

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