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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [mips/] [ref4955/] [v2_0/] [src/] [pc87338.c] - Blame information for rev 27

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

Line No. Rev Author Line
1 27 unneback
#ifndef CYGONCE_HAL_PC_SER_H
2
#define CYGONCE_HAL_PC_SER_H
3
//=============================================================================
4
//
5
//      pc87338.c
6
//
7
//      Simple driver for the serial controllers in the PC87338 SuperIO chip
8
//
9
//=============================================================================
10
//####ECOSGPLCOPYRIGHTBEGIN####
11
// -------------------------------------------
12
// This file is part of eCos, the Embedded Configurable Operating System.
13
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
14
//
15
// eCos is free software; you can redistribute it and/or modify it under
16
// the terms of the GNU General Public License as published by the Free
17
// Software Foundation; either version 2 or (at your option) any later version.
18
//
19
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
20
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
21
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
22
// for more details.
23
//
24
// You should have received a copy of the GNU General Public License along
25
// with eCos; if not, write to the Free Software Foundation, Inc.,
26
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27
//
28
// As a special exception, if other files instantiate templates or use macros
29
// or inline functions from this file, or you compile this file and link it
30
// with other works to produce a work based on this file, this file does not
31
// by itself cause the resulting work to be covered by the GNU General Public
32
// License. However the source code for this file must still be made available
33
// in accordance with section (3) of the GNU General Public License.
34
//
35
// This exception does not invalidate any other reasons why a work based on
36
// this file might be covered by the GNU General Public License.
37
//
38
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
39
// at http://sources.redhat.com/ecos/ecos-license/
40
// -------------------------------------------
41
//####ECOSGPLCOPYRIGHTEND####
42
//=============================================================================
43
//#####DESCRIPTIONBEGIN####
44
//
45
// Author(s):   jskov
46
// Contributors:jskov
47
// Date:        2000-06-20
48
// Description: Simple driver for the PC87338 serial controllers
49
//
50
//####DESCRIPTIONEND####
51
//
52
//=============================================================================
53
 
54
#include <pkgconf/hal.h>
55
 
56
#include <cyg/hal/hal_arch.h>           // SAVE/RESTORE GP macros
57
#include <cyg/hal/hal_io.h>             // IO macros
58
#include <cyg/hal/hal_if.h>             // interface API
59
#include <cyg/hal/hal_intr.h>           // HAL_ENABLE/MASK/UNMASK_INTERRUPTS
60
#include <cyg/hal/hal_misc.h>           // Helper functions
61
#include <cyg/hal/drv_api.h>            // CYG_ISR_HANDLED
62
 
63
//-----------------------------------------------------------------------------
64
// Controller definitions.
65
 
66
//-----------------------------------------------------------------------------
67
// There are two serial ports.
68
#define CYG_DEVICE_SERIAL_SCC1    0xb40003f8 // port 1
69
#define CYG_DEVICE_SERIAL_SCC2    0xb40002f8 // port 2
70
 
71
//-----------------------------------------------------------------------------
72
// Serial registers (shared by all banks)
73
#define CYG_DEVICE_BSR       (0x03)
74
#define CYG_DEVICE_LCR       (0x03)
75
 
76
#define CYG_DEVICE_BSR_BANK0 0x00
77
#define CYG_DEVICE_BSR_BANK2 0xe0
78
 
79
#define CYG_DEVICE_LCR_LEN_5BIT       0x00
80
#define CYG_DEVICE_LCR_LEN_6BIT       0x01
81
#define CYG_DEVICE_LCR_LEN_7BIT       0x02
82
#define CYG_DEVICE_LCR_LEN_8BIT       0x03
83
#define CYG_DEVICE_LCR_STOP_1         0x00
84
#define CYG_DEVICE_LCR_STOP_2         0x04
85
#define CYG_DEVICE_LCR_PARITY_NONE    0x00
86
#define CYG_DEVICE_LCR_PARITY_ODD     0x08
87
#define CYG_DEVICE_LCR_PARITY_EVEN    0x18
88
#define CYG_DEVICE_LCR_PARITY_LOGIC1  0x28
89
#define CYG_DEVICE_LCR_PARITY_LOGIC0  0x38
90
#define CYG_DEVICE_LCR_SBRK           0x40
91
 
92
// Bank 0 (control/status)
93
#define CYG_DEVICE_BK0_TXD   (0x00)
94
#define CYG_DEVICE_BK0_RXD   (0x00)
95
#define CYG_DEVICE_BK0_IER   (0x01)
96
#define CYG_DEVICE_BK0_EIR   (0x02)
97
#define CYG_DEVICE_BK0_FCR   (0x02)
98
#define CYG_DEVICE_BK0_MCR   (0x04)
99
#define CYG_DEVICE_BK0_LSR   (0x05)
100
#define CYG_DEVICE_BK0_MSR   (0x06)
101
#define CYG_DEVICE_BK0_SPR   (0x07)
102
#define CYG_DEVICE_BK0_ASCR  (0x07)
103
 
104
#define CYG_DEVICE_BK0_LSR_RXDA       0x01
105
#define CYG_DEVICE_BK0_LSR_OE         0x02
106
#define CYG_DEVICE_BK0_LSR_PE         0x04
107
#define CYG_DEVICE_BK0_LSR_FE         0x08
108
#define CYG_DEVICE_BK0_LSR_BRK        0x10
109
#define CYG_DEVICE_BK0_LSR_TXRDY      0x20
110
#define CYG_DEVICE_BK0_LSR_TXEMP      0x40
111
#define CYG_DEVICE_BK0_LSR_ER_INF     0x80
112
 
113
#define CYG_DEVICE_BK0_IER_TMR_IE     0x80
114
#define CYG_DEVICE_BK0_IER_SFIF_IE    0x40
115
#define CYG_DEVICE_BK0_IER_TXEMP_IE   0x20
116
#define CYG_DEVICE_BK0_IER_DMA_IE     0x10
117
#define CYG_DEVICE_BK0_IER_MS_IE      0x08
118
#define CYG_DEVICE_BK0_IER_LS_IE      0x04
119
#define CYG_DEVICE_BK0_IER_TXLDL_IE   0x02
120
#define CYG_DEVICE_BK0_IER_RXHDL_IE   0x01
121
 
122
#define CYG_DEVICE_BK0_EIR_FEN1       0x80
123
#define CYG_DEVICE_BK0_EIR_FEN0       0x40
124
#define CYG_DEVICE_BK0_EIR_RXFT       0x08
125
#define CYG_DEVICE_BK0_EIR_IPR1       0x04
126
#define CYG_DEVICE_BK0_EIR_IPR0       0x02
127
#define CYG_DEVICE_BK0_EIR_IPF        0x01
128
 
129
#define CYG_DEVICE_BK0_EIR_mask       0x07
130
#define CYG_DEVICE_BK0_EIR_IRQ_ERR    0x06
131
#define CYG_DEVICE_BK0_EIR_IRQ_RX     0x04
132
#define CYG_DEVICE_BK0_EIR_IRQ_TX     0x02
133
 
134
#define CYG_DEVICE_BK0_MCR_ISEN       0x08 // interrupt signal enable
135
 
136
 
137
// Bank 2 (baud generator)
138
#define CYG_DEVICE_BK2_BGDL  (0x00)
139
#define CYG_DEVICE_BK2_BGDH  (0x01)
140
#define CYG_DEVICE_BK2_EXCR1 (0x02)
141
#define CYG_DEVICE_BK2_EXCR2 (0x04)
142
#define CYG_DEVICE_BK2_TXFLV (0x06)
143
#define CYG_DEVICE_BK2_RXFLV (0x07)
144
 
145
 
146
//-----------------------------------------------------------------------------
147
typedef struct {
148
    cyg_uint8* base;
149
    cyg_int32 msec_timeout;
150
    int isr_vector;
151
} channel_data_t;
152
 
153
//-----------------------------------------------------------------------------
154
// The minimal init, get and put functions. All by polling.
155
 
156
void
157
cyg_hal_plf_serial_init_channel(void* __ch_data)
158
{
159
    cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
160
    cyg_uint8 lcr;
161
 
162
    HAL_WRITE_UINT8(base+CYG_DEVICE_BSR, CYG_DEVICE_BSR_BANK0);
163
    HAL_WRITE_UINT8(base+CYG_DEVICE_BK0_IER, 0);
164
    HAL_WRITE_UINT8(base+CYG_DEVICE_BK0_MCR, CYG_DEVICE_BK0_MCR_ISEN);
165
 
166
    // Disable FIFOs
167
    HAL_WRITE_UINT8(base+CYG_DEVICE_BK0_FCR, 0);
168
 
169
    // 8-1-no parity.
170
    HAL_WRITE_UINT8(base+CYG_DEVICE_LCR,
171
                    CYG_DEVICE_LCR_LEN_8BIT | CYG_DEVICE_LCR_STOP_1 | CYG_DEVICE_LCR_PARITY_NONE);
172
 
173
    // Set speed to 38400 (switch bank, remember old LCR setting)
174
    HAL_READ_UINT8(base+CYG_DEVICE_LCR, lcr);
175
    HAL_WRITE_UINT8(base+CYG_DEVICE_BSR, CYG_DEVICE_BSR_BANK2);
176
    HAL_WRITE_UINT8(base+CYG_DEVICE_BK2_BGDL, 3);
177
    HAL_WRITE_UINT8(base+CYG_DEVICE_BK2_BGDH, 0);
178
    HAL_WRITE_UINT8(base+CYG_DEVICE_LCR, lcr);
179
}
180
 
181
void
182
cyg_hal_plf_serial_putc(void* __ch_data, cyg_uint8 __ch)
183
{
184
    cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
185
    cyg_uint8 lsr;
186
    CYGARC_HAL_SAVE_GP();
187
 
188
    do {
189
        HAL_READ_UINT8(base+CYG_DEVICE_BK0_LSR, lsr);
190
    } while ((lsr & CYG_DEVICE_BK0_LSR_TXRDY) == 0);
191
 
192
    HAL_WRITE_UINT8(base+CYG_DEVICE_BK0_TXD, __ch);
193
 
194
    // Hang around until the character has been safely sent.
195
    do {
196
        HAL_READ_UINT8(base+CYG_DEVICE_BK0_LSR, lsr);
197
    } while ((lsr & CYG_DEVICE_BK0_LSR_TXRDY) == 0);
198
 
199
    CYGARC_HAL_RESTORE_GP();
200
}
201
 
202
static cyg_bool
203
cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch)
204
{
205
    cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
206
    cyg_uint8 lsr;
207
 
208
    HAL_READ_UINT8(base+CYG_DEVICE_BK0_LSR, lsr);
209
    if ((lsr & CYG_DEVICE_BK0_LSR_RXDA) == 0)
210
        return false;
211
 
212
    HAL_READ_UINT8 (base+CYG_DEVICE_BK0_RXD, *ch);
213
 
214
    return true;
215
}
216
 
217
cyg_uint8
218
cyg_hal_plf_serial_getc(void* __ch_data)
219
{
220
    cyg_uint8 ch;
221
    CYGARC_HAL_SAVE_GP();
222
 
223
    while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
224
 
225
    CYGARC_HAL_RESTORE_GP();
226
    return ch;
227
}
228
 
229
static channel_data_t channels[2] = {
230
    { (cyg_uint8*)CYG_DEVICE_SERIAL_SCC1, 1000, CYGNUM_HAL_INTERRUPT_DEBUG_UART},
231
    { (cyg_uint8*)CYG_DEVICE_SERIAL_SCC2, 1000, CYGNUM_HAL_INTERRUPT_USER_UART}
232
};
233
 
234
static void
235
cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf,
236
                         cyg_uint32 __len)
237
{
238
    CYGARC_HAL_SAVE_GP();
239
 
240
    while(__len-- > 0)
241
        cyg_hal_plf_serial_putc(__ch_data, *__buf++);
242
 
243
    CYGARC_HAL_RESTORE_GP();
244
}
245
 
246
static void
247
cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
248
{
249
    CYGARC_HAL_SAVE_GP();
250
 
251
    while(__len-- > 0)
252
        *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
253
 
254
    CYGARC_HAL_RESTORE_GP();
255
}
256
 
257
 
258
cyg_bool
259
cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
260
{
261
    int delay_count;
262
    channel_data_t* chan = (channel_data_t*)__ch_data;
263
    cyg_bool res;
264
    CYGARC_HAL_SAVE_GP();
265
 
266
    delay_count = chan->msec_timeout * 10; // delay in .1 ms steps
267
 
268
    for(;;) {
269
        res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
270
        if (res || 0 == delay_count--)
271
            break;
272
 
273
        CYGACC_CALL_IF_DELAY_US(100);
274
    }
275
 
276
    CYGARC_HAL_RESTORE_GP();
277
    return res;
278
}
279
 
280
static int
281
cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
282
{
283
    static int irq_state = 0;
284
    channel_data_t* chan = (channel_data_t*)__ch_data;
285
    cyg_uint8 ier;
286
    int ret = 0;
287
    CYGARC_HAL_SAVE_GP();
288
 
289
    switch (__func) {
290
    case __COMMCTL_IRQ_ENABLE:
291
        irq_state = 1;
292
 
293
        HAL_READ_UINT8(chan->base+CYG_DEVICE_BK0_IER, ier);
294
        ier |= CYG_DEVICE_BK0_IER_RXHDL_IE;
295
        HAL_WRITE_UINT8(chan->base+CYG_DEVICE_BK0_IER, ier);
296
 
297
        HAL_INTERRUPT_SET_LEVEL(chan->isr_vector, 1);
298
        HAL_INTERRUPT_UNMASK(chan->isr_vector);
299
        break;
300
    case __COMMCTL_IRQ_DISABLE:
301
        ret = irq_state;
302
        irq_state = 0;
303
 
304
        HAL_READ_UINT8(chan->base+CYG_DEVICE_BK0_IER, ier);
305
        ier &= ~CYG_DEVICE_BK0_IER_RXHDL_IE;
306
        HAL_WRITE_UINT8(chan->base+CYG_DEVICE_BK0_IER, ier);
307
 
308
        HAL_INTERRUPT_MASK(chan->isr_vector);
309
        break;
310
    case __COMMCTL_DBG_ISR_VECTOR:
311
        ret = chan->isr_vector;
312
        break;
313
    case __COMMCTL_SET_TIMEOUT:
314
    {
315
        va_list ap;
316
 
317
        va_start(ap, __func);
318
 
319
        ret = chan->msec_timeout;
320
        chan->msec_timeout = va_arg(ap, cyg_uint32);
321
 
322
        va_end(ap);
323
    }
324
    default:
325
        break;
326
    }
327
    CYGARC_HAL_RESTORE_GP();
328
    return ret;
329
}
330
 
331
static int
332
cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc,
333
                       CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
334
{
335
    int res = 0;
336
    cyg_uint8 eir, c;
337
    channel_data_t* chan = (channel_data_t*)__ch_data;
338
    CYGARC_HAL_SAVE_GP();
339
 
340
    HAL_INTERRUPT_ACKNOWLEDGE(chan->isr_vector);
341
 
342
    HAL_READ_UINT8(chan->base+CYG_DEVICE_BK0_EIR, eir);
343
 
344
    *__ctrlc = 0;
345
    if( (eir & CYG_DEVICE_BK0_EIR_mask) == CYG_DEVICE_BK0_EIR_IRQ_RX ) {
346
 
347
        HAL_READ_UINT8(chan->base+CYG_DEVICE_BK0_RXD, c);
348
 
349
        if( cyg_hal_is_break( &c , 1 ) )
350
            *__ctrlc = 1;
351
 
352
        res = CYG_ISR_HANDLED;
353
    }
354
 
355
    CYGARC_HAL_RESTORE_GP();
356
    return res;
357
}
358
 
359
static void
360
cyg_hal_plf_serial_init(void)
361
{
362
    hal_virtual_comm_table_t* comm;
363
    int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
364
 
365
    // Disable interrupts.
366
    HAL_INTERRUPT_MASK(channels[0].isr_vector);
367
    HAL_INTERRUPT_MASK(channels[1].isr_vector);
368
 
369
    // Init channels
370
    cyg_hal_plf_serial_init_channel((void*)&channels[0]);
371
    cyg_hal_plf_serial_init_channel((void*)&channels[1]);
372
 
373
    // Setup procs in the vector table
374
 
375
    // Set channel 0
376
    CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
377
    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
378
    CYGACC_COMM_IF_CH_DATA_SET(*comm, &channels[0]);
379
    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
380
    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
381
    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
382
    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
383
    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
384
    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
385
    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
386
 
387
    // Set channel 1
388
    CYGACC_CALL_IF_SET_CONSOLE_COMM(1);
389
    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
390
    CYGACC_COMM_IF_CH_DATA_SET(*comm, &channels[1]);
391
    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
392
    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
393
    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
394
    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
395
    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
396
    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
397
    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
398
 
399
    // Restore original console
400
    CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
401
}
402
 
403
void
404
cyg_hal_plf_comms_init(void)
405
{
406
    static int initialized = 0;
407
 
408
    if (initialized)
409
        return;
410
 
411
    initialized = 1;
412
 
413
    cyg_hal_plf_serial_init();
414
}
415
 
416
//-----------------------------------------------------------------------------
417
// end of pc87338.c
418
#endif // CYGONCE_HAL_PC_SER_INL

powered by: WebSVN 2.1.0

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