OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libbsp/] [m68k/] [mvme162/] [consolex/] [consolex.c] - Blame information for rev 173

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*
2
 *  This file contains the MVME162LX extended console IO package.
3
 *
4
 *  This file was created originally by
5
 *  On-Line Applications Research Corporation (OAR)
6
 *  and modified by:
7
 *
8
 *  Katsutoshi Shibuya - BU-Denken Co.,Ltd. - Sapporo, JAPAN
9
 *
10
 *  featuring support of:
11
 *
12
 *     - Multi-SCC chip handling
13
 *     - Non-blocking I/O (O_NDELAY flag in libc)
14
 *     - Raw mode device (no CR/LF detection)
15
 *     - RTS/CTS flow control
16
 *
17
 *  REMARKS: This routine requires multiple interrupt vectors
18
 *           from SCC_VECTOR (normaly 0x40)
19
 *           to SCC_VECTOR+(number of SCC chips)
20
 *
21
 *  The original copyright follows;
22
 *
23
 *  COPYRIGHT (c) 1989-1999.
24
 *  On-Line Applications Research Corporation (OAR).
25
 *
26
 *  The license and distribution terms for this file may be
27
 *  found in the file LICENSE in this distribution or at
28
 *  http://www.OARcorp.com/rtems/license.html.
29
 *
30
 *  Modifications of respective RTEMS file: COPYRIGHT (c) 1994.
31
 *  EISCAT Scientific Association. M.Savitski
32
 *
33
 *  This material is a part of the MVME162 Board Support Package
34
 *  for the RTEMS executive. Its licensing policies are those of the
35
 *  RTEMS above.
36
 *
37
 *  $Id: consolex.c,v 1.2 2001-09-27 12:00:18 chris Exp $
38
 */
39
 
40
#define M162_INIT
41
 
42
#include "consolex.h"
43
#include <bsp.h>
44
#include <rtems/libio.h>
45
#include <stdio.h>
46
#include <string.h>
47
#include <ctype.h>
48
 
49
#define NPORTS  4       /* Number of ports */
50
#define DEVICEPREFIX    "tty"
51
#define RAWDEVICEPREFIX "rtty"
52
#define CONSOLEPORT 0   /* port# of console:
53
                           undef this if you do not want /dev/console */
54
#define READRETRY 1     /* Maximum retry count for read one char */
55
#define WRITERETRY 8    /* Maximum retry count for write one char */
56
 
57
#define PORTFROM 0      /* for debug */
58
 
59
static unsigned char    opencount[NPORTS];
60
 
61
/***********************************************************************
62
   Ring buffer for device
63
 ***********************************************************************/
64
 
65
#define QUEUE_LENGTH 128        /* Must be 2^n number */
66
 
67
typedef struct {
68
  char buffer[QUEUE_LENGTH];
69
  volatile int  head;
70
  volatile int  tail;
71
} ReceiverBuffer;
72
 
73
#define ReceiverBufferInitialize( _buffer ) \
74
  do { \
75
    (_buffer)->head = (_buffer)->tail = 0; \
76
  } while ( 0 )
77
 
78
#define ReceiverBufferIsEmpty( _buffer ) \
79
   ( (_buffer)->tail == (_buffer)->head )
80
 
81
#define ReceiverBufferIsNearEmpty( _buffer ) \
82
   ( (_buffer)->tail == (((_buffer)->head + 3) & (QUEUE_LENGTH-1)) )
83
 
84
#define ReceiverBufferIsFull( _buffer ) \
85
   ( (_buffer)->head == (((_buffer)->tail + 1) & (QUEUE_LENGTH-1)) )
86
 
87
#define ReceiverBufferIsNearFull( _buffer ) \
88
   ( (_buffer)->head == (((_buffer)->tail + 3) & (QUEUE_LENGTH-1)) )
89
 
90
#define ReceiverBufferAdd( _buffer, _ch ) \
91
  do { \
92
    rtems_unsigned32 isrlevel; \
93
    \
94
    rtems_interrupt_disable( isrlevel ); \
95
      (_buffer)->tail = ((_buffer)->tail+1) & (QUEUE_LENGTH-1); \
96
      (_buffer)->buffer[ (_buffer)->tail ] = (_ch); \
97
    rtems_interrupt_enable( isrlevel ); \
98
  } while ( 0 )
99
 
100
#define ReceiverBufferRemove( _buffer, _ch ) \
101
  do { \
102
    rtems_unsigned32 isrlevel; \
103
    \
104
    rtems_interrupt_disable( isrlevel ); \
105
      (_buffer)->head = ((_buffer)->head+1) & (QUEUE_LENGTH-1); \
106
      (_ch) = (_buffer)->buffer[ (_buffer)->head ]; \
107
    rtems_interrupt_enable( isrlevel ); \
108
  } while ( 0 )
109
 
110
 
111
/***********************************************************************
112
   DEVICE DEPENDED PART
113
 ***********************************************************************/
114
 
115
 
116
/* Time constant parameters
117
   CAUTION: These parameters are for MVME162LX-213 board.
118
 */
119
 
120
#define TC38400 0x0006
121
#define TC19200 0x000e
122
#define TC9600  0x001e
123
 
124
/* Re-defining SCC register control macros
125
   to support Multi SCC chips */
126
 
127
#undef  scc
128
#if defined(mvme162lx)
129
static scc_regs *scc[NPORTS] = {
130
    ((scc_regs * const) 0xFFF45004),
131
    ((scc_regs * const) 0xFFF45000),
132
    ((scc_regs * const) 0xFFF45804),
133
    ((scc_regs * const) 0xFFF45800)
134
};
135
#else
136
/* XXX fix me */
137
#warning "MVME162 BSP -- unknown address for SCC's"
138
static scc_regs *scc[NPORTS] = {
139
    ((scc_regs * const) 0xFFF45004),
140
    ((scc_regs * const) 0xFFF45000),
141
    ((scc_regs * const) 0xFFF45804),
142
    ((scc_regs * const) 0xFFF45800)
143
};
144
#endif
145
 
146
#undef  ZWRITE0
147
#define ZWRITE0(port, v)  (scc[port]->csr = (unsigned char)(v))
148
#undef  ZREAD0
149
#define ZREAD0(port)  (scc[port]->csr)
150
 
151
#undef  ZREAD
152
#define ZREAD(port, n)  (ZWRITE0(port, n), (scc[port]->csr))
153
#undef  ZREADD
154
#define ZREADD(port)  (scc[port]->csr=0x08, scc[port]->csr )
155
 
156
#undef  ZWRITE
157
#define ZWRITE(port, n, v) (ZWRITE0(port, n), ZWRITE0(port, v))
158
#undef  ZWRITED
159
#define ZWRITED(port, v)  (scc[port]->csr = 0x08, \
160
                           scc[port]->csr = (unsigned char)(v))
161
 
162
static ReceiverBuffer   receiverBuffer[NPORTS];
163
 
164
/*
165
 *  Control flags (DTR/DCD/RTS/CTS)
166
 */
167
 
168
static unsigned char    wr4[NPORTS];
169
static unsigned char    wr5[NPORTS];
170
#define SCCSetDTR(port) ZWRITE(port, 5, (wr5[port] |= 0x80))
171
#define SCCResetDTR(port) ZWRITE(port, 5, (wr5[port] &= ~0x80))
172
#define SCCSetRTS(port) ZWRITE(port, 5, (wr5[port] |= 0x02))
173
#define SCCResetRTS(port) ZWRITE(port,5, (wr5[port] &= ~0x02))
174
#define SCCGetDCD(port) (ZREAD0(port)&0x08)
175
#define SCCGetCTS(port) (ZREAD0(port)&0x20)
176
 
177
 
178
/*
179
 *  Interrupt handler for receiver interrupts
180
 */
181
 
182
static rtems_isr        SCCReceiverISR(rtems_vector_number vector)
183
{
184
    register int    ipend, port;
185
 
186
    port = (vector-SCC_VECTOR)*2;
187
    ZWRITE0(port, 0x38);        /* reset highest IUS */
188
 
189
    ipend = ZREAD(port, 3);     /* read int pending from A side */
190
 
191
    if(ipend == 0x04)
192
        port++; /* channel B intr pending */
193
    else if(ipend == 0x20)
194
        ;       /* channel A intr pending */
195
    else
196
        return;
197
 
198
    ReceiverBufferAdd(&receiverBuffer[port], ZREADD(port));
199
 
200
    if(ZREAD(port,1) & 0x70){ /* check error stat */
201
        ZWRITE0(port, 0x30);    /* reset error */
202
    }
203
 
204
    if(ReceiverBufferIsNearFull(&receiverBuffer[port]))
205
        SCCResetRTS(port);
206
}
207
 
208
/*
209
 * Initialize
210
 */
211
 
212
void    SCCInitialize()
213
{
214
    int     i;
215
 
216
    for(i = PORTFROM; i < NPORTS; i+=2)
217
        ZWRITE(i, 9,0xc0);      /* Reset SCC Chip */
218
 
219
    for(i = PORTFROM; i < NPORTS; i++){
220
        ReceiverBufferInitialize(&(receiverBuffer[i]));
221
        wr4[i] = 0x44;
222
        ZWRITE(i, 4, wr4[i]);   /* x16 clock, 1 stop, parity none */
223
        ZWRITE(i, 1, 0); /* disable interrupts */
224
        ZWRITE(i, 2, SCC_VECTOR+(i/2));
225
        ZWRITE(i, 3, 0xc1);     /* receiver enable, 8bits */
226
        wr5[i] = 0x68;
227
        ZWRITE(i, 5, wr5[i]);   /* transmitter enable, 8bits, DTR&RTS off */
228
        ZWRITE(i,14, 0); /* stop baudrate gen. */
229
        ZWRITE(i,11,0x50);      /* use baurate gen. */
230
        ZWRITE(i,15, 1);        /* Select WR7' */
231
        ZWRITE(i, 7, 0); /* Disable all special interrupts */
232
        ZWRITE(i,10, 0);
233
        ZWRITE(i, 1, 0x10);     /* int on all Rx chars or special condition */
234
        set_vector(SCCReceiverISR, SCC_VECTOR+(i/2), 1); /* install ISR */
235
        ZWRITE(i, 9, 8);        /* master interrupt enable */
236
        ZWRITE(i,12,TC38400&0xff);      /* set 38400 baud */
237
        ZWRITE(i,13,TC38400>>8);
238
        ZWRITE(i,14, 3);        /* start baudrate gen. */
239
                                /* CAUTION: If your SCC use XTAL on RTxC,
240
                                   write 1 */
241
    }
242
    mcchip->vector_base = 0;
243
    mcchip->gen_control = 2;    /* MIEN */
244
    mcchip->SCC_int_ctl = 0x13; /* SCC IEN, IPL3 */
245
}
246
 
247
/*
248
 *   Non-blocking char input
249
 */
250
 
251
rtems_boolean   SCCGetOne(int port, char *ch)
252
{
253
    int retry = READRETRY;
254
    while(ReceiverBufferIsEmpty(&receiverBuffer[port]))
255
        if(--retry <= 0)
256
            return FALSE;
257
 
258
    ReceiverBufferRemove(&receiverBuffer[port],*ch);
259
 
260
    if(ReceiverBufferIsNearEmpty(&receiverBuffer[port]))
261
        SCCSetRTS(port);
262
    return TRUE;
263
}
264
 
265
/*
266
 *   Blocking char input
267
 */
268
 
269
char    SCCGetOneBlocked(int port)
270
{
271
    unsigned char tmp_char;
272
 
273
    while (!SCCGetOne(port, &tmp_char))
274
        rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
275
    return tmp_char;
276
}
277
 
278
/*
279
 *   Non-blocking char input
280
 *   No longer supports XON/XOFF flow control.
281
 */
282
 
283
rtems_boolean   SCCSendOne(int port, char ch)
284
{
285
    int retry = WRITERETRY;
286
 
287
    if(!SCCGetCTS(port))
288
        return FALSE;
289
    while(!(ZREAD0(port) & TX_BUFFER_EMPTY))
290
        if(--retry <= 0)
291
            return FALSE;
292
    ZWRITED(port, ch);
293
    return TRUE;
294
}
295
 
296
 
297
/*
298
 *   Blocking char output
299
 *   No longer supports XON/XOFF flow control.
300
 */
301
 
302
void    SCCSendOneBlocked(int port, char ch)
303
{
304
    while(!SCCSendOne(port, ch))
305
        rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
306
}
307
 
308
/*
309
 * Set parameters for transmission
310
 */
311
 
312
unsigned32      SCCSetAttributes(int port, struct termios *t)
313
{
314
    unsigned char       wr3;
315
 
316
    ZWRITE(port,1,0);    /* Disable interrupt */
317
    ZWRITE(port,3,0);    /* Disable receiver */
318
    /* Baud */
319
    switch(t->c_cflag & CBAUD){
320
    case B38400:
321
        ZWRITE(port,12,TC38400&0xff);
322
        ZWRITE(port,13,TC38400>>8);
323
        break;
324
    case B19200:
325
        ZWRITE(port,12,TC19200&0xff);
326
        ZWRITE(port,13,TC19200>>8);
327
        break;
328
    case B9600:
329
        ZWRITE(port,12,TC9600&0xff);
330
        ZWRITE(port,13,TC9600>>8);
331
        break;
332
    }
333
 
334
    /* Code size */
335
    wr5[port] &= 0x8f;
336
    wr3 = 0;     /* receiver control */
337
    switch(t->c_cflag & CSIZE){
338
    case CS8:
339
        wr5[port] |= 0x60;
340
        wr3 |= 0xc0;
341
        break;
342
    case CS7:
343
        wr5[port] |= 0x20;
344
        wr3 |= 0x40;
345
        break;
346
    }
347
 
348
    /* Parity */
349
    wr4[port] &= 0xf0;
350
    if(t->c_cflag & PARENB)
351
        wr4[port] |= 0x01;
352
    if(!(t->c_cflag & PARODD))
353
        wr4[port] |= 0x02;
354
    /* ZWRITE(port,4,wr4[port]);*/
355
 
356
    /* Stop bits */
357
    /* wr4[port] = ZREAD(port,4) & 0xfc;*/
358
    if(t->c_cflag & CSTOPB)
359
        wr4[port] |= 0x0c;
360
    else
361
        wr4[port] |= 0x04;
362
 
363
    ZWRITE(port,4,wr4[port]);   /* TxRx parameters */
364
    ZWRITE(port,5,wr5[port]);   /* Transmission parameters */
365
    ZWRITE(port,3,wr3|0x01);    /* Enable receiver */
366
    ZWRITE(port,1,0x10);        /* Enable interrupt */
367
 
368
    return 0;
369
}
370
 
371
/*
372
 * Get parameters for transmission
373
 */
374
 
375
unsigned32      SCCGetAttributes(int port, struct termios *t)
376
{
377
    unsigned32  b;
378
 
379
    t->c_cflag = 0;
380
 
381
    /* Baud */
382
    b = ZREAD(port,13);
383
    b <<= 8;
384
    b |= ZREAD(port,12);
385
    switch(b){
386
    case TC38400:
387
        t->c_cflag |= B38400;
388
        break;
389
    case TC19200:
390
        t->c_cflag |= B19200;
391
        break;
392
    case TC9600:
393
        t->c_cflag |= B9600;
394
        break;
395
    }
396
 
397
    /* Code size */
398
    /* wr = ZREAD(port,5);*/
399
    t->c_cflag &= ~CSIZE;
400
    switch(wr5[port]&0x60){
401
    case 0x60:
402
        t->c_cflag |= CS8;
403
        break;
404
    case 0x20:
405
        t->c_cflag |= CS7;
406
        break;
407
    }
408
 
409
    /* Parity */
410
    /* wr = ZREAD(port,4);*/
411
    if(wr4[port] & 0x01)
412
        t->c_cflag |= PARENB;
413
    else
414
        t->c_cflag &= ~PARENB;
415
    if(wr4[port] & 0x02)
416
        t->c_cflag &= ~PARODD;
417
    else
418
        t->c_cflag |= PARODD;
419
 
420
    /* Stop bits */
421
    /* wr = ZREAD(port,4);*/
422
    if((wr4[port]&0xc0) == 0xc0)
423
        t->c_cflag |= CSTOPB;
424
    else
425
        t->c_cflag &= ~CSTOPB;
426
 
427
    return 0;
428
}
429
 
430
/***********************************************************************
431
   DEVICE INDEPENDED PART
432
 ***********************************************************************/
433
 
434
#define LOCAL_ISTRIP    0x0001
435
#define LOCAL_INLCR     0x0002
436
#define LOCAL_IGNCR     0x0004
437
#define LOCAL_ICRNL     0x0008
438
#define LOCAL_IUCLC     0x0010
439
#define LOCAL_OLCUC     0x0020
440
#define LOCAL_ONLCR     0x0040
441
#define LOCAL_OCRNL     0x0080
442
#define LOCAL_ICANON    0x0100
443
#define LOCAL_ECHO      0x0200
444
 
445
/*
446
 *  Device initialize entry point
447
 */
448
 
449
rtems_device_driver consolex_initialize(rtems_device_major_number  major,
450
                                        rtems_device_minor_number  minor,
451
                                        void *arg)
452
{
453
    rtems_status_code   status;
454
    char        devname[16];
455
    int         i;
456
 
457
    SCCInitialize();
458
 
459
#ifdef  CONSOLEPORT
460
    status = rtems_io_register_name("/dev/console",major,
461
                                    (rtems_device_minor_number) CONSOLEPORT);
462
    if (status != RTEMS_SUCCESSFUL)
463
        rtems_fatal_error_occurred(status);
464
#endif
465
 
466
    for(i = PORTFROM; i < NPORTS; i++){
467
        /* Register cooked ttys */
468
        sprintf(devname,"/dev/%s%02d",DEVICEPREFIX,i);
469
        status = rtems_io_register_name(strdup(devname),major,
470
                                        (rtems_device_minor_number) i);
471
        if (status != RTEMS_SUCCESSFUL)
472
            rtems_fatal_error_occurred(status);
473
        /* Register raw ttys */
474
        sprintf(devname,"/dev/%s%02d",RAWDEVICEPREFIX,i);
475
        status = rtems_io_register_name(strdup(devname),major,
476
                                        (rtems_device_minor_number) i+NPORTS);
477
        if (status != RTEMS_SUCCESSFUL)
478
            rtems_fatal_error_occurred(status);
479
    }
480
 
481
    for(i = 0; i < NPORTS; i++){
482
        opencount[i] = 0;
483
    }
484
 
485
    return RTEMS_SUCCESSFUL;
486
}
487
 
488
/*
489
 *  Open entry point
490
 */
491
 
492
rtems_device_driver consolex_open(rtems_device_major_number major,
493
                                  rtems_device_minor_number minor,
494
                                  void *arg)
495
{
496
    rtems_libio_open_close_args_t *openargs = (rtems_libio_open_close_args_t *) arg;
497
    if(minor >= NPORTS)
498
        minor -= NPORTS;
499
    if(minor >= NPORTS)
500
        return RTEMS_INVALID_NUMBER;
501
 
502
    if(opencount[minor]++ == 0){
503
        /* first open */
504
        SCCSetDTR(minor);
505
        SCCSetRTS(minor);
506
    }
507
    openargs->iop->data0 = LOCAL_ICRNL|LOCAL_ONLCR|LOCAL_ICANON|LOCAL_ECHO;
508
    return RTEMS_SUCCESSFUL;
509
}
510
 
511
/*
512
 *  Close entry point
513
 */
514
 
515
rtems_device_driver consolex_close(rtems_device_major_number major,
516
                                   rtems_device_minor_number minor,
517
                                   void *arg)
518
{
519
    if(minor >= NPORTS)
520
        minor -= NPORTS;
521
    if(minor >= NPORTS)
522
        return RTEMS_INVALID_NUMBER;
523
 
524
    if(--(opencount[minor]) == 0){
525
        /* closed all */
526
        SCCResetRTS(minor);
527
        SCCResetDTR(minor);
528
    }
529
    return RTEMS_SUCCESSFUL;
530
}
531
 
532
/*
533
 * read bytes from the serial port.
534
 */
535
 
536
rtems_device_driver consolex_read_raw(rtems_device_major_number major,
537
                                      rtems_device_minor_number minor,
538
                                      void *arg)
539
{
540
    rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
541
    char *buffer;
542
    int count;
543
 
544
    if(minor >= NPORTS)
545
        return RTEMS_INVALID_NUMBER;
546
 
547
    buffer = rw_args->buffer;
548
    count = rw_args->count;
549
 
550
    if(rw_args->flags & LIBIO_FLAGS_NO_DELAY){
551
        /* Non blocking read */
552
        while(count){
553
            if(!SCCGetOne(minor,buffer))
554
                break;
555
            buffer++;
556
            count--;
557
        }
558
    }else{
559
        /* Blocking read */
560
        while(count){
561
            *buffer = SCCGetOneBlocked(minor);
562
            buffer++;
563
            count--;
564
        }
565
    }
566
 
567
    rw_args->bytes_moved = rw_args->count-count;
568
    return count ? RTEMS_UNSATISFIED : RTEMS_SUCCESSFUL;
569
}
570
 
571
rtems_device_driver consolex_read(rtems_device_major_number major,
572
                                      rtems_device_minor_number minor,
573
                                      void *arg)
574
{
575
    rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
576
    char *buffer;
577
    int count;
578
    unsigned32  mode;
579
 
580
    if(minor >= NPORTS)
581
        return consolex_read_raw(major,minor-NPORTS,arg);
582
 
583
    buffer = rw_args->buffer;
584
    count = rw_args->count;
585
    mode = rw_args->iop->data0;
586
 
587
    /* Cooked read */
588
    while(count){
589
        if(rw_args->flags & LIBIO_FLAGS_NO_DELAY){
590
            /* Non blocking read */
591
            if(!SCCGetOne(minor,buffer))
592
                break;
593
        }else{
594
            /* Blocking read */
595
            *buffer = SCCGetOneBlocked(minor);
596
        }
597
        if((mode&LOCAL_ICANON) && (*buffer == '\b')){
598
            if(buffer > (char *)(rw_args->buffer)){
599
                buffer--;
600
                count++;
601
                if(mode&LOCAL_ECHO){
602
                    SCCSendOneBlocked(minor,'\b');
603
                    SCCSendOneBlocked(minor,' ');
604
                    SCCSendOneBlocked(minor,'\b');
605
                }
606
            }
607
            continue;
608
        }
609
        if((mode&LOCAL_IGNCR) && (*buffer == '\r'))
610
            continue;
611
        if((mode&LOCAL_INLCR) && (*buffer == '\n'))
612
            *buffer = '\r';
613
        if((mode&LOCAL_ICRNL) && (*buffer == '\r'))
614
            *buffer = '\n';
615
        if((mode&LOCAL_IUCLC) && isupper((int)*buffer))
616
            *buffer = tolower(*buffer);
617
        if(mode&LOCAL_ISTRIP)
618
            *buffer &= 0x7f;
619
        if(mode&LOCAL_ECHO){
620
            /* Caution: Echo back is blocking output */
621
            SCCSendOneBlocked(minor,*buffer);
622
        }
623
        if((mode&LOCAL_ICANON) && (*buffer == '\n')){
624
            buffer++;
625
            count--;
626
            if(count)
627
                *buffer = 0;
628
            if((mode&LOCAL_ECHO)&&(mode&LOCAL_ONLCR))
629
                SCCSendOneBlocked(minor,'\r');
630
            break;      /* finish reading */
631
        }
632
        buffer++;
633
        count--;
634
    }
635
    rw_args->bytes_moved = rw_args->count-count;
636
    return count ? RTEMS_UNSATISFIED : RTEMS_SUCCESSFUL;
637
}
638
 
639
/*
640
 * write bytes to the serial port.
641
 */
642
 
643
rtems_device_driver consolex_write_raw(rtems_device_major_number major,
644
                                       rtems_device_minor_number minor,
645
                                       void * arg)
646
{
647
    rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
648
    char *buffer;
649
    int count;
650
 
651
    if(minor >= NPORTS)
652
        return RTEMS_INVALID_NUMBER;
653
 
654
    buffer = rw_args->buffer;
655
    count = rw_args->count;
656
 
657
    if(rw_args->flags & LIBIO_FLAGS_NO_DELAY){
658
        /* Non blocking write */
659
        while(count){
660
            if(!SCCSendOne(minor,*buffer))
661
                break;
662
            buffer++;
663
            count--;
664
        }
665
    }else{
666
        /* Blocking write */
667
        while(count){
668
            SCCSendOneBlocked(minor,*buffer);
669
            buffer++;
670
            count--;
671
        }
672
    }
673
 
674
    rw_args->bytes_moved = rw_args->count-count;
675
    return count ? RTEMS_UNSATISFIED : RTEMS_SUCCESSFUL;
676
}
677
 
678
rtems_device_driver consolex_write(rtems_device_major_number major,
679
                                   rtems_device_minor_number minor,
680
                                   void * arg)
681
{
682
    rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
683
    char *buffer;
684
    int count;
685
    char        ch;
686
    unsigned32  mode;
687
 
688
    if(minor >= NPORTS)
689
        return consolex_write_raw(major,minor-NPORTS,arg);
690
 
691
    buffer = rw_args->buffer;
692
    count = rw_args->count;
693
    mode = rw_args->iop->data0;
694
 
695
    /* Cooked write */
696
    while(count){
697
        ch = *buffer;
698
        if((mode&LOCAL_ONLCR) && (ch == '\n')){ /* Output CRLF */
699
            if(rw_args->flags & LIBIO_FLAGS_NO_DELAY){
700
                /* Non blocking write */
701
                if(!SCCSendOne(minor,'\r'))
702
                    break;
703
            }else{
704
                SCCSendOneBlocked(minor,'\r');
705
            }
706
        }
707
        if((mode&LOCAL_OCRNL) && (ch == '\r'))
708
            ch = '\n';
709
        if((mode&OLCUC) && (islower((int)ch)))
710
            ch = toupper(ch);
711
        if(rw_args->flags & LIBIO_FLAGS_NO_DELAY){
712
            /* Non blocking write */
713
            if(!SCCSendOne(minor,ch))
714
                break;
715
        }else{
716
            SCCSendOneBlocked(minor,ch);
717
        }
718
        buffer++;
719
        count--;
720
    }
721
 
722
    rw_args->bytes_moved = rw_args->count-count;
723
    return count ? RTEMS_UNSATISFIED : RTEMS_SUCCESSFUL;
724
}
725
 
726
/*
727
 *  IO Control entry point
728
 */
729
 
730
rtems_device_driver consolex_control(rtems_device_major_number major,
731
                                     rtems_device_minor_number minor,
732
                                     void * arg)
733
{
734
    rtems_libio_ioctl_args_t    *ioarg = (rtems_libio_ioctl_args_t *)arg;
735
    struct termios      *tm = ioarg->buffer;
736
    unsigned32  *mode = &(ioarg->iop->data0);
737
 
738
    if(minor >= NPORTS)
739
        minor -= NPORTS;
740
    if(minor >= NPORTS)
741
        return RTEMS_INVALID_NUMBER;
742
 
743
    switch(ioarg->command){
744
    case RTEMS_IO_GET_ATTRIBUTES:
745
        tm->c_iflag = tm->c_oflag = tm->c_cflag = tm->c_lflag = 0;
746
        if(*mode & LOCAL_ISTRIP)
747
            tm->c_iflag |= ISTRIP;
748
        if(*mode & LOCAL_INLCR)
749
            tm->c_iflag |= INLCR;
750
        if(*mode & LOCAL_IGNCR)
751
            tm->c_iflag |= IGNCR;
752
        if(*mode & LOCAL_ICRNL)
753
            tm->c_iflag |= ICRNL;
754
        if(*mode & LOCAL_IUCLC)
755
            tm->c_iflag |= IUCLC;
756
        if(*mode & LOCAL_OLCUC)
757
            tm->c_oflag |= OLCUC;
758
        if(*mode & LOCAL_ONLCR)
759
            tm->c_oflag |= ONLCR;
760
        if(*mode & LOCAL_OCRNL)
761
            tm->c_oflag |= OCRNL;
762
        if(*mode & LOCAL_ICANON)
763
            tm->c_lflag |= ICANON;
764
        if(*mode & LOCAL_ECHO)
765
            tm->c_lflag |= ECHO;
766
        ioarg->ioctl_return = SCCGetAttributes(minor,tm);
767
        break;
768
    case RTEMS_IO_SET_ATTRIBUTES:
769
        *mode = 0;
770
        if(tm->c_iflag & ISTRIP)
771
            *mode |= LOCAL_ISTRIP;
772
        if(tm->c_iflag & INLCR)
773
            *mode |= LOCAL_INLCR;
774
        if(tm->c_iflag & IGNCR)
775
            *mode |= LOCAL_IGNCR;
776
        if(tm->c_iflag & ICRNL)
777
            *mode |= LOCAL_ICRNL;
778
        if(tm->c_iflag & IUCLC)
779
            *mode |= LOCAL_IUCLC;
780
        if(tm->c_oflag & OLCUC)
781
            *mode |= LOCAL_OLCUC;
782
        if(tm->c_oflag & ONLCR)
783
            *mode |= LOCAL_ONLCR;
784
        if(tm->c_oflag & OCRNL)
785
            *mode |= LOCAL_OCRNL;
786
        if(tm->c_lflag & ICANON)
787
            *mode |= LOCAL_ICANON;
788
        if(tm->c_lflag & ECHO)
789
            *mode |= LOCAL_ECHO;
790
        ioarg->ioctl_return = SCCSetAttributes(minor,tm);
791
        break;
792
    default:
793
        return RTEMS_NOT_DEFINED;
794
    }
795
 
796
    return RTEMS_SUCCESSFUL;
797
}

powered by: WebSVN 2.1.0

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