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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [i386/] [pcmb/] [v2_0/] [src/] [pcmb_serial.c] - Blame information for rev 584

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

Line No. Rev Author Line
1 27 unneback
//=============================================================================
2
//
3
//      pcmb_serial.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):   proven
44
// Contributors:proven
45
// Date:        1998-10-05
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
 
57
#include <cyg/hal/hal_arch.h>           // basic machine info
58
#include <cyg/hal/hal_intr.h>           // interrupt macros
59
#include <cyg/hal/hal_io.h>             // IO macros
60
#include <cyg/hal/drv_api.h>
61
#include <cyg/hal/hal_if.h>             // interface API
62
#include <cyg/hal/hal_misc.h>
63
 
64
#include <cyg/hal/pcmb_serial.h>
65
 
66
 
67
/*---------------------------------------------------------------------------*/
68
/* From serial_16550.h */
69
#if CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD==9600
70
#define CYG_DEVICE_SERIAL_BAUD_MSB        0x00
71
#define CYG_DEVICE_SERIAL_BAUD_LSB        0x0C
72
#endif
73
#if CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD==19200
74
#define CYG_DEVICE_SERIAL_BAUD_MSB        0x00
75
#define CYG_DEVICE_SERIAL_BAUD_LSB        0x06
76
#endif
77
#if CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD==38400
78
#define CYG_DEVICE_SERIAL_BAUD_MSB        0x00
79
#define CYG_DEVICE_SERIAL_BAUD_LSB        0x03
80
#endif
81
#if CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD==57600
82
#define CYG_DEVICE_SERIAL_BAUD_MSB        0x00
83
#define CYG_DEVICE_SERIAL_BAUD_LSB        0x02
84
#endif
85
#if CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD==115200
86
#define CYG_DEVICE_SERIAL_BAUD_MSB        0x00
87
#define CYG_DEVICE_SERIAL_BAUD_LSB        0x01
88
#endif
89
 
90
#ifndef CYG_DEVICE_SERIAL_BAUD_MSB
91
#error Missing/incorrect serial baud rate defined - CDL error?
92
#endif
93
 
94
// Define the serial registers.
95
#define CYG_DEV_RBR 0x00   // receiver buffer register, read, dlab = 0
96
#define CYG_DEV_THR 0x00   // transmitter holding register, write, dlab = 0
97
#define CYG_DEV_DLL 0x00   // divisor latch (LS), read/write, dlab = 1
98
#define CYG_DEV_IER 0x01   // interrupt enable register, read/write, dlab = 0
99
#define CYG_DEV_DLM 0x01   // divisor latch (MS), read/write, dlab = 1
100
#define CYG_DEV_IIR 0x02   // interrupt identification register, read, dlab = 0
101
#define CYG_DEV_FCR 0x02   // fifo control register, write, dlab = 0
102
#define CYG_DEV_LCR 0x03   // line control register, read/write
103
#define CYG_DEV_MCR 0x04   // modem control register, read/write
104
#define CYG_DEV_LSR 0x05   // line status register, read
105
#define CYG_DEV_MSR 0x06   // modem status register, read
106
 
107
// Interrupt Enable Register
108
#define SIO_IER_RCV 0x01
109
#define SIO_IER_XMT 0x02
110
#define SIO_IER_LS  0x04
111
#define SIO_IER_MS  0x08
112
 
113
// The line status register bits.
114
#define SIO_LSR_DR      0x01            // data ready
115
#define SIO_LSR_OE      0x02            // overrun error
116
#define SIO_LSR_PE      0x04            // parity error
117
#define SIO_LSR_FE      0x08            // framing error
118
#define SIO_LSR_BI      0x10            // break interrupt
119
#define SIO_LSR_THRE    0x20            // transmitter holding register empty
120
#define SIO_LSR_TEMT    0x40            // transmitter register empty
121
#define SIO_LSR_ERR     0x80            // any error condition
122
 
123
// The modem status register bits.
124
#define SIO_MSR_DCTS  0x01              // delta clear to send
125
#define SIO_MSR_DDSR  0x02              // delta data set ready
126
#define SIO_MSR_TERI  0x04              // trailing edge ring indicator
127
#define SIO_MSR_DDCD  0x08              // delta data carrier detect
128
#define SIO_MSR_CTS   0x10              // clear to send
129
#define SIO_MSR_DSR   0x20              // data set ready
130
#define SIO_MSR_RI    0x40              // ring indicator
131
#define SIO_MSR_DCD   0x80              // data carrier detect
132
 
133
// The line control register bits.
134
#define SIO_LCR_WLS0   0x01             // word length select bit 0
135
#define SIO_LCR_WLS1   0x02             // word length select bit 1
136
#define SIO_LCR_STB    0x04             // number of stop bits
137
#define SIO_LCR_PEN    0x08             // parity enable
138
#define SIO_LCR_EPS    0x10             // even parity select
139
#define SIO_LCR_SP     0x20             // stick parity
140
#define SIO_LCR_SB     0x40             // set break
141
#define SIO_LCR_DLAB   0x80             // divisor latch access bit
142
 
143
// Modem Control Register
144
#define SIO_MCR_DTR 0x01
145
#define SIO_MCR_RTS 0x02
146
#define SIO_MCR_INT 0x08   // Enable interrupts
147
 
148
//=============================================================================
149
// Basic channel functions
150
 
151
static void
152
cyg_hal_plf_serial_init_channel(void* __ch_data)
153
{
154
    cyg_uint16 base = ((channel_data_t*)__ch_data)->base;
155
    cyg_uint8 lsr;
156
 
157
    HAL_WRITE_UINT8(base+CYG_DEV_IER, 0);
158
    HAL_WRITE_UINT8(base+CYG_DEV_IER, 0);
159
    HAL_WRITE_UINT8(base+CYG_DEV_MCR, 0);
160
 
161
    HAL_WRITE_UINT8(base+CYG_DEV_LCR, SIO_LCR_DLAB);
162
    HAL_WRITE_UINT8(base+CYG_DEV_DLL, CYG_DEVICE_SERIAL_BAUD_LSB);
163
    HAL_WRITE_UINT8(base+CYG_DEV_DLM, CYG_DEVICE_SERIAL_BAUD_MSB);
164
    // 8-1-no parity.
165
    HAL_WRITE_UINT8(base+CYG_DEV_LCR, SIO_LCR_WLS0 | SIO_LCR_WLS1);
166
 
167
    // Test whether the channel is valid or not. If the status
168
    // register reads back all ones, its a fair bet that it is not
169
    // actually there!
170
    HAL_READ_UINT8(base+CYG_DEV_LSR, lsr);
171
    ((channel_data_t*)__ch_data)->valid = (lsr != 0xFF);
172
 
173
//    HAL_WRITE_UINT8(base+CYG_DEV_FCR, 0x07);  // Enable & clear FIFO
174
}
175
 
176
//-----------------------------------------------------------------------------
177
 
178
void
179
cyg_hal_plf_serial_putc(void *__ch_data, char c)
180
{
181
    cyg_uint16 base = ((channel_data_t*)__ch_data)->base;
182
    cyg_uint8 lsr;
183
 
184
    if( !((channel_data_t*)__ch_data)->valid )
185
            return;
186
 
187
    CYGARC_HAL_SAVE_GP();
188
    do {
189
        HAL_READ_UINT8(base+CYG_DEV_LSR, lsr);
190
    } while ((lsr & SIO_LSR_THRE) == 0);
191
 
192
    HAL_WRITE_UINT8(base+CYG_DEV_THR, c);
193
 
194
    CYGARC_HAL_RESTORE_GP();
195
}
196
 
197
//-----------------------------------------------------------------------------
198
 
199
static cyg_bool
200
cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch)
201
{
202
    cyg_uint16 base = ((channel_data_t*)__ch_data)->base;
203
    cyg_uint8 lsr;
204
 
205
    if( !((channel_data_t*)__ch_data)->valid )
206
            return false;
207
 
208
    HAL_READ_UINT8(base+CYG_DEV_LSR, lsr);
209
    if ((lsr & SIO_LSR_DR) == 0)
210
        return false;
211
 
212
    HAL_READ_UINT8(base+CYG_DEV_RBR, *ch);
213
 
214
    return true;
215
}
216
 
217
//-----------------------------------------------------------------------------
218
 
219
cyg_uint8
220
cyg_hal_plf_serial_getc(void* __ch_data)
221
{
222
    cyg_uint8 ch;
223
 
224
    if( !((channel_data_t*)__ch_data)->valid )
225
            return '\n';
226
 
227
    CYGARC_HAL_SAVE_GP();
228
 
229
    while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
230
 
231
    CYGARC_HAL_RESTORE_GP();
232
 
233
    return ch;
234
}
235
 
236
//=============================================================================
237
// Call IF support
238
 
239
#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \
240
    || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES)
241
 
242
static void
243
cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf,
244
                         cyg_uint32 __len)
245
{
246
    CYGARC_HAL_SAVE_GP();
247
 
248
    while(__len-- > 0)
249
        cyg_hal_plf_serial_putc(__ch_data, *__buf++);
250
 
251
    CYGARC_HAL_RESTORE_GP();
252
}
253
 
254
static void
255
cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
256
{
257
    CYGARC_HAL_SAVE_GP();
258
 
259
    while(__len-- > 0)
260
        *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
261
 
262
    CYGARC_HAL_RESTORE_GP();
263
}
264
 
265
static cyg_bool
266
cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
267
{
268
    int delay_count;
269
    channel_data_t* chan = (channel_data_t*)__ch_data;
270
    cyg_bool res;
271
    CYGARC_HAL_SAVE_GP();
272
 
273
    delay_count = chan->msec_timeout * 10; // delay in .1 ms steps
274
 
275
    for(;;) {
276
        res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
277
        if (res || 0 == delay_count--)
278
            break;
279
 
280
        CYGACC_CALL_IF_DELAY_US(100);
281
    }
282
 
283
    CYGARC_HAL_RESTORE_GP();
284
    return res;
285
}
286
 
287
 
288
static int
289
cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
290
{
291
    static int irq_state = 0;
292
    channel_data_t* chan = (channel_data_t*)__ch_data;
293
    int ret = 0;
294
    CYGARC_HAL_SAVE_GP();
295
 
296
    switch (__func) {
297
    case __COMMCTL_IRQ_ENABLE:
298
        irq_state = 1;
299
 
300
        HAL_WRITE_UINT8(chan->base+CYG_DEV_IER, SIO_IER_RCV);
301
        HAL_WRITE_UINT8(chan->base+CYG_DEV_MCR, SIO_MCR_INT|SIO_MCR_DTR|SIO_MCR_RTS);
302
 
303
        HAL_INTERRUPT_UNMASK(chan->isr_vector);
304
        break;
305
    case __COMMCTL_IRQ_DISABLE:
306
        ret = irq_state;
307
        irq_state = 0;
308
 
309
        HAL_WRITE_UINT8(chan->base+CYG_DEV_IER, 0);
310
 
311
        HAL_INTERRUPT_MASK(chan->isr_vector);
312
        break;
313
    case __COMMCTL_DBG_ISR_VECTOR:
314
        ret = chan->isr_vector;
315
        break;
316
    case __COMMCTL_SET_TIMEOUT:
317
    {
318
        va_list ap;
319
 
320
        va_start(ap, __func);
321
 
322
        ret = chan->msec_timeout;
323
        chan->msec_timeout = va_arg(ap, cyg_uint32);
324
 
325
        va_end(ap);
326
    }
327
    default:
328
        break;
329
    }
330
 
331
 
332
    CYGARC_HAL_RESTORE_GP();
333
    return ret;
334
}
335
 
336
static int
337
cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc,
338
                       CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
339
{
340
    int res = 0;
341
    channel_data_t* chan = (channel_data_t*)__ch_data;
342
    char c;
343
    cyg_uint8 lsr;
344
    CYGARC_HAL_SAVE_GP();
345
 
346
    cyg_drv_interrupt_acknowledge(chan->isr_vector);
347
 
348
    *__ctrlc = 0;
349
    HAL_READ_UINT8(chan->base+CYG_DEV_LSR, lsr);
350
    if ( (lsr & SIO_LSR_DR) != 0 ) {
351
 
352
        HAL_READ_UINT8(chan->base+CYG_DEV_RBR, c);
353
        if( cyg_hal_is_break( &c , 1 ) )
354
            *__ctrlc = 1;
355
 
356
    }
357
 
358
    res = CYG_ISR_HANDLED;
359
 
360
    CYGARC_HAL_RESTORE_GP();
361
    return res;
362
}
363
 
364
void cyg_hal_plf_serial_init(void)
365
{
366
    hal_virtual_comm_table_t* comm;
367
    int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
368
    int i, num_serial = CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS;
369
 
370
#ifdef CYGSEM_HAL_I386_PC_DIAG_SCREEN
371
    --num_serial;
372
#endif
373
 
374
    for (i = 0; i < num_serial; i++) {
375
        // Disable interrupts.
376
        HAL_INTERRUPT_MASK(pc_ser_channels[i].isr_vector);
377
 
378
        // Init
379
        cyg_hal_plf_serial_init_channel(&pc_ser_channels[i]);
380
 
381
        // Setup procs in the vector table
382
 
383
        // Set channel 0
384
        CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
385
        comm = CYGACC_CALL_IF_CONSOLE_PROCS();
386
        CYGACC_COMM_IF_CH_DATA_SET(*comm, &pc_ser_channels[i]);
387
        CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
388
        CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
389
        CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
390
        CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
391
        CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
392
        CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
393
        CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
394
    }
395
 
396
    // Restore original console
397
    CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
398
}
399
 
400
#endif  //defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG)
401
        //  || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES)
402
 
403
//-----------------------------------------------------------------------------
404
// End of pcmb_serial.c

powered by: WebSVN 2.1.0

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