source: rtems/c/src/lib/libbsp/m68k/av5282/console/console.c @ 39a9f8e

4.104.11
Last change on this file since 39a9f8e was 39a9f8e, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on Dec 17, 2009 at 8:42:17 AM

adapted to new prototype for *_write function

  • Property mode set to 100644
File size: 20.8 KB
Line 
1 /*
2  *  Multi UART console serial I/O.
3  *
4  * TO DO: Add DMA input/output
5  */
6
7#include <stdio.h>
8#include <fcntl.h>
9#include <rtems/libio.h>
10#include <rtems/termiostypes.h>
11#include <termios.h>
12#include <bsp.h>
13#include <malloc.h>
14#include <rtems/mw_uid.h>
15
16#include <rtems/bspIo.h>
17
18#define UART_INTC0_IRQ_VECTOR(x) (64+13+(x))
19
20#define MCF5282_UART_USR_ERROR ( MCF5282_UART_USR_RB | \
21                                 MCF5282_UART_USR_FE | \
22                                 MCF5282_UART_USR_PE | \
23                                 MCF5282_UART_USR_OE )
24
25static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len);
26static ssize_t IntUartInterruptWrite (int minor, const char *buf, size_t len);
27
28static void
29_BSP_null_char( char c )
30{
31        int level;
32
33    if (c == '\n')
34        _BSP_null_char('\r');
35        rtems_interrupt_disable(level);
36    while ( (MCF5282_UART_USR(CONSOLE_PORT) & MCF5282_UART_USR_TXRDY) == 0 )
37        continue;
38    MCF5282_UART_UTB(CONSOLE_PORT) = c;
39    while ( (MCF5282_UART_USR(CONSOLE_PORT) & MCF5282_UART_USR_TXRDY) == 0 )
40        continue;
41        rtems_interrupt_enable(level);
42}
43BSP_output_char_function_type BSP_output_char = _BSP_null_char;
44
45#define MAX_UART_INFO     3
46#define RX_BUFFER_SIZE    512
47
48struct IntUartInfoStruct
49{
50        int                    iomode;
51        volatile int           uimr;
52        int                    baud;
53        int                    databits;
54        int                    parity;
55        int                    stopbits;
56        int                    hwflow;
57        int                    rx_in;
58        int                    rx_out;
59        char                   rx_buffer[RX_BUFFER_SIZE];
60        void                  *ttyp;
61};
62
63struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO];
64
65/***************************************************************************
66   Function : IntUartSet
67
68   Description : This updates the hardware UART settings.
69 ***************************************************************************/
70static void
71IntUartSet(int minor, int baud, int databits, int parity, int stopbits, int hwflow)
72{
73        int                         divisor;
74        uint32_t                                        clock_speed;
75        uint8_t                   umr1 = 0;
76        uint8_t                   umr2 = 0;
77        struct IntUartInfoStruct   *info = &IntUartInfo[minor];
78        int                         level;
79
80        rtems_interrupt_disable(level);
81
82
83        /* disable interrupts, clear RTS line, and disable the UARTS */
84        MCF5282_UART_UIMR(minor) = 0;
85        MCF5282_UART_UOP0(minor) = 1;
86        MCF5282_UART_UCR(minor) = (MCF5282_UART_UCR_TX_DISABLED | MCF5282_UART_UCR_RX_DISABLED);
87
88        /* save the current values */
89        info->uimr     = 0;
90        info->baud     = baud;
91        info->databits = databits;
92        info->parity   = parity;
93        info->stopbits = stopbits;
94        info->hwflow   = hwflow;
95
96    clock_speed = get_CPU_clock_speed();
97    /* determine the baud divisor value */
98    divisor = (clock_speed / ( 32 * baud ));
99    if ( divisor < 2 )
100        divisor = 2;
101
102        /* check to see if doing hardware flow control */
103        if ( hwflow )
104        {
105                /* set hardware flow options */
106                umr1 |= MCF5282_UART_UMR1_RXRTS;
107                umr2 |= MCF5282_UART_UMR2_TXCTS;
108        }
109
110        /* determine the new umr values */
111        umr1 |= (parity | databits);
112        umr2 |= (stopbits);
113
114        /* reset the uart */
115        MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_ERROR;
116        MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_RX;
117        MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_TX;
118
119        /* reset the uart mode register and update values */
120        MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_MR;
121        MCF5282_UART_UMR(minor) = umr1;
122        MCF5282_UART_UMR(minor) = umr2;
123
124        /* set the baud rate values */
125        MCF5282_UART_UCSR(minor) = (MCF5282_UART_UCSR_RCS_SYS_CLK | MCF5282_UART_UCSR_TCS_SYS_CLK);
126        MCF5282_UART_UBG1(minor) = (divisor & 0xff00) >> 8;
127        MCF5282_UART_UBG2(minor) = (divisor & 0x00ff);
128
129        /* enable the uart */
130    MCF5282_UART_UCR(minor) = (MCF5282_UART_UCR_TX_ENABLED | MCF5282_UART_UCR_RX_ENABLED);
131
132        /* check to see if interrupts need to be enabled */
133        if ( info->iomode != TERMIOS_POLLED )
134        {
135                /* enable rx interrupts */
136                info->uimr |= MCF5282_UART_UIMR_FFULL;
137                MCF5282_UART_UIMR(minor) = info->uimr;
138        }
139
140        /* check to see if doing hardware flow control */
141        if ( hwflow )
142        {
143                /* assert the RTS line */
144                MCF5282_UART_UOP1(minor) = 1;
145        }
146
147        rtems_interrupt_enable(level);
148
149}
150
151
152/***************************************************************************
153   Function : IntUartSetAttributes
154
155   Description : This provides the hardware-dependent portion of tcsetattr().
156   value and sets it. At the moment this just sets the baud rate.
157
158   Note: The highest baudrate is 115200 as this stays within
159   an error of +/- 5% at 25MHz processor clock
160 ***************************************************************************/
161static int
162IntUartSetAttributes(int minor, const struct termios *t)
163{
164        /* set default index values */
165        int                         baud     = (int)19200;
166        int                         databits = (int)MCF5282_UART_UMR1_BC_8;
167        int                         parity   = (int)MCF5282_UART_UMR1_PM_NONE;
168        int                         stopbits = (int)MCF5282_UART_UMR2_STOP_BITS_1;
169        int                         hwflow   = (int)0;
170        struct IntUartInfoStruct   *info     = &IntUartInfo[minor];
171
172        /* check to see if input is valid */
173        if ( t != (const struct termios *)0 )
174        {
175                /* determine baud rate index */
176                baud = rtems_termios_baud_to_number(t->c_cflag & CBAUD);
177
178                /* determine data bits */
179                switch ( t->c_cflag & CSIZE )
180                {
181                        case CS5:
182                                databits = (int)MCF5282_UART_UMR1_BC_5;
183                                break;
184                        case CS6:
185                                databits = (int)MCF5282_UART_UMR1_BC_6;
186                                break;
187                        case CS7:
188                                databits = (int)MCF5282_UART_UMR1_BC_7;
189                                break;
190                        case CS8:
191                                databits = (int)MCF5282_UART_UMR1_BC_8;
192                                break;
193                }
194
195                /* determine if parity is enabled */
196                if ( t->c_cflag & PARENB )
197                {
198                        if ( t->c_cflag & PARODD )
199                        {
200                                /* odd parity */
201                                parity = (int)MCF5282_UART_UMR1_PM_ODD;
202                        }
203                        else
204                        {
205                                /* even parity */
206                                parity = (int)MCF5282_UART_UMR1_PM_EVEN;
207                        }
208                }
209
210                /* determine stop bits */
211                if ( t->c_cflag & CSTOPB )
212                {
213                        /* two stop bits */
214                        stopbits = (int)MCF5282_UART_UMR2_STOP_BITS_2;
215                }
216
217                /* check to see if hardware flow control */
218                if ( t->c_cflag & CRTSCTS )
219                {
220                        hwflow = 1;
221                }
222        }
223
224        /* check to see if values have changed */
225        if ( ( baud     != info->baud     ) ||
226                 ( databits != info->databits ) ||
227                 ( parity   != info->parity   ) ||
228                 ( stopbits != info->stopbits ) ||
229                 ( hwflow   != info->hwflow   ) )
230        {
231
232                /* call function to set values */
233                IntUartSet(minor, baud, databits, parity, stopbits, hwflow);
234        }
235
236        return( RTEMS_SUCCESSFUL );
237
238}
239
240/***************************************************************************
241   Function : IntUartInterruptHandler
242
243   Description : This is the interrupt handler for the internal uart. It
244   determines which channel caused the interrupt before queueing any received
245   chars and dequeueing chars waiting for transmission.
246 ***************************************************************************/
247static rtems_isr
248IntUartInterruptHandler(rtems_vector_number v)
249{
250        unsigned int                chan = v - UART_INTC0_IRQ_VECTOR(0);
251        struct IntUartInfoStruct   *info = &IntUartInfo[chan];
252
253        /* check to see if received data */
254        if ( MCF5282_UART_UISR(chan) & MCF5282_UART_UISR_RXRDY )
255        {
256                /* read data and put into the receive buffer */
257                while ( MCF5282_UART_USR(chan) & MCF5282_UART_USR_RXRDY )
258                {
259
260                        if ( MCF5282_UART_USR(chan) & MCF5282_UART_USR_ERROR )
261                        {
262                                /* clear the error */
263                                MCF5282_UART_UCR(chan) = MCF5282_UART_UCR_RESET_ERROR;
264                        }
265                        /* put data in rx buffer and check for errors */
266                        info->rx_buffer[info->rx_in] = MCF5282_UART_URB(chan);
267
268                        /* update buffer values */
269                        info->rx_in++;
270
271                        if ( info->rx_in >= RX_BUFFER_SIZE )
272                        {
273                                info->rx_in = 0;
274                        }
275                }
276                /* Make sure the port has been opened */
277                if ( info->ttyp )
278                {
279
280                        /* check to see if task driven */
281                        if ( info->iomode == TERMIOS_TASK_DRIVEN )
282                        {
283                                /* notify rx task that rx buffer has data */
284                                rtems_termios_rxirq_occured(info->ttyp);
285                        }
286                        else
287                        {
288                                /* Push up the received data */
289                                rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer, info->rx_in);
290                                info->rx_in    = 0;
291                        }
292                }
293        }
294
295        /* check to see if data needs to be transmitted */
296        if ( ( info->uimr & MCF5282_UART_UIMR_TXRDY ) &&
297                 ( MCF5282_UART_UISR(chan) & MCF5282_UART_UISR_TXRDY ) )
298        {
299
300                /* disable tx interrupts */
301                info->uimr &= ~MCF5282_UART_UIMR_TXRDY;
302                MCF5282_UART_UIMR(chan) = info->uimr;
303
304                /* tell upper level that character has been sent */
305                if ( info->ttyp )
306                        rtems_termios_dequeue_characters(info->ttyp, 1);
307        }
308}
309
310
311
312/***************************************************************************
313   Function : IntUartInitialize
314
315   Description : This initialises the internal uart hardware for all
316   internal uarts. If the internal uart is to be interrupt driven then the
317   interrupt vectors are hooked.
318 ***************************************************************************/
319static void
320IntUartInitialize(void)
321{
322        unsigned int        chan;
323        struct IntUartInfoStruct   *info;
324        rtems_isr_entry old_handler;
325    int level;
326
327        for ( chan = 0; chan < MAX_UART_INFO; chan++ )
328        {
329                info = &IntUartInfo[chan];
330
331                info->ttyp     = NULL;
332                info->rx_in    = 0;
333                info->rx_out   = 0;
334                info->baud     = -1;
335                info->databits = -1;
336                info->parity   = -1;
337                info->stopbits = -1;
338                info->hwflow   = -1;
339                info->iomode   = TERMIOS_POLLED;
340
341                MCF5282_UART_UACR(chan) = 0;
342                MCF5282_UART_UIMR(chan) = 0;
343                if ( info->iomode != TERMIOS_POLLED )
344                {
345                        rtems_interrupt_catch (IntUartInterruptHandler,
346                                                                   UART_INTC0_IRQ_VECTOR(chan),
347                                                                   &old_handler);
348                }
349
350                /* set uart default values */
351                IntUartSetAttributes(chan, NULL);
352
353        /* unmask interrupt */
354                rtems_interrupt_disable(level);
355        switch(chan) {
356        case 0:
357            MCF5282_INTC0_ICR13 = MCF5282_INTC_ICR_IL(UART0_IRQ_LEVEL) |
358                                  MCF5282_INTC_ICR_IP(UART0_IRQ_PRIORITY);
359            MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT13 |
360                                    MCF5282_INTC_IMRL_MASKALL);
361            break;
362
363        case 1:
364            MCF5282_INTC0_ICR14 = MCF5282_INTC_ICR_IL(UART1_IRQ_LEVEL) |
365                                  MCF5282_INTC_ICR_IP(UART1_IRQ_PRIORITY);
366            MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT14 |
367                                    MCF5282_INTC_IMRL_MASKALL);
368            break;
369
370        case 2:
371            MCF5282_INTC0_ICR15 = MCF5282_INTC_ICR_IL(UART2_IRQ_LEVEL) |
372                                  MCF5282_INTC_ICR_IP(UART2_IRQ_PRIORITY);
373            MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT15 |
374                                    MCF5282_INTC_IMRL_MASKALL);
375            break;
376        }
377                rtems_interrupt_enable(level);
378
379        } /* of chan loop */
380
381
382} /* IntUartInitialise */
383
384
385/***************************************************************************
386   Function : IntUartInterruptWrite
387
388   Description : This writes a single character to the appropriate uart
389   channel. This is either called during an interrupt or in the user's task
390   to initiate a transmit sequence. Calling this routine enables Tx
391   interrupts.
392 ***************************************************************************/
393static ssize_t
394IntUartInterruptWrite (int minor, const char *buf, size_t len)
395{
396        int level;
397
398        rtems_interrupt_disable(level);
399
400        /* write out character */
401        MCF5282_UART_UTB(minor) = *buf;
402
403        /* enable tx interrupt */
404        IntUartInfo[minor].uimr |= MCF5282_UART_UIMR_TXRDY;
405        MCF5282_UART_UIMR(minor) = IntUartInfo[minor].uimr;
406
407        rtems_interrupt_enable(level);
408        return( 0 );
409}
410
411/***************************************************************************
412   Function : IntUartInterruptOpen
413
414   Description : This enables interrupts when the tty is opened.
415 ***************************************************************************/
416static int
417IntUartInterruptOpen(int major, int minor, void *arg)
418{
419        struct IntUartInfoStruct   *info = &IntUartInfo[minor];
420
421        /* enable the uart */
422        MCF5282_UART_UCR(minor) = (MCF5282_UART_UCR_TX_ENABLED | MCF5282_UART_UCR_RX_ENABLED);
423
424        /* check to see if interrupts need to be enabled */
425        if ( info->iomode != TERMIOS_POLLED )
426        {
427                /* enable rx interrupts */
428                info->uimr |= MCF5282_UART_UIMR_FFULL;
429                MCF5282_UART_UIMR(minor) = info->uimr;
430        }
431
432        /* check to see if doing hardware flow control */
433        if ( info->hwflow )
434        {
435                /* assert the RTS line */
436                MCF5282_UART_UOP1(minor) = 1;
437        }
438
439        return( 0 );
440}
441
442
443
444/***************************************************************************
445   Function : IntUartInterruptClose
446
447   Description : This disables interrupts when the tty is closed.
448 ***************************************************************************/
449static int
450IntUartInterruptClose(int major, int minor, void *arg)
451{
452        struct IntUartInfoStruct   *info = &IntUartInfo[minor];
453
454        /* disable the interrupts and the uart */
455        MCF5282_UART_UIMR(minor) = 0;
456        MCF5282_UART_UCR(minor) = (MCF5282_UART_UCR_TX_DISABLED | MCF5282_UART_UCR_RX_DISABLED);
457
458        /* reset values */
459        info->ttyp     = NULL;
460        info->uimr       = 0;
461        info->rx_in    = 0;
462        info->rx_out   = 0;
463
464        return( 0 );
465}
466
467/***************************************************************************
468   Function : IntUartTaskRead
469
470   Description : This reads all available characters from the internal uart
471   and places them into the termios buffer.  The rx interrupts will be
472   re-enabled after all data has been read.
473 ***************************************************************************/
474static int
475IntUartTaskRead(int minor)
476{
477        char                        buffer[RX_BUFFER_SIZE];
478        int                         count;
479        int                         rx_in;
480        int                         index = 0;
481        struct IntUartInfoStruct   *info  = &IntUartInfo[minor];
482
483        /* determine number of values to copy out */
484        rx_in = info->rx_in;
485        if ( info->rx_out <= rx_in )
486        {
487                count = rx_in - info->rx_out;
488        }
489        else
490        {
491                count = (RX_BUFFER_SIZE - info->rx_out) + rx_in;
492        }
493
494        /* copy data into local buffer from rx buffer */
495        while ( ( index < count ) && ( index < RX_BUFFER_SIZE ) )
496        {
497                /* copy data byte */
498                buffer[index] = info->rx_buffer[info->rx_out];
499                index++;
500
501                /* increment rx buffer values */
502                info->rx_out++;
503                if ( info->rx_out >= RX_BUFFER_SIZE )
504                {
505                        info->rx_out = 0;
506                }
507        }
508
509        /* check to see if buffer is not empty */
510        if ( count > 0 )
511        {
512                /* set characters into termios buffer  */
513                rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count);
514        }
515
516        return( EOF );
517}
518
519
520
521/***************************************************************************
522   Function : IntUartPollRead
523
524   Description : This reads a character from the internal uart. It returns
525   to the caller without blocking if not character is waiting.
526 ***************************************************************************/
527static int
528IntUartPollRead (int minor)
529{
530        if ( (MCF5282_UART_USR(minor) & MCF5282_UART_USR_RXRDY) == 0 )
531                return(-1);
532
533        return(MCF5282_UART_URB(minor));
534}
535
536
537/***************************************************************************
538   Function : IntUartPollWrite
539
540   Description : This writes out each character in the buffer to the
541   appropriate internal uart channel waiting till each one is sucessfully
542   transmitted.
543 ***************************************************************************/
544static ssize_t
545IntUartPollWrite (int minor, const char *buf, size_t len)
546{
547        size_t retval = len;
548        /* loop over buffer */
549        while ( len-- )
550        {
551                /* block until we can transmit */
552                while ( (MCF5282_UART_USR(minor) & MCF5282_UART_USR_TXRDY) == 0 )
553                        continue;
554                /* transmit data byte */
555                MCF5282_UART_UTB(minor) = *buf++;
556        }
557        return retval;
558}
559
560/***************************************************************************
561   Function : console_initialize
562
563   Description : This initialises termios, both sets of uart hardware before
564   registering /dev/tty devices for each channel and the system /dev/console.
565 ***************************************************************************/
566rtems_device_driver console_initialize(
567        rtems_device_major_number  major,
568        rtems_device_minor_number  minor,
569        void  *arg )
570{
571        rtems_status_code status;
572
573
574        /* Set up TERMIOS */
575        rtems_termios_initialize ();
576
577        /* set io modes for the different channels and initialize device */
578    IntUartInfo[minor].iomode = TERMIOS_IRQ_DRIVEN;
579        IntUartInitialize();
580
581        /* Register the console port */
582        status = rtems_io_register_name ("/dev/console", major, CONSOLE_PORT);
583        if ( status != RTEMS_SUCCESSFUL )
584        {
585                rtems_fatal_error_occurred (status);
586        }
587
588        /* Register the other port */
589        if ( CONSOLE_PORT != 0 )
590        {
591                status = rtems_io_register_name ("/dev/tty00", major, 0);
592                if ( status != RTEMS_SUCCESSFUL )
593                {
594                        rtems_fatal_error_occurred (status);
595                }
596        }
597        if ( CONSOLE_PORT != 1 )
598        {
599                status = rtems_io_register_name ("/dev/tty01", major, 1);
600                if ( status != RTEMS_SUCCESSFUL )
601                {
602                        rtems_fatal_error_occurred (status);
603                }
604        }
605
606        return(RTEMS_SUCCESSFUL);
607}
608
609/***************************************************************************
610   Function : console_open
611
612   Description : This actually opens the device depending on the minor
613   number set during initialisation. The device specific access routines are
614   passed to termios when the devices is opened depending on whether it is
615   polled or not.
616 ***************************************************************************/
617rtems_device_driver console_open(
618        rtems_device_major_number major,
619        rtems_device_minor_number minor,
620        void  * arg)
621{
622        rtems_status_code                status = RTEMS_INVALID_NUMBER;
623        rtems_libio_open_close_args_t   *args   = (rtems_libio_open_close_args_t *)arg;
624        struct IntUartInfoStruct        *info;
625
626        static const rtems_termios_callbacks IntUartPollCallbacks = {
627                NULL,                             /* firstOpen */
628                NULL,                             /* lastClose */
629                IntUartPollRead,          /* pollRead */
630                IntUartPollWrite,         /* write */
631                IntUartSetAttributes, /* setAttributes */
632                NULL,                             /* stopRemoteTx */
633                NULL,                             /* startRemoteTx */
634                TERMIOS_POLLED            /* mode */
635        };
636        static const rtems_termios_callbacks IntUartIntrCallbacks = {
637                IntUartInterruptOpen,  /* firstOpen */
638                IntUartInterruptClose, /* lastClose */
639                NULL,                              /* pollRead */
640                IntUartInterruptWrite, /* write */
641                IntUartSetAttributes,  /* setAttributes */
642                NULL,                              /* stopRemoteTx */
643                NULL,                              /* startRemoteTx */
644                TERMIOS_IRQ_DRIVEN         /* mode */
645        };
646
647        static const rtems_termios_callbacks IntUartTaskCallbacks = {
648                IntUartInterruptOpen,  /* firstOpen */
649                IntUartInterruptClose, /* lastClose */
650                IntUartTaskRead,           /* pollRead */
651                IntUartInterruptWrite, /* write */
652                IntUartSetAttributes,  /* setAttributes */
653                NULL,                              /* stopRemoteTx */
654                NULL,                              /* startRemoteTx */
655                TERMIOS_TASK_DRIVEN        /* mode */
656        };
657
658        /* open the port depending on the minor device number */
659        if ( ( minor >= 0 ) && ( minor < MAX_UART_INFO ) )
660        {
661                info = &IntUartInfo[minor];
662                switch ( info->iomode )
663                {
664                        case TERMIOS_POLLED:
665                                status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks);
666                                break;
667                        case TERMIOS_IRQ_DRIVEN:
668                                status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks);
669                                info->ttyp = args->iop->data1;
670                                break;
671                        case TERMIOS_TASK_DRIVEN:
672                                status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks);
673                                info->ttyp = args->iop->data1;
674                                break;
675                }
676        }
677
678        return( status );
679}
680
681/***************************************************************************
682   Function : console_close
683
684   Description : This closes the device via termios
685 ***************************************************************************/
686rtems_device_driver console_close(
687        rtems_device_major_number major,
688        rtems_device_minor_number minor,
689        void   * arg)
690{
691    return(rtems_termios_close (arg));
692}
693
694/******************
695*********************************************************
696   Function : console_read
697
698   Description : Read from the device via termios
699 ***************************************************************************/
700rtems_device_driver console_read(
701        rtems_device_major_number major,
702        rtems_device_minor_number minor,
703        void  * arg)
704{
705    return(rtems_termios_read (arg));
706}
707
708/***************************************************************************
709   Function : console_write
710
711   Description : Write to the device via termios
712 ***************************************************************************/
713rtems_device_driver console_write(
714        rtems_device_major_number major,
715        rtems_device_minor_number minor,
716        void  * arg)
717{
718    return(rtems_termios_write (arg));
719}
720
721/***************************************************************************
722   Function : console_ioctl
723
724   Description : Pass the IOCtl call to termios
725 ***************************************************************************/
726rtems_device_driver console_control(
727        rtems_device_major_number major,
728        rtems_device_minor_number minor,
729        void  * arg)
730{
731    return( rtems_termios_ioctl (arg) );
732}
733int DEBUG_OUTCHAR(int c)
734{
735    if(c == '\n')
736        DEBUG_OUTCHAR('\r');
737    _BSP_null_char(c);
738    return c;
739}
740void DEBUG_OUTSTR(const char *msg)
741{
742    while (*msg)
743        DEBUG_OUTCHAR(*msg++);
744}
745void DEBUG_OUTNUM(int i)
746{
747    int n;
748    static const char map[] = "0123456789ABCDEF";
749    DEBUG_OUTCHAR(' ');
750    for (n = 28 ; n >= 0 ; n -= 4)
751        DEBUG_OUTCHAR(map[(i >> n) & 0xF]);
752}
Note: See TracBrowser for help on using the repository browser.