source: rtems/c/src/lib/libbsp/m68k/uC5282/console/console.c @ 688696e4

4.104.114.84.95
Last change on this file since 688696e4 was 688696e4, checked in by Joel Sherrill <joel.sherrill@…>, on 03/12/07 at 11:18:23

2007-03-12 Joel Sherrill <joel@…>

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