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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [frv/] [frv400/] [current/] [src/] [hal_diag.c] - Blame information for rev 786

Details | Compare with Previous | View Log

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