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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [frv/] [frv400/] [v2_0/] [src/] [hal_diag.c] - Blame information for rev 174

Details | Compare with Previous | View Log

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