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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [arm/] [aeb/] [current/] [src/] [hal_diag.c] - Blame information for rev 856

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

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