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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [arm/] [aeb/] [v2_0/] [src/] [hal_diag.c] - Blame information for rev 249

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

Line No. Rev Author Line
1 27 unneback
/*=============================================================================
2
//
3
//      hal_diag.c
4
//
5
//      HAL diagnostic output code
6
//
7
//=============================================================================
8
//####ECOSGPLCOPYRIGHTBEGIN####
9
// -------------------------------------------
10
// This file is part of eCos, the Embedded Configurable Operating System.
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, 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 version.
16
//
17
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20
// for more details.
21
//
22
// You should have received a copy of the GNU General Public License along
23
// with eCos; if not, write to the Free Software Foundation, Inc.,
24
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25
//
26
// As a special exception, if other files instantiate templates or use macros
27
// or inline functions from this file, or you compile this file and link it
28
// with other works to produce a work based on this file, this file does not
29
// by itself cause the resulting work to be covered by the GNU General Public
30
// License. However the source code for this file must still be made available
31
// in accordance with section (3) of the GNU General Public License.
32
//
33
// This exception does not invalidate any other reasons why a work based on
34
// this file might be covered by the GNU General Public License.
35
//
36
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37
// at http://sources.redhat.com/ecos/ecos-license/
38
// -------------------------------------------
39
//####ECOSGPLCOPYRIGHTEND####
40
//=============================================================================
41
//#####DESCRIPTIONBEGIN####
42
//
43
// Author(s):   nickg, gthomas
44
// Contributors:nickg, gthomas
45
// Date:        1998-03-02
46
// Purpose:     HAL diagnostic output
47
// Description: Implementations of HAL diagnostic output support.
48
//
49
//####DESCRIPTIONEND####
50
//
51
//===========================================================================*/
52
 
53
#include <pkgconf/hal.h>
54
 
55
#include <cyg/infra/cyg_type.h>         // base types
56
#include <cyg/infra/cyg_trac.h>         // tracing macros
57
#include <cyg/infra/cyg_ass.h>          // assertion macros
58
 
59
#include <cyg/hal/hal_arch.h>           // SAVE/RESTORE GP macros
60
#include <cyg/hal/hal_io.h>             // IO macros
61
#include <cyg/hal/hal_if.h>             // interface API
62
#include <cyg/hal/hal_intr.h>           // HAL_ENABLE/MASK/UNMASK_INTERRUPTS
63
#include <cyg/hal/hal_misc.h>           // Helper functions
64
#include <cyg/hal/drv_api.h>            // CYG_ISR_HANDLED
65
 
66
/*---------------------------------------------------------------------------*/
67
// AEB Serial Port (UART1) for Debug
68
 
69
/*---------------------------------------------------------------------------*/
70
/* From serial_16550.h */
71
 
72
// UART1, 38400  (Using raw 24MHz system clock)
73
#define CYG_DEVICE_SERIAL_RS232_BAUD_MSB        (0)
74
#define CYG_DEVICE_SERIAL_RS232_BAUD_LSB        (13*3)
75
// This is the base address of UART1
76
#define CYG_DEV_UART1_BASE      0xFFFF0400
77
 
78
// Interrupt Enable Register
79
#define SIO_IER_RCV 0x01
80
#define SIO_IER_XMT 0x02
81
#define SIO_IER_LS  0x04
82
#define SIO_IER_MS  0x08
83
 
84
// Define the serial registers.
85
#define CYG_DEV_RBR 0x00   // receiver buffer register, read, dlab = 0
86
#define CYG_DEV_THR 0x00   // transmitter holding register, write, dlab = 0
87
#define CYG_DEV_DLL 0x00   // divisor latch (LS), read/write, dlab = 1
88
#define CYG_DEV_IER 0x04   // interrupt enable register, read/write, dlab = 0
89
#define CYG_DEV_DLM 0x04   // divisor latch (MS), read/write, dlab = 1
90
#define CYG_DEV_IIR 0x08   // interrupt identification register, read, dlab = 0
91
#define CYG_DEV_FCR 0x08   // fifo control register, write, dlab = 0
92
#define CYG_DEV_LCR 0x0C   // line control register, read/write
93
#define CYG_DEV_MCR 0x10   // modem control register, read/write
94
#define CYG_DEV_LSR 0x14   // line status register, read
95
#define CYG_DEV_MSR 0x18   // modem status register, read
96
 
97
// The line status register bits.
98
#define SIO_LSR_DR      0x01            // data ready
99
#define SIO_LSR_OE      0x02            // overrun error
100
#define SIO_LSR_PE      0x04            // parity error
101
#define SIO_LSR_FE      0x08            // framing error
102
#define SIO_LSR_BI      0x10            // break interrupt
103
#define SIO_LSR_THRE    0x20            // transmitter holding register empty
104
#define SIO_LSR_TEMT    0x40            // transmitter register empty
105
#define SIO_LSR_ERR     0x80            // any error condition
106
 
107
// The modem status register bits.
108
#define SIO_MSR_DCTS  0x01              // delta clear to send
109
#define SIO_MSR_DDSR  0x02              // delta data set ready
110
#define SIO_MSR_TERI  0x04              // trailing edge ring indicator
111
#define SIO_MSR_DDCD  0x08              // delta data carrier detect
112
#define SIO_MSR_CTS   0x10              // clear to send
113
#define SIO_MSR_DSR   0x20              // data set ready
114
#define SIO_MSR_RI    0x40              // ring indicator
115
#define SIO_MSR_DCD   0x80              // data carrier detect
116
 
117
// The line control register bits.
118
#define SIO_LCR_WLS0   0x01             // word length select bit 0
119
#define SIO_LCR_WLS1   0x02             // word length select bit 1
120
#define SIO_LCR_STB    0x04             // number of stop bits
121
#define SIO_LCR_PEN    0x08             // parity enable
122
#define SIO_LCR_EPS    0x10             // even parity select
123
#define SIO_LCR_SP     0x20             // stick parity
124
#define SIO_LCR_SB     0x40             // set break
125
#define SIO_LCR_DLAB   0x80             // divisor latch access bit
126
 
127
// Modem Control Register
128
#define SIO_MCR_DTR 0x01
129
#define SIO_MCR_RTS 0x02
130
#define SIO_MCR_INT 0x08   // Enable interrupts
131
 
132
 
133
//-----------------------------------------------------------------------------
134
typedef struct {
135
    cyg_uint8* base;
136
    cyg_int32 msec_timeout;
137
    int isr_vector;
138
} channel_data_t;
139
 
140
//-----------------------------------------------------------------------------
141
 
142
static void
143
cyg_hal_plf_serial_init_channel(void* __ch_data)
144
{
145
    cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
146
    cyg_uint8 lcr, dll, dlm;
147
 
148
    // 8-1-no parity.
149
    HAL_WRITE_UINT8(base+CYG_DEV_LCR, SIO_LCR_WLS0 | SIO_LCR_WLS1);
150
 
151
    HAL_READ_UINT8(base+CYG_DEV_LCR, lcr);
152
    lcr |= SIO_LCR_DLAB;
153
    HAL_WRITE_UINT8(base+CYG_DEV_LCR, lcr);
154
    HAL_READ_UINT8(base+CYG_DEV_DLL, dll);
155
    HAL_READ_UINT8(base+CYG_DEV_DLM, dlm);
156
    HAL_WRITE_UINT8 (base+CYG_DEV_DLL, CYG_DEVICE_SERIAL_RS232_BAUD_LSB);
157
    HAL_WRITE_UINT8 (base+CYG_DEV_DLM, CYG_DEVICE_SERIAL_RS232_BAUD_MSB);
158
    lcr &= ~SIO_LCR_DLAB;
159
    HAL_WRITE_UINT8 (base+CYG_DEV_LCR, lcr);
160
    HAL_WRITE_UINT8 (base+CYG_DEV_FCR, 0x07);  // Enable & clear FIFO
161
}
162
 
163
void
164
cyg_hal_plf_serial_putc(void *__ch_data, char c)
165
{
166
    cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
167
    cyg_uint8 lsr;
168
    CYGARC_HAL_SAVE_GP();
169
 
170
    do {
171
        HAL_READ_UINT8(base+CYG_DEV_LSR, lsr);
172
    } while ((lsr & SIO_LSR_THRE) == 0);
173
 
174
    HAL_WRITE_UINT8(base+CYG_DEV_THR, c);
175
 
176
    CYGARC_HAL_RESTORE_GP();
177
}
178
 
179
static cyg_bool
180
cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch)
181
{
182
    cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
183
    cyg_uint8 lsr;
184
 
185
    HAL_READ_UINT8(base+CYG_DEV_LSR, lsr);
186
    if ((lsr & SIO_LSR_DR) == 0)
187
        return false;
188
 
189
    HAL_READ_UINT8(base+CYG_DEV_RBR, *ch);
190
 
191
    return true;
192
}
193
 
194
cyg_uint8
195
cyg_hal_plf_serial_getc(void* __ch_data)
196
{
197
    cyg_uint8 ch;
198
    CYGARC_HAL_SAVE_GP();
199
 
200
    while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
201
 
202
    CYGARC_HAL_RESTORE_GP();
203
    return ch;
204
}
205
 
206
static void
207
cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf,
208
                         cyg_uint32 __len)
209
{
210
    CYGARC_HAL_SAVE_GP();
211
 
212
    while(__len-- > 0)
213
        cyg_hal_plf_serial_putc(__ch_data, *__buf++);
214
 
215
    CYGARC_HAL_RESTORE_GP();
216
}
217
 
218
static void
219
cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
220
{
221
    CYGARC_HAL_SAVE_GP();
222
 
223
    while(__len-- > 0)
224
        *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
225
 
226
    CYGARC_HAL_RESTORE_GP();
227
}
228
 
229
cyg_bool
230
cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
231
{
232
    int delay_count;
233
    channel_data_t* chan = (channel_data_t*)__ch_data;
234
    cyg_bool res;
235
    CYGARC_HAL_SAVE_GP();
236
 
237
    delay_count = chan->msec_timeout * 10; // delay in .1 ms steps
238
 
239
    for(;;) {
240
        res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
241
        if (res || 0 == delay_count--)
242
            break;
243
 
244
        CYGACC_CALL_IF_DELAY_US(100);
245
    }
246
 
247
    CYGARC_HAL_RESTORE_GP();
248
    return res;
249
}
250
 
251
static int
252
cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
253
{
254
    static int irq_state = 0;
255
    channel_data_t* chan = (channel_data_t*)__ch_data;
256
    int ret = 0;
257
    CYGARC_HAL_SAVE_GP();
258
 
259
    switch (__func) {
260
    case __COMMCTL_IRQ_ENABLE:
261
        irq_state = 1;
262
 
263
        HAL_WRITE_UINT8(chan->base+CYG_DEV_IER, SIO_IER_RCV);
264
        HAL_WRITE_UINT8(chan->base+CYG_DEV_MCR, SIO_MCR_INT|SIO_MCR_DTR|SIO_MCR_RTS);
265
 
266
        HAL_INTERRUPT_UNMASK(chan->isr_vector);
267
        break;
268
    case __COMMCTL_IRQ_DISABLE:
269
        ret = irq_state;
270
        irq_state = 0;
271
 
272
        HAL_WRITE_UINT8(chan->base+CYG_DEV_IER, 0);
273
        HAL_WRITE_UINT8(chan->base+CYG_DEV_MCR, SIO_MCR_INT|SIO_MCR_DTR|SIO_MCR_RTS);
274
 
275
        HAL_INTERRUPT_MASK(chan->isr_vector);
276
        break;
277
    case __COMMCTL_DBG_ISR_VECTOR:
278
        ret = chan->isr_vector;
279
        break;
280
    case __COMMCTL_SET_TIMEOUT:
281
    {
282
        va_list ap;
283
 
284
        va_start(ap, __func);
285
 
286
        ret = chan->msec_timeout;
287
        chan->msec_timeout = va_arg(ap, cyg_uint32);
288
 
289
        va_end(ap);
290
    }
291
    default:
292
        break;
293
    }
294
    CYGARC_HAL_RESTORE_GP();
295
    return ret;
296
}
297
 
298
static int
299
cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc,
300
                       CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
301
{
302
    int res = 0;
303
    channel_data_t* chan = (channel_data_t*)__ch_data;
304
    char c;
305
    cyg_uint8 lsr;
306
    CYGARC_HAL_SAVE_GP();
307
 
308
    cyg_drv_interrupt_acknowledge(chan->isr_vector);
309
 
310
 
311
    *__ctrlc = 0;
312
    HAL_READ_UINT8(chan->base+CYG_DEV_LSR, lsr);
313
    if ( (lsr & SIO_LSR_DR) != 0 ) {
314
 
315
        HAL_READ_UINT8(chan->base+CYG_DEV_RBR, c);
316
        if( cyg_hal_is_break( &c , 1 ) )
317
            *__ctrlc = 1;
318
 
319
        res = CYG_ISR_HANDLED;
320
    }
321
 
322
    CYGARC_HAL_RESTORE_GP();
323
    return res;
324
}
325
 
326
static channel_data_t aeb_ser_channels[1];
327
 
328
static void
329
cyg_hal_plf_serial_init(void)
330
{
331
    hal_virtual_comm_table_t* comm;
332
    int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
333
    channel_data_t* chan;
334
 
335
    chan = &aeb_ser_channels[0];
336
    chan->base = (cyg_uint8*)CYG_DEV_UART1_BASE;
337
    chan->isr_vector = CYGNUM_HAL_INTERRUPT_UART1;
338
    chan->msec_timeout = 1000;
339
 
340
    // Init channel
341
    cyg_hal_plf_serial_init_channel(chan);
342
 
343
    // Setup procs in the vector table
344
 
345
    // Set channel 0
346
    CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
347
    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
348
    CYGACC_COMM_IF_CH_DATA_SET(*comm, chan);
349
    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
350
    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
351
    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
352
    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
353
    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
354
    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
355
    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
356
 
357
    // Restore original console
358
    CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
359
}
360
 
361
void
362
cyg_hal_plf_comms_init(void)
363
{
364
    static int initialized = 0;
365
 
366
    if (initialized)
367
        return;
368
 
369
    initialized = 1;
370
 
371
    cyg_hal_plf_serial_init();
372
}
373
 
374
//=============================================================================
375
// Compatibility with older stubs
376
//=============================================================================
377
 
378
#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
379
 
380
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
381
#include <cyg/hal/drv_api.h>
382
#include <cyg/hal/hal_stub.h>           // cyg_hal_gdb_interrupt
383
#endif
384
 
385
// Assumption: all diagnostic output must be GDB packetized unless this is a ROM (i.e.
386
// totally stand-alone) system.
387
 
388
#if defined(CYG_HAL_STARTUP_ROM) || !defined(CYGDBG_HAL_DIAG_TO_DEBUG_CHAN)
389
#define HAL_DIAG_USES_HARDWARE
390
#endif
391
 
392
 
393
static channel_data_t aeb_ser_channel = {(cyg_uint8*)CYG_DEV_UART1_BASE, 0, 0};
394
 
395
#ifdef HAL_DIAG_USES_HARDWARE
396
 
397
void hal_diag_init(void)
398
{
399
    static int init = 0;
400
    char *msg = "\n\rAEB-1 eCos\n\r";
401
 
402
    if (init++) return;
403
 
404
    cyg_hal_plf_serial_init_channel(&aeb_ser_channel);
405
 
406
    while (*msg) cyg_hal_plf_serial_putc(&aeb_ser_channel, *msg++);
407
}
408
 
409
#ifdef DEBUG_DIAG
410
#if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
411
#define DIAG_BUFSIZE 32
412
#else
413
#define DIAG_BUFSIZE 2048
414
#endif
415
static char diag_buffer[DIAG_BUFSIZE];
416
static int diag_bp = 0;
417
#endif
418
 
419
void hal_diag_write_char(char c)
420
{
421
    hal_diag_init();
422
 
423
    cyg_hal_plf_serial_putc(&aeb_ser_channel, c);
424
 
425
#ifdef DEBUG_DIAG
426
    diag_buffer[diag_bp++] = c;
427
    if (diag_bp == DIAG_BUFSIZE) diag_bp = 0;
428
#endif
429
}
430
 
431
void hal_diag_read_char(char *c)
432
{
433
    *c = cyg_hal_plf_serial_getc(&aeb_ser_channel);
434
}
435
 
436
#else // HAL_DIAG relies on GDB
437
 
438
// Initialize diag port - assume GDB channel is already set up
439
void hal_diag_init(void)
440
{
441
    if (0) cyg_hal_plf_serial_init_channel(&aeb_ser_channel); // avoid warning
442
}
443
 
444
// Actually send character down the wire
445
static void
446
hal_diag_write_char_serial(char c)
447
{
448
    hal_diag_init();
449
 
450
    cyg_hal_plf_serial_putc(&aeb_ser_channel, c);
451
}
452
 
453
static bool
454
hal_diag_read_serial(char *c)
455
{
456
    long timeout = 1000000000;  // A long time...
457
    while (!cyg_hal_plf_serial_getc_nonblock(&aeb_ser_channel, c))
458
        if (0 == --timeout) return false;
459
 
460
    return true;
461
}
462
 
463
void
464
hal_diag_read_char(char *c)
465
{
466
    while (!hal_diag_read_serial(c)) ;
467
}
468
 
469
void
470
hal_diag_write_char(char c)
471
{
472
    static char line[100];
473
    static int pos = 0;
474
 
475
    // No need to send CRs
476
    if( c == '\r' ) return;
477
 
478
    line[pos++] = c;
479
 
480
    if( c == '\n' || pos == sizeof(line) )
481
    {
482
 
483
        CYG_INTERRUPT_STATE old;
484
 
485
        // Disable interrupts. This prevents GDB trying to interrupt us
486
        // while we are in the middle of sending a packet. The serial
487
        // receive interrupt will be seen when we re-enable interrupts
488
        // later.
489
 
490
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
491
        CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION(old);
492
#else
493
        HAL_DISABLE_INTERRUPTS(old);
494
#endif
495
 
496
        while(1)
497
        {
498
            static char hex[] = "0123456789ABCDEF";
499
            cyg_uint8 csum = 0;
500
            int i;
501
            char c1;
502
 
503
            hal_diag_write_char_serial('$');
504
            hal_diag_write_char_serial('O');
505
            csum += 'O';
506
            for( i = 0; i < pos; i++ )
507
            {
508
                char ch = line[i];
509
                char h = hex[(ch>>4)&0xF];
510
                char l = hex[ch&0xF];
511
                hal_diag_write_char_serial(h);
512
                hal_diag_write_char_serial(l);
513
                csum += h;
514
                csum += l;
515
            }
516
            hal_diag_write_char_serial('#');
517
            hal_diag_write_char_serial(hex[(csum>>4)&0xF]);
518
            hal_diag_write_char_serial(hex[csum&0xF]);
519
 
520
            // Wait for the ACK character '+' from GDB here and handle
521
            // receiving a ^C instead.  This is the reason for this clause
522
            // being a loop.
523
            if (!hal_diag_read_serial(&c1))
524
                continue;   // No response - try sending packet again
525
 
526
            if( c1 == '+' )
527
                break;              // a good acknowledge
528
 
529
#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
530
            cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_UART1);
531
            if( c1 == 3 ) {
532
                // Ctrl-C: breakpoint.
533
                cyg_hal_gdb_interrupt (__builtin_return_address(0));
534
                break;
535
            }
536
#endif
537
            // otherwise, loop round again
538
        }
539
 
540
        pos = 0;
541
 
542
 
543
        // And re-enable interrupts
544
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
545
        CYG_HAL_GDB_LEAVE_CRITICAL_IO_REGION(old);
546
#else
547
        HAL_RESTORE_INTERRUPTS(old);
548
#endif
549
 
550
    }
551
}
552
#endif
553
 
554
#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
555
 
556
 
557
/*---------------------------------------------------------------------------*/
558
/* End of hal_diag.c */

powered by: WebSVN 2.1.0

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