source: rtems/c/src/lib/libbsp/m68k/mcf52235/console/console.c @ 8f25cec

4.104.114.95
Last change on this file since 8f25cec was 3aac2db, checked in by Chris Johns <chrisj@…>, on 06/11/08 at 07:59:03

2008-06-10 Matthew Riek <matthew.riek@…>

  • .cvsignore, ChangeLog?, Makefile.am, README, bsp_specs, clock/clock.c, configure.ac, console/console.c, gdb-init, include/bsp.h, include/bspopts.h.in, include/coverhd.h, include/tm27.h, preinstall.am, start/start.S, startup/bspclean.c, startup/bspstart.c, startup/cfinit.c, startup/init52235.c, startup/linkcmds, timer/timer.c: New.
  • Property mode set to 100644
File size: 20.7 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 MCF_UART_USR_ERROR ( MCF_UART_USR_RB | \
21                             MCF_UART_USR_FE | \
22                             MCF_UART_USR_PE | \
23                             MCF_UART_USR_OE )
24
25static int IntUartPollWrite(int minor, const char *buf, int len);
26static int IntUartInterruptWrite (int minor, const char *buf, int 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 ( (MCF_UART_USR(CONSOLE_PORT) & MCF_UART_USR_TXRDY) == 0 )
37        continue;
38    MCF_UART_UTB(CONSOLE_PORT) = c;
39    while ( (MCF_UART_USR(CONSOLE_PORT) & MCF_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        MCF_UART_UIMR(minor) = 0;
85        MCF_UART_UOP0(minor) = 1;
86        MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_DISABLED | MCF_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 = bsp_get_CPU_clock_speed();
97    /* determine the baud divisor value */
98    // MRTODO
99    //divisor = ((clock_speed/2) / ( 32 * baud ));
100    divisor = ((clock_speed) / ( 32 * baud ));
101    if ( divisor < 2 )
102        divisor = 2;
103
104        /* check to see if doing hardware flow control */
105        if ( hwflow )
106        {
107                /* set hardware flow options */
108                umr1 |= MCF_UART_UMR_RXRTS;
109                umr2 |= MCF_UART_UMR_TXCTS;
110        }
111
112        /* determine the new umr values */
113        umr1 |= (parity | databits);
114        umr2 |= (stopbits);
115
116        /* reset the uart */
117        MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_ERROR;
118        MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_RX;
119        MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_TX;
120
121        /* reset the uart mode register and update values */
122        MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_MR;
123        MCF_UART_UMR(minor) = umr1;
124        MCF_UART_UMR(minor) = umr2;
125
126        /* set the baud rate values */
127        MCF_UART_UCSR(minor) = (MCF_UART_UCSR_RCS_SYS_CLK | MCF_UART_UCSR_TCS_SYS_CLK);
128        MCF_UART_UBG1(minor) = (divisor & 0xff00) >> 8;
129        MCF_UART_UBG2(minor) = (divisor & 0x00ff);
130
131        /* enable the uart */
132    MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED);
133
134        /* check to see if interrupts need to be enabled */
135        if ( info->iomode != TERMIOS_POLLED )
136        {
137                /* enable rx interrupts */
138                info->uimr |= MCF_UART_UIMR_RXRDY_FU;
139                MCF_UART_UIMR(minor) = info->uimr;
140        }
141
142        /* check to see if doing hardware flow control */
143        if ( hwflow )
144        {
145                /* assert the RTS line */
146                MCF_UART_UOP1(minor) = 1;
147        }
148
149        rtems_interrupt_enable(level);
150
151}
152
153
154/***************************************************************************
155   Function : IntUartSetAttributes
156
157   Description : This provides the hardware-dependent portion of tcsetattr().
158   value and sets it. At the moment this just sets the baud rate.
159
160   Note: The highest baudrate is 115200 as this stays within
161   an error of +/- 5% at 25MHz processor clock
162 ***************************************************************************/
163static int
164IntUartSetAttributes(int minor, const struct termios *t)
165{
166        /* set default index values */
167        int                         baud     = (int)19200;
168        int                         databits = (int)MCF_UART_UMR_BC_8;
169        int                         parity   = (int)MCF_UART_UMR_PM_NONE;
170        int                         stopbits = (int)MCF_UART_UMR_SB_STOP_BITS_1;
171        int                         hwflow   = (int)0;
172        struct IntUartInfoStruct   *info     = &IntUartInfo[minor];
173
174        /* check to see if input is valid */
175        if ( t != (const struct termios *)0 )
176        {
177                /* determine baud rate index */
178                baud = termios_baud_to_number(t->c_cflag & CBAUD);
179
180                /* determine data bits */
181                switch ( t->c_cflag & CSIZE )
182                {
183                        case CS5:
184                                databits = (int)MCF_UART_UMR_BC_5;
185                                break;
186                        case CS6:
187                                databits = (int)MCF_UART_UMR_BC_6;
188                                break;
189                        case CS7:
190                                databits = (int)MCF_UART_UMR_BC_7;
191                                break;
192                        case CS8:
193                                databits = (int)MCF_UART_UMR_BC_8;
194                                break;
195                }
196
197                /* determine if parity is enabled */
198                if ( t->c_cflag & PARENB )
199                {
200                        if ( t->c_cflag & PARODD )
201                        {
202                                /* odd parity */
203                                parity = (int)MCF_UART_UMR_PM_ODD;
204                        }
205                        else
206                        {
207                                /* even parity */
208                                parity = (int)MCF_UART_UMR_PM_EVEN;
209                        }
210                }
211
212                /* determine stop bits */
213                if ( t->c_cflag & CSTOPB )
214                {
215                        /* two stop bits */
216                        stopbits = (int)MCF_UART_UMR_SB_STOP_BITS_2;
217                }
218
219                /* check to see if hardware flow control */
220                if ( t->c_cflag & CRTSCTS )
221                {
222                        hwflow = 1;
223                }
224        }
225
226        /* check to see if values have changed */
227        if ( ( baud     != info->baud     ) ||
228                 ( databits != info->databits ) ||
229                 ( parity   != info->parity   ) ||
230                 ( stopbits != info->stopbits ) ||
231                 ( hwflow   != info->hwflow   ) )
232        {
233
234                /* call function to set values */
235                IntUartSet(minor, baud, databits, parity, stopbits, hwflow);
236        }
237
238        return( RTEMS_SUCCESSFUL );
239
240}
241
242/***************************************************************************
243   Function : IntUartInterruptHandler
244
245   Description : This is the interrupt handler for the internal uart. It
246   determines which channel caused the interrupt before queueing any received
247   chars and dequeueing chars waiting for transmission.
248 ***************************************************************************/
249static rtems_isr
250IntUartInterruptHandler(rtems_vector_number v)
251{
252        unsigned int                chan = v - UART_INTC0_IRQ_VECTOR(0);
253        struct IntUartInfoStruct   *info = &IntUartInfo[chan];
254
255        /* check to see if received data */
256        if ( MCF_UART_UISR(chan) & MCF_UART_UISR_RXRDY_FU )
257        {
258                /* read data and put into the receive buffer */
259                while ( MCF_UART_USR(chan) & MCF_UART_USR_RXRDY )
260                {
261
262                        if ( MCF_UART_USR(chan) & MCF_UART_USR_ERROR )
263                        {
264                                /* clear the error */
265                                MCF_UART_UCR(chan) = MCF_UART_UCR_RESET_ERROR;
266                        }
267                        /* put data in rx buffer and check for errors */
268                        info->rx_buffer[info->rx_in] = MCF_UART_URB(chan);
269
270                        /* update buffer values */
271                        info->rx_in++;
272
273                        if ( info->rx_in >= RX_BUFFER_SIZE )
274                        {
275                                info->rx_in = 0;
276                        }
277                }
278                /* Make sure the port has been opened */
279                if ( info->ttyp )
280                {
281
282                        /* check to see if task driven */
283                        if ( info->iomode == TERMIOS_TASK_DRIVEN )
284                        {
285                                /* notify rx task that rx buffer has data */
286                                rtems_termios_rxirq_occured(info->ttyp);
287                        }
288                        else
289                        {
290                                /* Push up the received data */
291                                rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer, info->rx_in);
292                                info->rx_in    = 0;
293                        }
294                }
295        }
296
297        /* check to see if data needs to be transmitted */
298        if ( ( info->uimr & MCF_UART_UIMR_TXRDY ) &&
299                 ( MCF_UART_UISR(chan) & MCF_UART_UISR_TXRDY ) )
300        {
301
302                /* disable tx interrupts */
303                info->uimr &= ~MCF_UART_UIMR_TXRDY;
304                MCF_UART_UIMR(chan) = info->uimr;
305
306                /* tell upper level that character has been sent */
307                if ( info->ttyp )
308                        rtems_termios_dequeue_characters(info->ttyp, 1);
309        }
310}
311
312
313
314/***************************************************************************
315   Function : IntUartInitialize
316
317   Description : This initialises the internal uart hardware for all
318   internal uarts. If the internal uart is to be interrupt driven then the
319   interrupt vectors are hooked.
320 ***************************************************************************/
321static void
322IntUartInitialize(void)
323{
324        unsigned int        chan;
325        struct IntUartInfoStruct   *info;
326        rtems_isr_entry old_handler;
327    int level;
328
329        for ( chan = 0; chan < MAX_UART_INFO; chan++ )
330        {
331                info = &IntUartInfo[chan];
332
333                info->ttyp     = NULL;
334                info->rx_in    = 0;
335                info->rx_out   = 0;
336                info->baud     = -1;
337                info->databits = -1;
338                info->parity   = -1;
339                info->stopbits = -1;
340                info->hwflow   = -1;
341                info->iomode   = TERMIOS_POLLED; /*polled console io */
342
343                MCF_UART_UACR(chan) = 0;
344                MCF_UART_UIMR(chan) = 0;
345                if ( info->iomode != TERMIOS_POLLED )
346                {
347                        rtems_interrupt_catch (IntUartInterruptHandler,
348                                                                   UART_INTC0_IRQ_VECTOR(chan),
349                                                                   &old_handler);
350                }
351
352                /* set uart default values */
353                IntUartSetAttributes(chan, NULL);
354
355        /* unmask interrupt */
356                rtems_interrupt_disable(level);
357        switch(chan) {
358        case 0:
359            MCF_INTC0_ICR13 = MCF_INTC_ICR_IL(UART0_IRQ_LEVEL) |
360                                  MCF_INTC_ICR_IP(UART0_IRQ_PRIORITY);
361            MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK13 |
362                                    MCF_INTC_IMRL_MASKALL);
363            break;
364
365        case 1:
366            MCF_INTC0_ICR14 = MCF_INTC_ICR_IL(UART1_IRQ_LEVEL) |
367                                  MCF_INTC_ICR_IP(UART1_IRQ_PRIORITY);
368            MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK14 |
369                                    MCF_INTC_IMRL_MASKALL);
370            break;
371
372        case 2:
373            MCF_INTC0_ICR15 = MCF_INTC_ICR_IL(UART2_IRQ_LEVEL) |
374                                  MCF_INTC_ICR_IP(UART2_IRQ_PRIORITY);
375            MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK15 |
376                                    MCF_INTC_IMRL_MASKALL);
377            break;
378        }
379                rtems_interrupt_enable(level);
380
381        } /* of chan loop */
382
383
384} /* IntUartInitialise */
385
386
387/***************************************************************************
388   Function : IntUartInterruptWrite
389
390   Description : This writes a single character to the appropriate uart
391   channel. This is either called during an interrupt or in the user's task
392   to initiate a transmit sequence. Calling this routine enables Tx
393   interrupts.
394 ***************************************************************************/
395static int
396IntUartInterruptWrite (int minor, const char *buf, int len)
397{
398        int level;
399
400        rtems_interrupt_disable(level);
401
402        /* write out character */
403        MCF_UART_UTB(minor) = *buf;
404
405        /* enable tx interrupt */
406        IntUartInfo[minor].uimr |= MCF_UART_UIMR_TXRDY;
407        MCF_UART_UIMR(minor) = IntUartInfo[minor].uimr;
408
409        rtems_interrupt_enable(level);
410        return( 0 );
411}
412
413/***************************************************************************
414   Function : IntUartInterruptOpen
415
416   Description : This enables interrupts when the tty is opened.
417 ***************************************************************************/
418static int
419IntUartInterruptOpen(int major, int minor, void *arg)
420{
421        struct IntUartInfoStruct   *info = &IntUartInfo[minor];
422
423        /* enable the uart */
424        MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED);
425
426        /* check to see if interrupts need to be enabled */
427        if ( info->iomode != TERMIOS_POLLED )
428        {
429                /* enable rx interrupts */
430                info->uimr |= MCF_UART_UIMR_RXRDY_FU;
431                MCF_UART_UIMR(minor) = info->uimr;
432        }
433
434        /* check to see if doing hardware flow control */
435        if ( info->hwflow )
436        {
437                /* assert the RTS line */
438                MCF_UART_UOP1(minor) = 1;
439        }
440
441        return( 0 );
442}
443
444
445
446/***************************************************************************
447   Function : IntUartInterruptClose
448
449   Description : This disables interrupts when the tty is closed.
450 ***************************************************************************/
451static int
452IntUartInterruptClose(int major, int minor, void *arg)
453{
454        struct IntUartInfoStruct   *info = &IntUartInfo[minor];
455
456        /* disable the interrupts and the uart */
457        MCF_UART_UIMR(minor) = 0;
458        MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_DISABLED | MCF_UART_UCR_RX_DISABLED);
459
460        /* reset values */
461        info->ttyp     = NULL;
462        info->uimr       = 0;
463        info->rx_in    = 0;
464        info->rx_out   = 0;
465
466        return( 0 );
467}
468
469/***************************************************************************
470   Function : IntUartTaskRead
471
472   Description : This reads all available characters from the internal uart
473   and places them into the termios buffer.  The rx interrupts will be
474   re-enabled after all data has been read.
475 ***************************************************************************/
476static int
477IntUartTaskRead(int minor)
478{
479        char                        buffer[RX_BUFFER_SIZE];
480        int                         count;
481        int                         rx_in;
482        int                         index = 0;
483        struct IntUartInfoStruct   *info  = &IntUartInfo[minor];
484
485        /* determine number of values to copy out */
486        rx_in = info->rx_in;
487        if ( info->rx_out <= rx_in )
488        {
489                count = rx_in - info->rx_out;
490        }
491        else
492        {
493                count = (RX_BUFFER_SIZE - info->rx_out) + rx_in;
494        }
495
496        /* copy data into local buffer from rx buffer */
497        while ( ( index < count ) && ( index < RX_BUFFER_SIZE ) )
498        {
499                /* copy data byte */
500                buffer[index] = info->rx_buffer[info->rx_out];
501                index++;
502
503                /* increment rx buffer values */
504                info->rx_out++;
505                if ( info->rx_out >= RX_BUFFER_SIZE )
506                {
507                        info->rx_out = 0;
508                }
509        }
510
511        /* check to see if buffer is not empty */
512        if ( count > 0 )
513        {
514                /* set characters into termios buffer  */
515                rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count);
516        }
517
518        return( EOF );
519}
520
521
522
523/***************************************************************************
524   Function : IntUartPollRead
525
526   Description : This reads a character from the internal uart. It returns
527   to the caller without blocking if not character is waiting.
528 ***************************************************************************/
529static int
530IntUartPollRead (int minor)
531{
532        if ( (MCF_UART_USR(minor) & MCF_UART_USR_RXRDY) == 0 )
533                return(-1);
534
535        return(MCF_UART_URB(minor));
536}
537
538
539/***************************************************************************
540   Function : IntUartPollWrite
541
542   Description : This writes out each character in the buffer to the
543   appropriate internal uart channel waiting till each one is sucessfully
544   transmitted.
545 ***************************************************************************/
546static int
547IntUartPollWrite (int minor, const char *buf, int len)
548{
549        /* loop over buffer */
550        while ( len-- )
551        {
552                /* block until we can transmit */
553                while ( (MCF_UART_USR(minor) & MCF_UART_USR_TXRDY) == 0 )
554                        continue;
555                /* transmit data byte */
556                MCF_UART_UTB(minor) = *buf++;
557        }
558        return(0);
559}
560
561
562/***************************************************************************
563   Function : console_initialize
564
565   Description : This initialises termios, both sets of uart hardware before
566   registering /dev/tty devices for each channel and the system /dev/console.
567 ***************************************************************************/
568rtems_device_driver console_initialize(
569        rtems_device_major_number  major,
570        rtems_device_minor_number  minor,
571        void  *arg )
572{
573        rtems_status_code status;
574
575
576        /* Set up TERMIOS */
577        rtems_termios_initialize ();
578
579        /* set io modes for the different channels and initialize device */
580    IntUartInfo[minor].iomode = TERMIOS_IRQ_DRIVEN;
581        IntUartInitialize();
582
583        /* Register the console port */
584        status = rtems_io_register_name ("/dev/console", major, CONSOLE_PORT);
585        if ( status != RTEMS_SUCCESSFUL )
586        {
587                rtems_fatal_error_occurred (status);
588        }
589
590        /* Register the other port */
591        if ( CONSOLE_PORT != 0 )
592        {
593                status = rtems_io_register_name ("/dev/tty00", major, 0);
594                if ( status != RTEMS_SUCCESSFUL )
595                {
596                        rtems_fatal_error_occurred (status);
597                }
598        }
599        if ( CONSOLE_PORT != 1 )
600        {
601                status = rtems_io_register_name ("/dev/tty01", major, 1);
602                if ( status != RTEMS_SUCCESSFUL )
603                {
604                        rtems_fatal_error_occurred (status);
605                }
606        }
607
608        return(RTEMS_SUCCESSFUL);
609}
610
611/***************************************************************************
612   Function : console_open
613
614   Description : This actually opens the device depending on the minor
615   number set during initialisation. The device specific access routines are
616   passed to termios when the devices is opened depending on whether it is
617   polled or not.
618 ***************************************************************************/
619rtems_device_driver console_open(
620        rtems_device_major_number major,
621        rtems_device_minor_number minor,
622        void  * arg)
623{
624        rtems_status_code                status = RTEMS_INVALID_NUMBER;
625        rtems_libio_open_close_args_t   *args   = (rtems_libio_open_close_args_t *)arg;
626        struct IntUartInfoStruct        *info;
627
628        static const rtems_termios_callbacks IntUartPollCallbacks = {
629                NULL,                             /* firstOpen */
630                NULL,                             /* lastClose */
631                IntUartPollRead,          /* pollRead */
632                IntUartPollWrite,         /* write */
633                IntUartSetAttributes, /* setAttributes */
634                NULL,                             /* stopRemoteTx */
635                NULL,                             /* startRemoteTx */
636                TERMIOS_POLLED            /* mode */
637        };
638        static const rtems_termios_callbacks IntUartIntrCallbacks = {
639                IntUartInterruptOpen,  /* firstOpen */
640                IntUartInterruptClose, /* lastClose */
641                NULL,                              /* pollRead */
642                IntUartInterruptWrite, /* write */
643                IntUartSetAttributes,  /* setAttributes */
644                NULL,                              /* stopRemoteTx */
645                NULL,                              /* startRemoteTx */
646                TERMIOS_IRQ_DRIVEN         /* mode */
647        };
648
649        static const rtems_termios_callbacks IntUartTaskCallbacks = {
650                IntUartInterruptOpen,  /* firstOpen */
651                IntUartInterruptClose, /* lastClose */
652                IntUartTaskRead,           /* pollRead */
653                IntUartInterruptWrite, /* write */
654                IntUartSetAttributes,  /* setAttributes */
655                NULL,                              /* stopRemoteTx */
656                NULL,                              /* startRemoteTx */
657                TERMIOS_TASK_DRIVEN        /* mode */
658        };
659
660        /* open the port depending on the minor device number */
661        if ( ( minor >= 0 ) && ( minor < MAX_UART_INFO ) )
662        {
663                info = &IntUartInfo[minor];
664                switch ( info->iomode )
665                {
666                        case TERMIOS_POLLED:
667                                status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks);
668                                break;
669                        case TERMIOS_IRQ_DRIVEN:
670                                status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks);
671                                info->ttyp = args->iop->data1;
672                                break;
673                        case TERMIOS_TASK_DRIVEN:
674                                status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks);
675                                info->ttyp = args->iop->data1;
676                                break;
677                }
678        }
679
680        if (status == RTEMS_SUCCESSFUL)
681        {
682                /*
683                * Reset the default baudrate.
684                */
685                struct termios term;
686                if (tcgetattr (STDIN_FILENO, &term) >= 0)
687                {
688                        term.c_cflag &= ~(CBAUD | CSIZE);
689                        term.c_cflag |= CS8 | B19200;
690                        tcsetattr (STDIN_FILENO, TCSANOW, &term);
691                }
692        }
693
694        return( status );
695}
696
697/***************************************************************************
698   Function : console_close
699
700   Description : This closes the device via termios
701 ***************************************************************************/
702rtems_device_driver console_close(
703        rtems_device_major_number major,
704        rtems_device_minor_number minor,
705        void   * arg)
706{
707    return(rtems_termios_close (arg));
708}
709
710/******************
711*********************************************************
712   Function : console_read
713
714   Description : Read from the device via termios
715 ***************************************************************************/
716rtems_device_driver console_read(
717        rtems_device_major_number major,
718        rtems_device_minor_number minor,
719        void  * arg)
720{
721    return(rtems_termios_read (arg));
722}
723
724/***************************************************************************
725   Function : console_write
726
727   Description : Write to the device via termios
728 ***************************************************************************/
729rtems_device_driver console_write(
730        rtems_device_major_number major,
731        rtems_device_minor_number minor,
732        void  * arg)
733{
734    return(rtems_termios_write (arg));
735}
736
737/***************************************************************************
738   Function : console_ioctl
739
740   Description : Pass the IOCtl call to termios
741 ***************************************************************************/
742rtems_device_driver console_control(
743        rtems_device_major_number major,
744        rtems_device_minor_number minor,
745        void  * arg)
746{
747    return( rtems_termios_ioctl (arg) );
748}
749int DEBUG_OUTCHAR(int c)
750{
751    if(c == '\n')
752        DEBUG_OUTCHAR('\r');
753    _BSP_null_char(c);
754    return c;
755}
756void DEBUG_OUTSTR(const char *msg)
757{
758    while (*msg)
759        DEBUG_OUTCHAR(*msg++);
760}
761void DEBUG_OUTNUM(int i)
762{
763    int n;
764    static const char map[] = "0123456789ABCDEF";
765    DEBUG_OUTCHAR(' ');
766    for (n = 28 ; n >= 0 ; n -= 4)
767        DEBUG_OUTCHAR(map[(i >> n) & 0xF]);
768}
Note: See TracBrowser for help on using the repository browser.