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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [mips/] [vrc437x/] [v2_0/] [src/] [plf_serial.c] - Blame information for rev 174

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//=============================================================================
2
//
3
//      plf_stub.c
4
//
5
//      Platform specific code for GDB stub support.
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, jskov (based on the old tx39 hal_stub.c)
44
// Contributors:nickg, jskov
45
// Date:        1999-02-12
46
// Purpose:     Platform specific code for GDB stub support.
47
//              
48
//####DESCRIPTIONEND####
49
//
50
//=============================================================================
51
 
52
#include <pkgconf/hal.h>
53
 
54
#include <cyg/hal/hal_io.h>             // HAL IO macros
55
#include <cyg/hal/hal_diag.h>           // diag output. FIXME
56
 
57
#include <cyg/hal/hal_arch.h>
58
#include <cyg/hal/hal_intr.h>
59
#include <cyg/hal/hal_if.h>
60
#include <cyg/hal/hal_misc.h>
61
#include <cyg/hal/drv_api.h>            // CYG_ISR_HANDLED
62
 
63
#include <cyg/hal/plf_z8530.h>
64
 
65
/*---------------------------------------------------------------------------*/
66
 
67
static unsigned char _diag_init[] = {
68
    0x00, /* Register 0 */
69
    0x00, /* Register 1 - no interrupts */
70
    0x00, /* Register 2 */
71
    0xC1, /* Register 3 - Rx enable, 8 data */
72
    0x44, /* Register 4 - x16 clock, 1 stop, no parity */
73
    0x68, /* Register 5 - Tx enable, 8 data */
74
    0x00, /* Register 6 */
75
    0x00, /* Register 7 */
76
    0x00, /* Register 8 */
77
    0x00, /* Register 9 */
78
    0x00, /* Register 10 */
79
    0x56, /* Register 11 - Rx, Tx clocks from baud rate generator */
80
    0x00, /* Register 12 - baud rate LSB */
81
    0x00, /* Register 13 - baud rate MSB */
82
    0x03, /* Register 14 - enable baud rate generator */
83
    0x00  /* Register 15 */
84
};
85
 
86
#define BRTC(brate) (( ((unsigned) DUART_CLOCK) / (2*(brate)*SCC_CLKMODE_TC)) - 2)
87
#define DUART_CLOCK          4915200         /* Z8530 duart */
88
#define SCC_CLKMODE_TC       16              /* Always run x16 clock for async modes */
89
 
90
//-----------------------------------------------------------------------------
91
 
92
typedef struct {
93
    cyg_uint32 base;
94
    cyg_uint32 msec_timeout;
95
    int isr_vector;
96
} channel_data_t;
97
 
98
static channel_data_t channels[2] = {
99
    { DUART_A, 1000, CYGNUM_HAL_INTERRUPT_DUART},
100
    { DUART_B, 1000, CYGNUM_HAL_INTERRUPT_DUART}
101
};
102
 
103
//-----------------------------------------------------------------------------
104
// Set the baud rate
105
 
106
static void
107
cyg_hal_plf_serial_set_baud(cyg_uint32 duart, cyg_uint16 baud_rate)
108
{
109
    unsigned short brg = BRTC(baud_rate);
110
    HAL_DUART_WRITE_CR(duart, 12, brg&0xFF);
111
    HAL_DUART_WRITE_CR(duart, 13, brg>>8);
112
}
113
 
114
//-----------------------------------------------------------------------------
115
// The minimal init, get and put functions. All by polling.
116
 
117
void
118
cyg_hal_plf_serial_init_channel(void* __ch_data)
119
{
120
    cyg_uint32 duart;
121
    unsigned short brg = BRTC(CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD);
122
    int i;
123
    channel_data_t *chan;
124
 
125
    // Some of the diagnostic print code calls through here with no idea what the ch_data is.
126
    // Go ahead and assume it is channels[0].
127
    if (__ch_data == 0)
128
        __ch_data = (void*)&channels[0];
129
 
130
    chan = (channel_data_t*)__ch_data;
131
 
132
#ifdef CYGPRI_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_CONFIGURABLE    
133
    if( (chan-&channels[0]) == CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL )
134
        brg = BRTC(CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_BAUD);
135
#endif    
136
#ifdef CYGPRI_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_CONFIGURABLE
137
    if( (chan-&channels[0]) == CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL )
138
        brg = BRTC(CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD);
139
#endif
140
 
141
    duart = chan->base;
142
 
143
    _diag_init[12] = brg & 0xFF;
144
    _diag_init[13] = brg >> 8;
145
    for (i = 1;  i < 16;  i++) {
146
        HAL_DUART_WRITE_CR(duart, i, _diag_init[i]);
147
    }
148
 
149
}
150
 
151
void
152
cyg_hal_plf_serial_putc(void* __ch_data, cyg_uint8 __ch)
153
{
154
    cyg_uint32 duart;
155
    cyg_uint8 rr0;
156
 
157
    // Some of the diagnostic print code calls through here with no idea what the ch_data is.
158
    // Go ahead and assume it is channels[0].
159
    if (__ch_data == 0)
160
      __ch_data = (void*)&channels[0];
161
 
162
    duart = ((channel_data_t*)__ch_data)->base;
163
 
164
    CYGARC_HAL_SAVE_GP();
165
 
166
    do
167
    {
168
        HAL_DUART_READ_CR(duart, 0, rr0 );
169
    } while( (rr0 & 0x04) == 0 );
170
 
171
    HAL_DUART_WRITE_TR( duart, __ch );
172
 
173
    HAL_INTERRUPT_ACKNOWLEDGE( CYGNUM_HAL_INTERRUPT_DUART );
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_uint32 duart;
182
    cyg_uint8 rr0;
183
 
184
    // Some of the diagnostic print code calls through here with no idea what the ch_data is.
185
    // Go ahead and assume it is channels[0].
186
    if (__ch_data == 0)
187
      __ch_data = (void*)&channels[0];
188
 
189
    duart = ((channel_data_t*)__ch_data)->base;
190
 
191
    HAL_DUART_READ_CR(duart, 0, rr0 );
192
 
193
    if( (rr0 & 0x01) == 0 )
194
        return false;
195
 
196
    HAL_DUART_READ_RR( duart, *ch );
197
 
198
    HAL_INTERRUPT_ACKNOWLEDGE( CYGNUM_HAL_INTERRUPT_DUART );
199
 
200
    return true;
201
}
202
 
203
cyg_uint8
204
cyg_hal_plf_serial_getc(void* __ch_data)
205
{
206
    cyg_uint8 ch;
207
    CYGARC_HAL_SAVE_GP();
208
 
209
    // Some of the diagnostic print code calls through here with no idea what the ch_data is.
210
    // Go ahead and assume it is channels[0].
211
    if (__ch_data == 0)
212
      __ch_data = (void*)&channels[0];
213
 
214
    while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
215
 
216
    CYGARC_HAL_RESTORE_GP();
217
    return ch;
218
}
219
 
220
#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
221
 
222
static void
223
cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf,
224
                         cyg_uint32 __len)
225
{
226
    CYGARC_HAL_SAVE_GP();
227
 
228
    // Some of the diagnostic print code calls through here with no idea what the ch_data is.
229
    // Go ahead and assume it is channels[0].
230
    if (__ch_data == 0)
231
      __ch_data = (void*)&channels[0];
232
 
233
    while(__len-- > 0)
234
        cyg_hal_plf_serial_putc(__ch_data, *__buf++);
235
 
236
    CYGARC_HAL_RESTORE_GP();
237
}
238
 
239
static void
240
cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
241
{
242
    CYGARC_HAL_SAVE_GP();
243
 
244
    // Some of the diagnostic print code calls through here with no idea what the ch_data is.
245
    // Go ahead and assume it is channels[0].
246
    if (__ch_data == 0)
247
      __ch_data = (void*)&channels[0];
248
 
249
    while(__len-- > 0)
250
        *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
251
 
252
    CYGARC_HAL_RESTORE_GP();
253
}
254
 
255
 
256
cyg_bool
257
cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
258
{
259
    int delay_count;
260
    channel_data_t* chan;
261
    cyg_bool res;
262
    CYGARC_HAL_SAVE_GP();
263
 
264
    // Some of the diagnostic print code calls through here with no idea what the ch_data is.
265
    // Go ahead and assume it is channels[0].
266
    if (__ch_data == 0)
267
      __ch_data = (void*)&channels[0];
268
 
269
    chan = (channel_data_t*)__ch_data;
270
 
271
    delay_count = chan->msec_timeout * 10; // delay in .1 ms steps
272
 
273
    for(;;) {
274
        res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
275
        if (res || 0 == delay_count--)
276
            break;
277
        CYGACC_CALL_IF_DELAY_US(100);
278
    }
279
 
280
    CYGARC_HAL_RESTORE_GP();
281
    return res;
282
}
283
 
284
 
285
static int
286
cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
287
{
288
    static int irq_state = 0;
289
    channel_data_t* chan;
290
    int ret = 0;
291
    CYGARC_HAL_SAVE_GP();
292
 
293
    // Some of the diagnostic print code calls through here with no idea what the ch_data is.
294
    // Go ahead and assume it is channels[0].
295
    if (__ch_data == 0)
296
      __ch_data = (void*)&channels[0];
297
 
298
    chan = (channel_data_t*)__ch_data;
299
 
300
    switch (__func) {
301
    case __COMMCTL_IRQ_ENABLE:
302
        irq_state = 1;
303
 
304
        HAL_DUART_WRITE_CR( chan->base, 1, 0x10 );
305
        HAL_DUART_WRITE_CR( chan->base, 9, 0x0a );
306
 
307
        HAL_INTERRUPT_SET_LEVEL(chan->isr_vector, 0);
308
        HAL_INTERRUPT_UNMASK(chan->isr_vector);
309
        break;
310
    case __COMMCTL_IRQ_DISABLE:
311
        ret = irq_state;
312
        irq_state = 0;
313
 
314
        HAL_DUART_WRITE_CR( chan->base, 1, 0x00 );
315
        HAL_DUART_WRITE_CR( chan->base, 9, 0x00 );
316
 
317
        HAL_INTERRUPT_MASK(chan->isr_vector);
318
        break;
319
    case __COMMCTL_DBG_ISR_VECTOR:
320
        ret = chan->isr_vector;
321
        break;
322
    case __COMMCTL_SET_TIMEOUT:
323
    {
324
        va_list ap;
325
 
326
        va_start(ap, __func);
327
 
328
        ret = chan->msec_timeout;
329
        chan->msec_timeout = va_arg(ap, cyg_uint32);
330
 
331
        va_end(ap);
332
    }
333
    break;
334
    case __COMMCTL_SETBAUD:
335
    {
336
        cyg_uint32 baud_rate;
337
        cyg_uint32 duart = chan->base;
338
        va_list ap;
339
 
340
        va_start(ap, __func);
341
        baud_rate = va_arg(ap, cyg_uint32);
342
        va_end(ap);
343
 
344
        // Set baud rate.
345
        cyg_hal_plf_serial_set_baud(duart, baud_rate);
346
 
347
    }
348
    break;
349
 
350
    case __COMMCTL_GETBAUD:
351
        break;
352
    default:
353
        break;
354
    }
355
    CYGARC_HAL_RESTORE_GP();
356
    return ret;
357
}
358
 
359
static int
360
cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc,
361
                       CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
362
{
363
    int res = 0;
364
    channel_data_t* chan;
365
    char c;
366
 
367
    CYGARC_HAL_SAVE_GP();
368
 
369
    // Some of the diagnostic print code calls through here with no idea what the ch_data is.
370
    // Go ahead and assume it is channels[0].
371
    if (__ch_data == 0)
372
      __ch_data = (void*)&channels[0];
373
 
374
    chan = (channel_data_t*)__ch_data;
375
 
376
    HAL_INTERRUPT_ACKNOWLEDGE(chan->isr_vector);
377
 
378
    *__ctrlc = 0;
379
 
380
    if ( cyg_hal_plf_serial_getc_nonblock(__ch_data, &c) )
381
    {
382
        if( cyg_hal_is_break( &c , 1 ) )
383
            *__ctrlc = 1;
384
 
385
        res = CYG_ISR_HANDLED;
386
    }
387
 
388
    CYGARC_HAL_RESTORE_GP();
389
 
390
    return res;
391
}
392
 
393
#endif
394
 
395
static void
396
cyg_hal_plf_serial_init(void)
397
{
398
#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT    
399
    hal_virtual_comm_table_t* comm;
400
    int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
401
#endif
402
    // Disable interrupts.
403
    HAL_INTERRUPT_MASK(channels[0].isr_vector);
404
 
405
    // Init channels
406
    cyg_hal_plf_serial_init_channel((void*)&channels[0]);
407
 
408
#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT    
409
    // Setup procs in the vector table
410
 
411
    // Set channel 0
412
    CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
413
    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
414
    CYGACC_COMM_IF_CH_DATA_SET(*comm, &channels[0]);
415
    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
416
    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
417
    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
418
    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
419
    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
420
    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
421
    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
422
 
423
    // Restore original console
424
    CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
425
#endif    
426
}
427
 
428
 
429
void
430
cyg_hal_plf_comms_init(void)
431
{
432
    static int initialized = 0;
433
 
434
    if (initialized)
435
        return;
436
 
437
    initialized = 1;
438
 
439
    cyg_hal_plf_serial_init();
440
}
441
 
442
//-----------------------------------------------------------------------------
443
// End of plf_serial.c

powered by: WebSVN 2.1.0

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