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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [arm/] [arm9/] [innovator/] [v2_0/] [src/] [hal_diag.c] - Blame information for rev 819

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):   Patrick Doyle <wpd@delcomsys.com>
44
// Contributors:Patrick Doyle <wpd@delcomsys.com>
45
// Date:        2002-12-17
46
// Purpose:     HAL diagnostic output
47
//      This file contains the type definitions, constants, and function
48
//      prototoypes that implement very simple access to the UART on the
49
//      OMAP part.
50
// Description: Implementations of HAL diagnostic output support.
51
//
52
//####DESCRIPTIONEND####
53
//
54
//=============================================================================
55
 
56
#include <pkgconf/hal.h>
57
#include CYGBLD_HAL_VARIANT_H           // Variant specific configuration
58
#include CYGBLD_HAL_PLATFORM_H          // Platform specific configuration
59
 
60
#include <cyg/infra/cyg_type.h>         // base types
61
#include <cyg/infra/cyg_trac.h>         // tracing macros
62
#include <cyg/infra/cyg_ass.h>          // assertion macros
63
 
64
#include <cyg/hal/hal_arch.h>           // basic machine info
65
#include <cyg/hal/hal_intr.h>           // interrupt macros
66
#include <cyg/hal/hal_io.h>             // IO macros
67
#include <cyg/hal/hal_diag.h>
68
#include <cyg/hal/drv_api.h>
69
#include <cyg/hal/hal_if.h>             // interface API
70
#include <cyg/hal/hal_misc.h>           // Helper functions
71
#include <cyg/hal/innovator.h>          // platform definitions
72
 
73
//-----------------------------------------------------------------------------
74
 
75
#define CYG_DEVICE_SERIAL_BAUD_DIV (CYGNUM_HAL_ARM_INNOVATOR_PERIPHERAL_CLOCK/CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD/16)
76
#define CYG_DEVICE_SERIAL_BAUD_LSB (CYG_DEVICE_SERIAL_BAUD_DIV&0xff)
77
#define CYG_DEVICE_SERIAL_BAUD_MSB ((CYG_DEVICE_SERIAL_BAUD_DIV>>8)&0xff)
78
 
79
//-----------------------------------------------------------------------------
80
typedef struct {
81
    cyg_int32 msec_timeout;
82
#ifdef LATER
83
    cyg_uint32 base;
84
    int isr_vector;
85
#endif
86
} channel_data_t;
87
 
88
/************************************************************************
89
 * Useful definitions -- note that 'USE_MODEM_UART' has not been extensively
90
 * tested nor debugged (read -- it probably doesn't work).
91
 ************************************************************************/
92
/*#define USE_MODEM_UART*/
93
#ifdef USE_MODEM_UART
94
#define BASE_ADDR 0xfffce800
95
#define STRIDE    1
96
#else
97
#define BASE_ADDR 0xfffb0000
98
#define STRIDE    4
99
#endif
100
 
101
#define RHR   0x00
102
#define THR   0x00
103
#define DLL   0x00
104
#define DLH   0x01
105
#define IER   0x01
106
#define FCR   0x02
107
#define EFR   0x02
108
#define IIR   0x02
109
#define LCR   0x03
110
#define MCR   0x04
111
#define XON1  0x04
112
#define LSR   0x05
113
#define XON2  0x05
114
#define MSR   0x06
115
#define TCR   0x06
116
#define XOFF1 0x06
117
#define SPR   0x07
118
#define TLR   0x07
119
#define XOFF2 0x07
120
#define MDR1  0x08
121
#define UASR  0x0e
122
#define SCR   0x10
123
#define SSR   0x11
124
#define OSC_12M 0x13
125
 
126
 
127
/************************************************************************
128
 * Data local to this file
129
 ************************************************************************/
130
#define write_serial(offset, value) \
131
  *(volatile char *)(BASE_ADDR + STRIDE * (offset)) = value
132
 
133
#define read_serial(offset) \
134
  (*(volatile char *)(BASE_ADDR + STRIDE * (offset)))
135
 
136
/************************************************************************
137
 * Forward References
138
 ************************************************************************/
139
 
140
/************************************************************************
141
 * Function:
142
 *      init_uart()
143
 *
144
 * Purpose:
145
 *      This procedure may be called in order to initialize the UART
146
 *      prior to use.
147
 *
148
 * Operation:
149
 *      Set up the UART for 115,200 baud, 8 bits, 1 stop bit, no parity.
150
 *
151
 *      The UART is defined by the 'BASE_ADDR' macro.
152
 *
153
 * Notes/Issues:
154
 *      This pays some lip service to being able to use UART3, but since
155
 *      it seems to me that the use of UART3 requires that the DSP do
156
 *      some setup (at least, until I learn more), it probably won't
157
 *      work for UART3.
158
 ************************************************************************/
159
static void
160
quick_init_uart(void)
161
{
162
  /* UART Software Reset */
163
  write_serial(LCR, 0xBF); /* Access to EFR & UART break is removed */
164
  write_serial(EFR, BIT_04); /* Set EFR[4] = 0x1 */
165
  write_serial(LCR, 0x00); /* Access to IER & MCR is allowed */
166
 
167
  write_serial(IER, 0x00); /* Disable all interrupts */
168
  write_serial(MCR, 0x00); /* DTR, RTS, XON, loopbback inactive */
169
 
170
  write_serial(MDR1,0x07); /* UART is in reset */
171
 
172
  /* UART FIFO Configuration */
173
  write_serial(MCR, read_serial(MCR) | BIT_06); /* Set MCR[6] = 1 */
174
  write_serial(TCR, 0x0F); /* RTS off when Rx FIFO at 60 bytes, on at 0 */
175
  write_serial(TLR, 0x88); /* set TX & RX trigger levels each to 32 */
176
  write_serial(FCR, 0x07); /* Enable & reset FIFOs, triggers at 8 */
177
  write_serial(LCR, 0xBF); /* Access EFR */
178
  write_serial(EFR, 0xC0); /* Enable auto RTS & CTS */
179
  write_serial(LCR, 0x00); /* Access to IER & MCR is allowed */
180
  write_serial(MCR, read_serial(MCR) & ~BIT_06); /* Clear MCR[6] */
181
 
182
  /* Baud Rate and Stop Configuration */
183
  write_serial(LCR, 0x03); /* 8,N,1 */
184
#ifdef USE_MODEM_UART
185
  write_serial(LCR, 0x83); /* gain access to DLH and DLL */
186
  write_serial(DLH, 0x00); /* Divisor value = Operating Freq/(16 x Baud Rate) */
187
  write_serial(DLL, 0x0D); /* DPLL2 configured for Operating Freq = 24 MHz */
188
                           /* Baud Rate = 115,200 bps */
189
#else
190
  write_serial(OSC_12M, 1);/* Set divisor value to 6.5 */
191
  write_serial(LCR, 0x83); /* gain access to DLH and DLL */
192
  write_serial(DLH, 0x00); /* Divisor value =
193
                            *     Operating Freq/(16 x 6.5 x Baud Rate) */
194
  write_serial(DLL, 0x01); /* DPLL2 configured for Operating Freq = 12 MHz */
195
                           /* Baud Rate = 115,200 bps */
196
#endif
197
  write_serial(LCR, 0x03); /* restore LCR */
198
 
199
  write_serial(MDR1,0x00); /* enable UART */
200
}
201
 
202
/************************************************************************
203
 * Function:
204
 *      putchar(c)
205
 *
206
 * Purpose:
207
 *      This procedure may be called in order to output a character on
208
 *      the serial port.  It blocks until the serial port TX FIFO is
209
 *      empty.
210
 *
211
 * Operation:
212
 *      Write character to the Transmit Holding Register (THR).  Can
213
 *      optionally map the Linefeed character to a Carriage Return
214
 *      character and/or output a Carriage Return character whenever
215
 *      a Linefeed character is seen, depending on #ifdefs.
216
 *
217
 * Notes/Issues:
218
 *      This could be optimized to block only when the serial port TX
219
 *      FIFO is full.
220
 ************************************************************************/
221
static void
222
quick_putchar(char c)
223
{
224
/* #define MAP_LF_TO_CR */
225
#ifdef MAP_LF_TO_CR
226
  if (c == '\n') {
227
    c = '\r';
228
  }
229
#endif
230
  while ((read_serial(LSR) & 0x20) == 0) ;
231
  write_serial(THR, c);
232
 
233
/*  #define DO_CRLF */
234
#ifdef DO_CRLF
235
  if (c == '\n') {
236
    quick_putchar('\r');
237
  }
238
#endif
239
}
240
 
241
/************************************************************************
242
 * Function:
243
 *      getchar()
244
 *
245
 * Purpose:
246
 *      This function may be called in order to read a character from
247
 *      the serial port.
248
 *
249
 * Operation:
250
 *      Poll the Line Status register until it indicates a character has
251
 *      been received.  Return the character to the caller.
252
 *
253
 * Notes/Issues:
254
 *
255
 ************************************************************************/
256
static int
257
quick_getchar(void)
258
{
259
  while ((read_serial(LSR) & 0x01) == 0) ;
260
  return(read_serial(RHR));
261
}
262
 
263
/************************************************************************
264
 * Function:
265
 *      getchar_nonblock()
266
 *
267
 * Purpose:
268
 *      This function may be called in order to read a character from
269
 *      the serial port.
270
 *
271
 * Operation:
272
 *      Poll the Line Status register until it indicates a character has
273
 *      been received.  Return the character to the caller.
274
 *
275
 * Notes/Issues:
276
 *
277
 ************************************************************************/
278
static int
279
quick_getchar_nonblock(char *c)
280
{
281
  if ((read_serial(LSR) & 0x01) == 0) {
282
    return(0);
283
  } else {
284
    *c = read_serial(RHR);
285
    return(1);
286
  }
287
}
288
 
289
//-----------------------------------------------------------------------------
290
 
291
static void
292
cyg_hal_plf_serial_init_channel(void* __ch_data)
293
{
294
#ifdef LATER
295
    cyg_uint32 base = ((channel_data_t*)__ch_data)->base;
296
 
297
    // 8-1-no parity.
298
    HAL_WRITE_UINT32(base+_UART_MC, _UART_MC_8BIT | _UART_MC_1STOP | _UART_MC_PARITY_NONE);
299
 
300
    HAL_WRITE_UINT32(base+_UART_DIV_LO, CYG_DEVICE_SERIAL_BAUD_LSB);
301
    HAL_WRITE_UINT32(base+_UART_DIV_HI, CYG_DEVICE_SERIAL_BAUD_MSB);
302
    HAL_WRITE_UINT32(base+_UART_FCR, (_UART_FCR_TC | _UART_FCR_RC |
303
                                      _UART_FCR_TX_THR_15 | _UART_FCR_RX_THR_1));  // clear & enableFIFO
304
 
305
    // enable RX interrupts - otherwise ISR cannot be polled. Actual
306
    // interrupt control of serial happens via INT_MASK
307
    HAL_WRITE_UINT32(base+_UART_IES, _UART_INTS_RE);
308
#endif
309
}
310
 
311
void
312
cyg_hal_plf_serial_putc(void *__ch_data, char c)
313
{
314
#ifdef LATER
315
    cyg_uint32 base = ((channel_data_t*)__ch_data)->base;
316
    cyg_uint32 tsr;
317
    CYGARC_HAL_SAVE_GP();
318
 
319
    do {
320
        HAL_READ_UINT32(base+_UART_TSR, tsr);
321
        // Wait for TXI flag to be set - or for the register to be
322
        // zero (works around a HW bug it seems).
323
    } while (tsr && (tsr & _UART_TSR_TXI) == 0);
324
 
325
    HAL_WRITE_UINT32(base+_UART_TD, (cyg_uint32)(unsigned char)c);
326
 
327
    CYGARC_HAL_RESTORE_GP();
328
#else
329
    quick_putchar(c);
330
#endif
331
}
332
 
333
static cyg_bool
334
cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch)
335
{
336
#ifdef LATER
337
    cyg_uint32 base = ((channel_data_t*)__ch_data)->base;
338
    cyg_uint32 rsr, isr, data;
339
 
340
    HAL_READ_UINT32(base+_UART_ISR, isr);
341
    if (0 == (isr & _UART_INTS_RI)) {
342
        HAL_READ_UINT32(base+_UART_RSR, rsr);
343
        if (0 == rsr)
344
            return false;
345
    }
346
 
347
    HAL_READ_UINT32(base+_UART_RD, data);
348
    *ch = (cyg_uint8)(data & 0xff);
349
 
350
    // Read RSR to clear interrupt, and RDS to clear errors
351
    HAL_READ_UINT32(base+_UART_RSR, data);
352
    HAL_READ_UINT32(base+_UART_RDS, data);
353
 
354
    return true;
355
#else
356
    return(quick_getchar_nonblock(ch));
357
#endif
358
}
359
 
360
cyg_uint8
361
cyg_hal_plf_serial_getc(void* __ch_data)
362
{
363
#ifdef LATER
364
    cyg_uint8 ch;
365
    CYGARC_HAL_SAVE_GP();
366
 
367
    while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
368
 
369
    CYGARC_HAL_RESTORE_GP();
370
    return ch;
371
#else
372
    return(quick_getchar());
373
#endif
374
}
375
 
376
static channel_data_t innovator_ser_channels[1] = {
377
    { 1000 }
378
};
379
 
380
static void
381
cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf,
382
                         cyg_uint32 __len)
383
{
384
    CYGARC_HAL_SAVE_GP();
385
 
386
    while(__len-- > 0)
387
        cyg_hal_plf_serial_putc(__ch_data, *__buf++);
388
 
389
    CYGARC_HAL_RESTORE_GP();
390
}
391
 
392
static void
393
cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
394
{
395
    CYGARC_HAL_SAVE_GP();
396
 
397
    while(__len-- > 0)
398
        *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
399
 
400
    CYGARC_HAL_RESTORE_GP();
401
}
402
 
403
cyg_bool
404
cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
405
{
406
    int delay_count;
407
    channel_data_t* chan = (channel_data_t*)__ch_data;
408
    cyg_bool res;
409
    CYGARC_HAL_SAVE_GP();
410
 
411
    delay_count = chan->msec_timeout * 10; // delay in .1 ms steps
412
 
413
    for(;;) {
414
        res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
415
        if (res || 0 == delay_count--)
416
            break;
417
 
418
        CYGACC_CALL_IF_DELAY_US(100);
419
    }
420
 
421
    CYGARC_HAL_RESTORE_GP();
422
    return res;
423
}
424
 
425
static int
426
cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
427
{
428
    static int irq_state = 0;
429
    channel_data_t* chan = (channel_data_t*)__ch_data;
430
    int ret = 0;
431
    CYGARC_HAL_SAVE_GP();
432
 
433
    switch (__func) {
434
    case __COMMCTL_IRQ_ENABLE:
435
        irq_state = 1;
436
 
437
        // Need to keep it enabled to allow polling using ISR
438
        //HAL_WRITE_UINT32(chan->base+_UART_IES, _UART_INTS_RE);
439
 
440
#ifdef LATER
441
        HAL_INTERRUPT_UNMASK(chan->isr_vector);
442
#endif
443
        break;
444
    case __COMMCTL_IRQ_DISABLE:
445
        ret = irq_state;
446
        irq_state = 0;
447
 
448
        // Need to keep it enabled to allow polling using ISR
449
        // HAL_WRITE_UINT32(chan->base+_UART_IEC, _UART_INTS_RE);
450
 
451
#ifdef LATER
452
        HAL_INTERRUPT_MASK(chan->isr_vector);
453
#endif
454
        break;
455
    case __COMMCTL_DBG_ISR_VECTOR:
456
#ifdef LATER
457
        ret = chan->isr_vector;
458
#else
459
        ret = 0;
460
#endif
461
        break;
462
    case __COMMCTL_SET_TIMEOUT:
463
    {
464
        va_list ap;
465
 
466
        va_start(ap, __func);
467
 
468
        ret = chan->msec_timeout;
469
        chan->msec_timeout = va_arg(ap, cyg_uint32);
470
 
471
        va_end(ap);
472
    }
473
    default:
474
        break;
475
    }
476
    CYGARC_HAL_RESTORE_GP();
477
    return ret;
478
}
479
 
480
static int
481
cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc,
482
                       CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
483
{
484
#ifdef LATER
485
    int res = 0;
486
    channel_data_t* chan = (channel_data_t*)__ch_data;
487
    cyg_uint32 isr, ch, rsr;
488
    char c;
489
    CYGARC_HAL_SAVE_GP();
490
 
491
    cyg_drv_interrupt_acknowledge(chan->isr_vector);
492
 
493
    *__ctrlc = 0;
494
    HAL_READ_UINT32(chan->base+_UART_ISR, isr);
495
    HAL_READ_UINT32(chan->base+_UART_RSR, rsr);
496
 
497
    // Again, check both RI and the RX FIFO count.
498
    if ( ((isr & _UART_INTS_RI) != 0 ) || (rsr) ) {
499
 
500
        HAL_READ_UINT32(chan->base+_UART_RD, ch);
501
 
502
        c = (char)ch;
503
        if( cyg_hal_is_break( &c , 1 ) )
504
            *__ctrlc = 1;
505
 
506
        res = CYG_ISR_HANDLED;
507
    }
508
 
509
    CYGARC_HAL_RESTORE_GP();
510
    return res;
511
#else
512
    return 0;
513
#endif
514
}
515
 
516
static void
517
cyg_hal_plf_serial_init(void)
518
{
519
    hal_virtual_comm_table_t* comm;
520
    int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
521
 
522
#ifdef LATER
523
    // Disable interrupts.
524
    HAL_INTERRUPT_MASK(innovator_ser_channels[0].isr_vector);
525
 
526
    // Init channels
527
    cyg_hal_plf_serial_init_channel(&innovator_ser_channels[0]);
528
#else
529
    quick_init_uart();
530
#endif
531
 
532
    // Setup procs in the vector table
533
 
534
    // Set channel 0
535
    CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
536
    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
537
    CYGACC_COMM_IF_CH_DATA_SET(*comm, &innovator_ser_channels[0]);
538
    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
539
    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
540
    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
541
    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
542
    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
543
    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
544
    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
545
 
546
    // Restore original console
547
    CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
548
 
549
}
550
 
551
void
552
cyg_hal_plf_comms_init(void)
553
{
554
    static int initialized = 0;
555
 
556
    if (initialized)
557
        return;
558
 
559
    initialized = 1;
560
 
561
    cyg_hal_plf_serial_init();
562
}
563
 
564
//-----------------------------------------------------------------------------
565
// LEDs
566
void
567
hal_diag_led(int n)
568
{
569
}
570
 
571
//-----------------------------------------------------------------------------
572
// End of hal_diag.c

powered by: WebSVN 2.1.0

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