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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [powerpc/] [csb281/] [v2_0/] [src/] [hal_diag.c] - Blame information for rev 279

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 I/O 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
// Copyright (C) 2002, 2003 Gary Thomas
13
//
14
// eCos is free software; you can redistribute it and/or modify it under
15
// the terms of the GNU General Public License as published by the Free
16
// Software Foundation; either version 2 or (at your option) any later version.
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19
// 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 along
24
// with eCos; if not, write to the Free Software Foundation, Inc.,
25
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26
//
27
// As a special exception, if other files instantiate templates or use macros
28
// or inline functions from this file, or you compile this file and link it
29
// with other works to produce a work based on this file, this file does not
30
// by itself cause the resulting work to be covered by the GNU General Public
31
// License. However the source code for this file must still be made available
32
// in accordance with section (3) of the GNU General Public License.
33
//
34
// This exception does not invalidate any other reasons why a work based on
35
// this file might be covered by the GNU General Public License.
36
//
37
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
38
// at http://sources.redhat.com/ecos/ecos-license/
39
// -------------------------------------------
40
//####ECOSGPLCOPYRIGHTEND####
41
//=============================================================================
42
//#####DESCRIPTIONBEGIN####
43
//
44
// Author(s):   hmt
45
// Contributors:hmt, gthomas
46
// Date:        1999-06-08
47
// Purpose:     HAL diagnostic output
48
// Description: Implementations of HAL diagnostic I/O support.
49
//
50
//####DESCRIPTIONEND####
51
//
52
//=============================================================================
53
 
54
#include <pkgconf/hal.h>
55
 
56
#include <cyg/infra/cyg_type.h>         // base types
57
#include <cyg/infra/cyg_trac.h>         // tracing macros
58
#include <cyg/infra/cyg_ass.h>          // assertion macros
59
 
60
#include <cyg/hal/hal_io.h>             // IO macros
61
#include <cyg/hal/hal_diag.h>
62
#include <cyg/hal/hal_misc.h>           // cyg_hal_is_break()
63
#include <cyg/hal/hal_intr.h>           // Interrupt macros
64
#include <cyg/hal/drv_api.h>
65
 
66
#if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
67
#include <cyg/hal/hal_stub.h>           // hal_output_gdb_string
68
#endif
69
 
70
#include <cyg/hal/ppc_regs.h>
71
 
72
//=============================================================================
73
// Serial driver
74
//=============================================================================
75
 
76
//-----------------------------------------------------------------------------
77
// There are two serial ports.
78
#define CYG_DEV_SERIAL_BASE_A    0xF0004500 // port A
79
#define CYG_DEV_SERIAL_BASE_B    0xF0004600 // port B
80
 
81
//-----------------------------------------------------------------------------
82
// Default baud rate is 38400
83
#define _MEMCLK (CYGHWR_HAL_POWERPC_MEM_SPEED*1000000)
84
#define _BAUD   CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD
85
#define CYG_DEV_SERIAL_RS232_T1_VALUE_B38400  (((_MEMCLK/16)/_BAUD) >> 8)
86
#define CYG_DEV_SERIAL_RS232_T2_VALUE_B38400  (((_MEMCLK/16)/_BAUD) & 0xFF)
87
 
88
//-----------------------------------------------------------------------------
89
// Define the serial registers. The 8245 has a 16552 UART builtin.
90
//
91
#define CYG_DEV_SERIAL_RBR   0x00  // receiver buffer register, read, dlab = 0
92
#define CYG_DEV_SERIAL_THR   0x00 // transmitter holding register, write, dlab = 0
93
#define CYG_DEV_SERIAL_DLL   0x00 // divisor latch (LS), read/write, dlab = 1
94
#define CYG_DEV_SERIAL_IER   0x01 // interrupt enable register, read/write, dlab = 0
95
#define CYG_DEV_SERIAL_DLM   0x01 // divisor latch (MS), read/write, dlab = 1
96
#define CYG_DEV_SERIAL_IIR   0x02 // interrupt identification register, read, dlab = 0
97
#define CYG_DEV_SERIAL_FCR   0x02 // fifo control register, write, dlab = 0
98
#define CYG_DEV_SERIAL_AFR   0x02 // alternate function register, read/write, dlab = 1
99
#define CYG_DEV_SERIAL_LCR   0x03 // line control register, read/write
100
#define CYG_DEV_SERIAL_MCR   0x04
101
#define CYG_DEV_SERIAL_MCR_A 0x04
102
#define CYG_DEV_SERIAL_MCR_B 0x04
103
#define CYG_DEV_SERIAL_LSR   0x05 // line status register, read
104
#define CYG_DEV_SERIAL_MSR   0x06 // modem status register, read
105
#define CYG_DEV_SERIAL_SCR   0x07 // scratch pad register
106
#define CYG_DEV_SERIAL_DCR   0x11 // device control (UART vs DUART)
107
 
108
// The interrupt enable register bits.
109
#define SIO_IER_ERDAI   0x01            // enable received data available irq
110
#define SIO_IER_ETHREI  0x02            // enable THR empty interrupt
111
#define SIO_IER_ELSI    0x04            // enable receiver line status irq
112
#define SIO_IER_EMSI    0x08            // enable modem status interrupt
113
 
114
// The interrupt identification register bits.
115
#define SIO_IIR_IP      0x01            // 0 if interrupt pending
116
#define SIO_IIR_ID_MASK 0x0e            // mask for interrupt ID bits
117
#define ISR_Tx  0x02
118
#define ISR_Rx  0x04
119
 
120
// The line status register bits.
121
#define SIO_LSR_DR      0x01            // data ready
122
#define SIO_LSR_OE      0x02            // overrun error
123
#define SIO_LSR_PE      0x04            // parity error
124
#define SIO_LSR_FE      0x08            // framing error
125
#define SIO_LSR_BI      0x10            // break interrupt
126
#define SIO_LSR_THRE    0x20            // transmitter holding register empty
127
#define SIO_LSR_TEMT    0x40            // transmitter register empty
128
#define SIO_LSR_ERR     0x80            // any error condition
129
 
130
// The modem status register bits.
131
#define SIO_MSR_DCTS  0x01              // delta clear to send
132
#define SIO_MSR_DDSR  0x02              // delta data set ready
133
#define SIO_MSR_TERI  0x04              // trailing edge ring indicator
134
#define SIO_MSR_DDCD  0x08              // delta data carrier detect
135
#define SIO_MSR_CTS   0x10              // clear to send
136
#define SIO_MSR_DSR   0x20              // data set ready
137
#define SIO_MSR_RI    0x40              // ring indicator
138
#define SIO_MSR_DCD   0x80              // data carrier detect
139
 
140
// The line control register bits.
141
#define SIO_LCR_WLS0   0x01             // word length select bit 0
142
#define SIO_LCR_WLS1   0x02             // word length select bit 1
143
#define SIO_LCR_STB    0x04             // number of stop bits
144
#define SIO_LCR_PEN    0x08             // parity enable
145
#define SIO_LCR_EPS    0x10             // even parity select
146
#define SIO_LCR_SP     0x20             // stick parity
147
#define SIO_LCR_SB     0x40             // set break
148
#define SIO_LCR_DLAB   0x80             // divisor latch access bit
149
 
150
// The FIFO control register
151
#define SIO_FCR_FEN    0x01             // enable xmit and rcvr fifos
152
#define SIO_FCR_RFR    0x02             // clear RCVR FIFO
153
#define SIO_FCR_TFR    0x04             // clear XMIT FIFO
154
 
155
// DUART control
156
#define SIO_DCR_SDM    0x01             // Special DUART mode
157
 
158
 
159
//-----------------------------------------------------------------------------
160
typedef struct {
161
    cyg_uint8* base;
162
    cyg_int32 msec_timeout;
163
    int isr_vector;
164
} channel_data_t;
165
 
166
//-----------------------------------------------------------------------------
167
static void
168
init_serial_channel(const channel_data_t* __ch_data)
169
{
170
    cyg_uint8* base = __ch_data->base;
171
    cyg_uint8 lcr, iir;
172
 
173
    HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_IER, 0);
174
 
175
    // Disable and clear FIFOs (need to enable to clear).
176
    HAL_READ_UINT8(base+CYG_DEV_SERIAL_IIR, iir);
177
    if ((iir & 0xC0) == 0) {
178
        HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_FCR, (SIO_FCR_FEN | SIO_FCR_RFR | SIO_FCR_TFR));
179
        HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_FCR, 0);
180
    }
181
 
182
    // 8-1-no parity.
183
    HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_LCR, SIO_LCR_WLS0 | SIO_LCR_WLS1);
184
 
185
    // Set speed to 38400.
186
    HAL_READ_UINT8(base+CYG_DEV_SERIAL_LCR, lcr);
187
    lcr |= SIO_LCR_DLAB;
188
    HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_LCR, lcr);
189
 
190
 
191
    HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_DLL,
192
                    CYG_DEV_SERIAL_RS232_T2_VALUE_B38400);
193
    HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_DLM,
194
                    CYG_DEV_SERIAL_RS232_T1_VALUE_B38400);
195
    lcr &= ~SIO_LCR_DLAB;
196
    HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_LCR, lcr);
197
 
198
    HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_DCR, SIO_DCR_SDM);
199
 
200
    // Enable FIFOs (and clear them).
201
    if ((iir & 0xC0) == 0) {
202
        HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_FCR, (SIO_FCR_FEN | SIO_FCR_RFR | SIO_FCR_TFR));
203
    }
204
}
205
 
206
static void
207
cyg_hal_plf_serial_error(void *__ch_data, cyg_uint8 lsr)
208
{
209
    // Ignore?
210
}
211
 
212
static cyg_bool
213
cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch)
214
{
215
    cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
216
    cyg_uint8 lsr;
217
 
218
    HAL_READ_UINT8(base+CYG_DEV_SERIAL_LSR, lsr);
219
    if ((lsr & SIO_LSR_ERR) != 0) {
220
        cyg_hal_plf_serial_error(__ch_data, lsr);
221
    }
222
    if ((lsr & SIO_LSR_DR) == 0)
223
        return false;
224
 
225
    HAL_READ_UINT8(base+CYG_DEV_SERIAL_RBR, *ch);
226
 
227
    return true;
228
}
229
 
230
 
231
cyg_uint8
232
cyg_hal_plf_serial_getc(void* __ch_data)
233
{
234
    cyg_uint8 ch;
235
    CYGARC_HAL_SAVE_GP();
236
 
237
    while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
238
 
239
    CYGARC_HAL_RESTORE_GP();
240
    return ch;
241
}
242
 
243
void
244
cyg_hal_plf_serial_putc(void* __ch_data, cyg_uint8 c)
245
{
246
    cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
247
    cyg_uint8 lsr;
248
    CYGARC_HAL_SAVE_GP();
249
 
250
    do {
251
        HAL_READ_UINT8(base+CYG_DEV_SERIAL_LSR, lsr);
252
    } while ((lsr & SIO_LSR_THRE) == 0);
253
 
254
    HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_THR, c);
255
 
256
    // Hang around until the character has been safely sent.
257
    do {
258
        HAL_READ_UINT8(base+CYG_DEV_SERIAL_LSR, lsr);
259
    } while ((lsr & SIO_LSR_THRE) == 0);
260
 
261
    CYGARC_HAL_RESTORE_GP();
262
}
263
 
264
static const channel_data_t channels[2] = {
265
    { (cyg_uint8*)CYG_DEV_SERIAL_BASE_A, 1000, CYGNUM_HAL_INTERRUPT_UART0},
266
#if (CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 1)
267
    { (cyg_uint8*)CYG_DEV_SERIAL_BASE_B, 1000, CYGNUM_HAL_INTERRUPT_UART1},
268
#endif
269
};
270
 
271
static void
272
cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf,
273
                         cyg_uint32 __len)
274
{
275
    CYGARC_HAL_SAVE_GP();
276
 
277
    while(__len-- > 0)
278
        cyg_hal_plf_serial_putc(__ch_data, *__buf++);
279
 
280
    CYGARC_HAL_RESTORE_GP();
281
}
282
 
283
static void
284
cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
285
{
286
    CYGARC_HAL_SAVE_GP();
287
 
288
    while(__len-- > 0)
289
        *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
290
 
291
    CYGARC_HAL_RESTORE_GP();
292
}
293
 
294
cyg_bool
295
cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
296
{
297
    int delay_count;
298
    channel_data_t* chan = (channel_data_t*)__ch_data;
299
    cyg_bool res;
300
    CYGARC_HAL_SAVE_GP();
301
 
302
    delay_count = chan->msec_timeout * 10; // delay in .1 ms steps
303
    for(;;) {
304
        res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
305
        if (res || 0 == delay_count--)
306
            break;
307
 
308
        CYGACC_CALL_IF_DELAY_US(100);
309
    }
310
 
311
    CYGARC_HAL_RESTORE_GP();
312
    return res;
313
}
314
 
315
static int
316
cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
317
{
318
    static int irq_state = 0;
319
    channel_data_t* chan = (channel_data_t*)__ch_data;
320
    cyg_uint8 ier;
321
    int ret = 0;
322
    CYGARC_HAL_SAVE_GP();
323
 
324
    switch (__func) {
325
    case __COMMCTL_IRQ_ENABLE:
326
        HAL_INTERRUPT_UNMASK(chan->isr_vector);
327
        HAL_INTERRUPT_SET_LEVEL(chan->isr_vector, 1);
328
        HAL_READ_UINT8(chan->base+CYG_DEV_SERIAL_IER, ier);
329
        ier |= SIO_IER_ERDAI;
330
        HAL_WRITE_UINT8(chan->base+CYG_DEV_SERIAL_IER, ier);
331
        irq_state = 1;
332
        break;
333
    case __COMMCTL_IRQ_DISABLE:
334
        ret = irq_state;
335
        irq_state = 0;
336
        HAL_INTERRUPT_MASK(chan->isr_vector);
337
        HAL_READ_UINT8(chan->base+CYG_DEV_SERIAL_IER, ier);
338
        ier &= ~SIO_IER_ERDAI;
339
        HAL_WRITE_UINT8(chan->base+CYG_DEV_SERIAL_IER, ier);
340
        break;
341
    case __COMMCTL_DBG_ISR_VECTOR:
342
        ret = chan->isr_vector;
343
        break;
344
    case __COMMCTL_SET_TIMEOUT:
345
    {
346
        va_list ap;
347
 
348
        va_start(ap, __func);
349
 
350
        ret = chan->msec_timeout;
351
        chan->msec_timeout = va_arg(ap, cyg_uint32);
352
 
353
        va_end(ap);
354
    }
355
    default:
356
        break;
357
    }
358
    CYGARC_HAL_RESTORE_GP();
359
    return ret;
360
}
361
 
362
static int
363
cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc,
364
                       CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
365
{
366
    channel_data_t* chan = (channel_data_t*)__ch_data;
367
    cyg_uint8 _iir;
368
    int res = 0;
369
    CYGARC_HAL_SAVE_GP();
370
 
371
    HAL_READ_UINT8(chan->base+CYG_DEV_SERIAL_IIR, _iir);
372
    _iir &= SIO_IIR_ID_MASK;
373
 
374
    *__ctrlc = 0;
375
    if ( ISR_Rx == _iir ) {
376
        cyg_uint8 c, lsr;
377
        HAL_READ_UINT8(chan->base+CYG_DEV_SERIAL_LSR, lsr);
378
        if (lsr & SIO_LSR_DR) {
379
 
380
            HAL_READ_UINT8(chan->base+CYG_DEV_SERIAL_RBR, c);
381
 
382
            if( cyg_hal_is_break( &c , 1 ) )
383
                *__ctrlc = 1;
384
        }
385
 
386
        // Acknowledge the interrupt
387
        HAL_INTERRUPT_ACKNOWLEDGE(chan->isr_vector);
388
        res = CYG_ISR_HANDLED;
389
    }
390
 
391
    CYGARC_HAL_RESTORE_GP();
392
    return res;
393
}
394
 
395
static void
396
cyg_hal_plf_serial_init(void)
397
{
398
    hal_virtual_comm_table_t* comm;
399
    int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
400
 
401
    // Disable interrupts.
402
    HAL_INTERRUPT_MASK(channels[0].isr_vector);
403
#if (CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 1)
404
    HAL_INTERRUPT_MASK(channels[1].isr_vector);
405
#endif
406
 
407
    // Init channels
408
    init_serial_channel(&channels[0]);
409
#if (CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 1)
410
    init_serial_channel(&channels[1]);
411
#endif
412
 
413
    // Setup procs in the vector table
414
 
415
    // Set channel 0
416
    CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
417
    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
418
    CYGACC_COMM_IF_CH_DATA_SET(*comm, &channels[0]);
419
    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
420
    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
421
    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
422
    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
423
    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
424
    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
425
    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
426
 
427
#if (CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 1)
428
    // Set channel 1
429
    CYGACC_CALL_IF_SET_CONSOLE_COMM(1);
430
    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
431
    CYGACC_COMM_IF_CH_DATA_SET(*comm, &channels[1]);
432
    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
433
    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
434
    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
435
    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
436
    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
437
    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
438
    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
439
#endif
440
 
441
    // Restore original console
442
    CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
443
}
444
 
445
void
446
cyg_hal_plf_comms_init(void)
447
{
448
    static int initialized = 0;
449
 
450
    if (initialized)
451
        return;
452
    initialized = 1;
453
 
454
    cyg_hal_plf_serial_init();
455
}
456
 
457
// EOF hal_diag.c

powered by: WebSVN 2.1.0

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