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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [arm/] [xscale/] [iq80321/] [v2_0/] [src/] [hal_diag.c] - Blame information for rev 307

Go to most recent revision | 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, msalter
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 CYGBLD_HAL_VARIANT_H           // Variant specific configuration
55
#include CYGBLD_HAL_PLATFORM_H          // Platform specific configuration
56
 
57
#include <cyg/infra/cyg_type.h>         // base types
58
#include <cyg/infra/cyg_trac.h>         // tracing macros
59
#include <cyg/infra/cyg_ass.h>          // assertion macros
60
 
61
#include <cyg/hal/hal_arch.h>           // basic machine info
62
#include <cyg/hal/hal_intr.h>           // interrupt macros
63
#include <cyg/hal/hal_io.h>             // IO macros
64
#include <cyg/hal/hal_diag.h>
65
#include <cyg/hal/drv_api.h>
66
#include <cyg/hal/hal_if.h>             // interface API
67
#include <cyg/hal/hal_misc.h>           // Helper functions
68
#include <cyg/hal/iq80321.h>            // platform definitions
69
 
70
/*---------------------------------------------------------------------------*/
71
/* From serial_16550.h */
72
 
73
//-----------------------------------------------------------------------------
74
// Based on 1.8432 MHz xtal
75
 
76
struct baud_config {
77
    cyg_int32 baud_rate;
78
    cyg_uint8 msb;
79
    cyg_uint8 lsb;
80
};
81
 
82
struct baud_config baud_conf[] = {
83
    {9600,   0x00, 0x0c},
84
    {19200,  0x00, 0x06},
85
    {38400,  0x00, 0x03},
86
    {57600,  0x00, 0x02},
87
    {115200, 0x00, 0x01}};
88
 
89
// Define the serial registers.
90
#define CYG_DEV_RBR   0x00 // receiver buffer register, read, dlab = 0
91
#define CYG_DEV_THR   0x00 // transmitter holding register, write, dlab = 0
92
#define CYG_DEV_DLL   0x00 // divisor latch (LS), read/write, dlab = 1
93
#define CYG_DEV_IER   0x01 // interrupt enable register, read/write, dlab = 0
94
#define CYG_DEV_DLM   0x01 // divisor latch (MS), read/write, dlab = 1
95
#define CYG_DEV_IIR   0x02 // interrupt identification register, read, dlab = 0
96
#define CYG_DEV_FCR   0x02 // fifo control register, write, dlab = 0
97
#define CYG_DEV_LCR   0x03 // line control register, write
98
#define CYG_DEV_MCR   0x04 // modem control register, write
99
#define CYG_DEV_LSR   0x05 // line status register, read
100
#define CYG_DEV_MSR   0x06 // modem status register, read
101
#define CYG_DEV_SCR   0x07 // scratch pad register
102
 
103
// Interrupt Enable Register
104
#define SIO_IER_RCV 0x01
105
#define SIO_IER_XMT 0x02
106
#define SIO_IER_LS  0x04
107
#define SIO_IER_MS  0x08
108
 
109
// The line status register bits.
110
#define SIO_LSR_DR      0x01            // data ready
111
#define SIO_LSR_OE      0x02            // overrun error
112
#define SIO_LSR_PE      0x04            // parity error
113
#define SIO_LSR_FE      0x08            // framing error
114
#define SIO_LSR_BI      0x10            // break interrupt
115
#define SIO_LSR_THRE    0x20            // transmitter holding register empty
116
#define SIO_LSR_TEMT    0x40            // transmitter register empty
117
#define SIO_LSR_ERR     0x80            // any error condition
118
 
119
// The modem status register bits.
120
#define SIO_MSR_DCTS  0x01              // delta clear to send
121
#define SIO_MSR_DDSR  0x02              // delta data set ready
122
#define SIO_MSR_TERI  0x04              // trailing edge ring indicator
123
#define SIO_MSR_DDCD  0x08              // delta data carrier detect
124
#define SIO_MSR_CTS   0x10              // clear to send
125
#define SIO_MSR_DSR   0x20              // data set ready
126
#define SIO_MSR_RI    0x40              // ring indicator
127
#define SIO_MSR_DCD   0x80              // data carrier detect
128
 
129
// The line control register bits.
130
#define SIO_LCR_WLS0   0x01             // word length select bit 0
131
#define SIO_LCR_WLS1   0x02             // word length select bit 1
132
#define SIO_LCR_STB    0x04             // number of stop bits
133
#define SIO_LCR_PEN    0x08             // parity enable
134
#define SIO_LCR_EPS    0x10             // even parity select
135
#define SIO_LCR_SP     0x20             // stick parity
136
#define SIO_LCR_SB     0x40             // set break
137
#define SIO_LCR_DLAB   0x80             // divisor latch access bit
138
 
139
// Modem Control Register
140
#define SIO_MCR_DTR 0x01
141
#define SIO_MCR_RTS 0x02
142
 
143
 
144
//-----------------------------------------------------------------------------
145
typedef struct {
146
    cyg_uint8* base;
147
    cyg_int32 msec_timeout;
148
    int isr_vector;
149
    cyg_int32 baud_rate;
150
} channel_data_t;
151
 
152
 
153
//-----------------------------------------------------------------------------
154
 
155
static int
156
set_baud( channel_data_t *chan )
157
{
158
    cyg_uint8* base = chan->base;
159
    cyg_uint8 i;
160
 
161
    for (i=0; i<(sizeof(baud_conf)/sizeof(baud_conf[0])); i++)
162
    {
163
        if (chan->baud_rate == baud_conf[i].baud_rate) {
164
            cyg_uint8 lcr;
165
            HAL_READ_UINT8(base+CYG_DEV_LCR, lcr);
166
            HAL_WRITE_UINT8(base+CYG_DEV_LCR, lcr|SIO_LCR_DLAB);
167
            HAL_WRITE_UINT8(base+CYG_DEV_DLL, baud_conf[i].lsb);
168
            HAL_WRITE_UINT8(base+CYG_DEV_DLM, baud_conf[i].msb);
169
            HAL_WRITE_UINT8(base+CYG_DEV_LCR, lcr);
170
            return 1;
171
        }
172
    }
173
    return -1;
174
}
175
 
176
static void
177
cyg_hal_plf_serial_init_channel(void* __ch_data)
178
{
179
    cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
180
    channel_data_t* chan = (channel_data_t*)__ch_data;
181
 
182
    // 8-1-no parity.
183
    HAL_WRITE_UINT8(base+CYG_DEV_LCR, SIO_LCR_WLS0 | SIO_LCR_WLS1);
184
    chan->baud_rate = CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD;
185
    set_baud( chan );
186
    HAL_WRITE_UINT8(base+CYG_DEV_FCR, 0x07);  // Enable & clear FIFO
187
}
188
 
189
void
190
cyg_hal_plf_serial_putc(void *__ch_data, char c)
191
{
192
    cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
193
    cyg_uint8 lsr;
194
    CYGARC_HAL_SAVE_GP();
195
 
196
    do {
197
       HAL_READ_UINT8(base+CYG_DEV_LSR, lsr);
198
    } while ((lsr & SIO_LSR_THRE) == 0);
199
 
200
    HAL_WRITE_UINT8(base+CYG_DEV_THR, c);
201
 
202
    CYGARC_HAL_RESTORE_GP();
203
}
204
 
205
static cyg_bool
206
cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch)
207
{
208
    cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
209
    cyg_uint8 lsr;
210
 
211
    HAL_READ_UINT8(base+CYG_DEV_LSR, lsr);
212
    if ((lsr & SIO_LSR_DR) == 0)
213
        return false;
214
 
215
    HAL_READ_UINT8(base+CYG_DEV_RBR, *ch);
216
 
217
    return true;
218
}
219
 
220
cyg_uint8
221
cyg_hal_plf_serial_getc(void* __ch_data)
222
{
223
    cyg_uint8 ch;
224
    CYGARC_HAL_SAVE_GP();
225
 
226
    while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
227
 
228
    CYGARC_HAL_RESTORE_GP();
229
    return ch;
230
}
231
 
232
static channel_data_t plf_ser_channels[1] = {
233
    { (cyg_uint8*)IQ80321_UART_ADDR, 1000, CYGNUM_HAL_INTERRUPT_UART }
234
};
235
 
236
static void
237
cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf,
238
                         cyg_uint32 __len)
239
{
240
    CYGARC_HAL_SAVE_GP();
241
 
242
    while(__len-- > 0)
243
        cyg_hal_plf_serial_putc(__ch_data, *__buf++);
244
 
245
    CYGARC_HAL_RESTORE_GP();
246
}
247
 
248
static void
249
cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
250
{
251
    CYGARC_HAL_SAVE_GP();
252
 
253
    while(__len-- > 0)
254
        *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
255
 
256
    CYGARC_HAL_RESTORE_GP();
257
}
258
 
259
cyg_bool
260
cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
261
{
262
    int delay_count;
263
    channel_data_t* chan = (channel_data_t*)__ch_data;
264
    cyg_bool res;
265
    CYGARC_HAL_SAVE_GP();
266
 
267
    delay_count = chan->msec_timeout * 10; // delay in .1 ms steps
268
 
269
    for(;;) {
270
        res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
271
        if (res || 0 == delay_count--)
272
            break;
273
 
274
        CYGACC_CALL_IF_DELAY_US(100);
275
    }
276
 
277
    CYGARC_HAL_RESTORE_GP();
278
    return res;
279
}
280
 
281
static int
282
cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
283
{
284
    static int irq_state = 0;
285
    channel_data_t* chan = (channel_data_t*)__ch_data;
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_WRITE_UINT8(chan->base+CYG_DEV_IER, SIO_IER_RCV);
294
        HAL_INTERRUPT_UNMASK(chan->isr_vector);
295
        break;
296
    case __COMMCTL_IRQ_DISABLE:
297
        ret = irq_state;
298
        irq_state = 0;
299
 
300
        HAL_WRITE_UINT8(chan->base+CYG_DEV_IER, 0);
301
        HAL_INTERRUPT_MASK(chan->isr_vector);
302
        break;
303
    case __COMMCTL_DBG_ISR_VECTOR:
304
        ret = chan->isr_vector;
305
        break;
306
    case __COMMCTL_SET_TIMEOUT:
307
    {
308
        va_list ap;
309
 
310
        va_start(ap, __func);
311
 
312
        ret = chan->msec_timeout;
313
        chan->msec_timeout = va_arg(ap, cyg_uint32);
314
 
315
        va_end(ap);
316
    }
317
    case __COMMCTL_GETBAUD:
318
        ret = chan->baud_rate;
319
        break;
320
    case __COMMCTL_SETBAUD:
321
    {
322
        va_list ap;
323
        va_start(ap, __func);
324
        chan->baud_rate = va_arg(ap, cyg_int32);
325
        va_end(ap);
326
        ret = set_baud(chan);
327
        break;
328
    }
329
    default:
330
        break;
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
        res = CYG_ISR_HANDLED;
357
    }
358
 
359
    CYGARC_HAL_RESTORE_GP();
360
    return res;
361
}
362
 
363
static void
364
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
 
369
    // Disable interrupts.
370
    HAL_INTERRUPT_MASK(plf_ser_channels[0].isr_vector);
371
 
372
    // Init channels
373
    cyg_hal_plf_serial_init_channel(&plf_ser_channels[0]);
374
 
375
    // Setup procs in the vector table
376
 
377
    // Set channel 0
378
    CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
379
    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
380
    CYGACC_COMM_IF_CH_DATA_SET(*comm, &plf_ser_channels[0]);
381
    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
382
    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
383
    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
384
    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
385
    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
386
    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
387
    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
388
 
389
    // Restore original console
390
    CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
391
}
392
 
393
void
394
cyg_hal_plf_comms_init(void)
395
{
396
    static int initialized = 0;
397
 
398
    if (initialized)
399
        return;
400
 
401
    initialized = 1;
402
 
403
    cyg_hal_plf_serial_init();
404
}
405
 
406
/*---------------------------------------------------------------------------*/
407
 
408
cyg_uint8 cyg_hal_led_segment[16] = {
409
    DISPLAY_0, DISPLAY_1, DISPLAY_2, DISPLAY_3,
410
    DISPLAY_4, DISPLAY_5, DISPLAY_6, DISPLAY_7,
411
    DISPLAY_8, DISPLAY_9, DISPLAY_A, DISPLAY_B,
412
    DISPLAY_C, DISPLAY_D, DISPLAY_E, DISPLAY_F };
413
 
414
void
415
hal_diag_led(int n)
416
{
417
    HAL_WRITE_UINT8(DISPLAY_RIGHT, cyg_hal_led_segment[n & 0x0f]);
418
}
419
 
420
/*---------------------------------------------------------------------------*/
421
/* 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.