source: rtems/c/src/lib/libbsp/m68k/genmcf548x/console/console.c @ 1bc0ad2

5
Last change on this file since 1bc0ad2 was 1bc0ad2, checked in by Sebastian Huber <sebastian.huber@…>, on 09/08/17 at 08:38:46

Simplify and unify BSP_output_char

The BSP_output_char should output a char and not mingle with high level
processing, e.g. '\n' to '\r\n' translation. Move this translation to
rtems_putc(). Remove it from all the BSP_output_char implementations.

Close #3122.

  • Property mode set to 100644
File size: 24.6 KB
Line 
1/*===============================================================*\
2| Project: RTEMS generic mcf548x BSP                              |
3+-----------------------------------------------------------------+
4| File: console.c                                                 |
5+-----------------------------------------------------------------+
6| The file contains the console driver code of generic MCF548x    |
7| BSP.                                                            |
8+-----------------------------------------------------------------+
9|                    Copyright (c) 2007                           |
10|                    Embedded Brains GmbH                         |
11|                    Obere Lagerstr. 30                           |
12|                    D-82178 Puchheim                             |
13|                    Germany                                      |
14|                    rtems@embedded-brains.de                     |
15+-----------------------------------------------------------------+
16|                                                                 |
17| Parts of the code has been derived from the "dBUG source code"  |
18| package Freescale is providing for M548X EVBs. The usage of     |
19| the modified or unmodified code and it's integration into the   |
20| generic mcf548x BSP has been done according to the Freescale    |
21| license terms.                                                  |
22|                                                                 |
23| The Freescale license terms can be reviewed in the file         |
24|                                                                 |
25|    Freescale_license.txt                                        |
26|                                                                 |
27+-----------------------------------------------------------------+
28|                                                                 |
29| The generic mcf548x BSP has been developed on the basic         |
30| structures and modules of the av5282 BSP.                       |
31|                                                                 |
32+-----------------------------------------------------------------+
33|                                                                 |
34| The license and distribution terms for this file may be         |
35| found in the file LICENSE in this distribution or at            |
36|                                                                 |
37| http://www.rtems.org/license/LICENSE.                           |
38|                                                                 |
39+-----------------------------------------------------------------+
40|                                                                 |
41|   date                      history                        ID   |
42| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
43| 12.11.07                    1.0                            ras  |
44|                                                                 |
45\*===============================================================*/
46
47 /*
48  *  Multi UART console serial I/O.
49  *
50  * TO DO: Add DMA input/output
51  */
52
53#include <stdio.h>
54#include <fcntl.h>
55#include <termios.h>
56#include <malloc.h>
57
58#include <bsp.h>
59#include <bsp/irq-generic.h>
60#include <rtems/libio.h>
61#include <rtems/termiostypes.h>
62#include <rtems/console.h>
63#include <rtems/bspIo.h>
64
65#define UART_INTC0_IRQ_VECTOR(x) (64+35-(x))
66
67#define MCF548X_PSC_SR_ERROR ( MCF548X_PSC_SR_RB_NEOF   | \
68                           MCF548X_PSC_SR_FE_PHYERR | \
69                           MCF548X_PSC_SR_PE_CRCERR | \
70                           MCF548X_PSC_SR_OE )
71
72static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len);
73static int IntUartPollRead (int minor);
74
75static void
76_BSP_null_char( char c )
77{
78        int level;
79
80        rtems_interrupt_disable(level);
81    while (!((MCF548X_PSC_SR(CONSOLE_PORT) & MCF548X_PSC_SR_TXRDY)))
82        continue;
83    *((uint8_t *) &MCF548X_PSC_TB(CONSOLE_PORT)) = c;
84    while (!((MCF548X_PSC_SR(CONSOLE_PORT) & MCF548X_PSC_SR_TXRDY)))
85        continue;
86        rtems_interrupt_enable(level);
87}
88BSP_output_char_function_type     BSP_output_char = _BSP_null_char;
89BSP_polling_getchar_function_type BSP_poll_char = NULL;
90
91#define MAX_UART_INFO     4
92#define RX_BUFFER_SIZE    248
93
94struct IntUartInfoStruct
95{
96        int                    iomode;
97        volatile int           imr;
98        int                    baud;
99        int                    databits;
100        int                    parity;
101        int                    stopbits;
102        int                    hwflow;
103        int                    rx_in;
104        int                    rx_out;
105        char                   rx_buffer[RX_BUFFER_SIZE];
106        void                  *ttyp;
107};
108
109struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO];
110
111static int GetBaud( int baudHandle )
112{
113        int baud = BSP_CONSOLE_BAUD;
114        switch(baudHandle)
115        {
116                case B0:
117                        baud = (int)0;
118                        break;
119                case B1200:
120                        baud = (int)1200;
121                        break;
122                case B2400:
123                        baud = (int)2400;
124                        break;
125                case B4800:
126                        baud = (int)4800;
127                        break;
128                case B9600:
129                        baud = (int)9600;
130                        break;
131                case B19200:
132                        baud = (int)19200;
133                        break;
134                case B38400:
135                        baud = (int)38400;
136                        break;
137                case B57600:
138                        baud = (int)57600;
139                        break;
140                case B115200:
141                        baud = (int)115200;
142                        break;
143        }
144        return baud;
145}
146
147/***************************************************************************
148   Function : IntUartSet
149
150   Description : This updates the hardware UART settings.
151 ***************************************************************************/
152static void
153IntUartSet(int minor, int baud, int databits, int parity, int stopbits, int hwflow)
154{
155        uint8_t                    psc_mode_1 = 0, psc_mode_2 = 0;
156        uint16_t                   divider;
157        int                        level;
158        struct IntUartInfoStruct   *info = &IntUartInfo[minor];
159
160        rtems_interrupt_disable(level);
161
162        /* disable interrupts, clear RTS line, and disable the UARTS */
163        /* Mask all psc interrupts */
164        MCF548X_PSC_IMR(minor) = 0x0000;
165
166        /* Clear RTS to send */
167        MCF548X_PSC_OPSET(minor) &= ~(MCF548X_PSC_OPSET_RTS);
168
169        /* Disable receiver and transmitter */
170    MCF548X_PSC_CR(minor) &= ~(MCF548X_PSC_CR_RX_ENABLED | MCF548X_PSC_CR_TX_ENABLED);
171
172    /* provide gpio settings */
173    switch (minor)
174          {
175      case 0:
176        MCF548X_GPIO_PAR_PSC0    = (0 | MCF548X_GPIO_PAR_PSC0_PAR_TXD0 | MCF548X_GPIO_PAR_PSC0_PAR_RXD0);
177
178        if(hwflow)
179          {
180          MCF548X_GPIO_PAR_PSC0 |= (0 | MCF548X_GPIO_PAR_PSC0_PAR_CTS0_CTS | MCF548X_GPIO_PAR_PSC0_PAR_RTS0_RTS);
181          }
182        break;
183      case 1:
184        MCF548X_GPIO_PAR_PSC1    = (0 | MCF548X_GPIO_PAR_PSC1_PAR_TXD1 | MCF548X_GPIO_PAR_PSC1_PAR_RXD1);
185
186        if(hwflow)
187          {
188          MCF548X_GPIO_PAR_PSC1 |= (0 | MCF548X_GPIO_PAR_PSC1_PAR_CTS1_CTS | MCF548X_GPIO_PAR_PSC1_PAR_RTS1_RTS);
189          }
190        break;
191      case 2:
192        MCF548X_GPIO_PAR_PSC2    = (0 | MCF548X_GPIO_PAR_PSC2_PAR_TXD2 | MCF548X_GPIO_PAR_PSC2_PAR_RXD2);
193
194        if(hwflow)
195          {
196          MCF548X_GPIO_PAR_PSC2 |= (0 | MCF548X_GPIO_PAR_PSC2_PAR_CTS2_CTS | MCF548X_GPIO_PAR_PSC2_PAR_RTS2_RTS);
197          }
198        break;
199      case 3:
200        MCF548X_GPIO_PAR_PSC3    = (0 | MCF548X_GPIO_PAR_PSC3_PAR_TXD3 | MCF548X_GPIO_PAR_PSC3_PAR_RXD3);
201
202        if(hwflow)
203          {
204          MCF548X_GPIO_PAR_PSC3 |= (0 | MCF548X_GPIO_PAR_PSC3_PAR_CTS3_CTS | MCF548X_GPIO_PAR_PSC3_PAR_RTS3_RTS);
205          }
206        break;
207      default:
208        break;
209        }
210
211    /* save the current values */
212        info->imr      = 0;
213        info->baud     = baud;
214        info->databits = databits;
215        info->parity   = parity;
216        info->stopbits = stopbits;
217        info->hwflow   = hwflow;
218
219    /* Put PSC in UART mode */
220        MCF548X_PSC_SICR(minor) = MCF548X_PSC_SICR_SIM_UART;
221
222    /* set the baud rate values */
223        MCF548X_PSC_CSR(minor) = (0 | MCF548X_PSC_CSR_RCSEL_SYS_CLK | MCF548X_PSC_CSR_TCSEL_SYS_CLK);
224
225        /* Calculate baud settings */
226        divider = (uint16_t)((get_CPU_clock_speed())/(baud * 32));
227        MCF548X_PSC_CTUR(minor) =  (uint8_t) ((divider >> 8) & 0xFF);
228        MCF548X_PSC_CTLR(minor) =  (uint8_t) (divider & 0xFF);
229
230        /* Reset transmitter, receiver, mode register, and error conditions */
231        MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_RESET_RX;
232        MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_RESET_TX;
233        MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_RESET_ERROR;
234        MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_BKCHGINT;
235        MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_RESET_MR;
236
237        /* check to see if doing hardware flow control */
238        if ( hwflow )
239        {
240                /* set hardware flow options */
241                psc_mode_1 = MCF548X_PSC_MR_RXRTS;
242        psc_mode_2 = MCF548X_PSC_MR_TXCTS;
243        }
244
245    /* set mode registers */
246        psc_mode_1 |= (uint8_t)(parity | databits);
247    psc_mode_2 |= (uint8_t)(stopbits);
248
249    /* set mode registers */
250        MCF548X_PSC_MR(minor) = psc_mode_1;
251    MCF548X_PSC_MR(minor) = psc_mode_2;
252
253    /* Setup FIFO Alarms */
254    MCF548X_PSC_RFAR(minor) = MCF548X_PSC_RFAR_ALARM(248);
255        MCF548X_PSC_TFAR(minor) = MCF548X_PSC_TFAR_ALARM(248);
256
257        /* check to see if interrupts need to be enabled */
258        if ( info->iomode != TERMIOS_POLLED )
259        {
260                /* enable rx interrupts */
261                info->imr |= MCF548X_PSC_IMR_RXRDY_FU;
262                MCF548X_PSC_IMR(minor) = info->imr;
263        }
264
265        /* check to see if doing hardware flow control */
266        if ( hwflow )
267        {
268                /* assert the RTS line */
269                MCF548X_PSC_OPSET(minor) = MCF548X_PSC_OPSET_RTS;
270        }
271
272        rtems_interrupt_enable(level);
273
274    /* Enable receiver and transmitter */
275        MCF548X_PSC_CR(minor) =(0 | MCF548X_PSC_CR_RX_ENABLED | MCF548X_PSC_CR_TX_ENABLED);
276
277
278}
279
280/***************************************************************************
281   Function : IntUartSetAttributes
282
283   Description : This provides the hardware-dependent portion of tcsetattr().
284   value and sets it. At the moment this just sets the baud rate.
285
286   Note: The highest baudrate is 115200 as this stays within
287   an error of +/- 5% at 25MHz processor clock
288 ***************************************************************************/
289static int
290IntUartSetAttributes(int minor, const struct termios *t)
291{
292/* set default index values */
293#ifdef HAS_DBUG
294        int                         baud     = DBUG_SETTINGS.console_baudrate;
295#else
296        int                         baud     = (int)BSP_CONSOLE_BAUD;
297#endif
298        int                         databits = (int)MCF548X_PSC_MR_BC_8;
299        int                         parity   = (int)MCF548X_PSC_MR_PM_NONE;
300        int                         stopbits = (int)MCF548X_PSC_MR_SB_STOP_BITS_1;
301        int                         hwflow   = (int)1;
302        struct IntUartInfoStruct   *info     = &IntUartInfo[minor];
303
304        /* check to see if input is valid */
305        if ( t != (const struct termios *)0 )
306        {
307                /* determine baud rate index */
308    baud = GetBaud( t->c_ospeed );
309
310                /* determine data bits */
311                switch ( t->c_cflag & CSIZE )
312                {
313                        case CS5:
314                                databits = (int)MCF548X_PSC_MR_BC_5;
315                                break;
316                        case CS6:
317                                databits = (int)MCF548X_PSC_MR_BC_6;
318                                break;
319                        case CS7:
320                                databits = (int)MCF548X_PSC_MR_BC_7;
321                                break;
322                        case CS8:
323                                databits = (int)MCF548X_PSC_MR_BC_8;
324                                break;
325                }
326
327                /* determine if parity is enabled */
328                if ( t->c_cflag & PARENB )
329                {
330                        if ( t->c_cflag & PARODD )
331                        {
332                                /* odd parity */
333                                parity = (int)MCF548X_PSC_MR_PM_ODD;
334                        }
335                        else
336                        {
337                                /* even parity */
338                                parity = (int)MCF548X_PSC_MR_PM_EVEN;
339                        }
340                }
341
342                /* determine stop bits */
343                if ( t->c_cflag & CSTOPB )
344                {
345                        /* two stop bits */
346                        stopbits = (int)MCF548X_PSC_MR_SB_STOP_BITS_2;
347                }
348
349                /* check to see if hardware flow control */
350                if ( t->c_cflag & CRTSCTS )
351                {
352                        hwflow = 1;
353                }
354        }
355
356        /* check to see if values have changed */
357        if ( ( baud     != info->baud     ) ||
358                 ( databits != info->databits ) ||
359                 ( parity   != info->parity   ) ||
360                 ( stopbits != info->stopbits ) ||
361                 ( hwflow   != info->hwflow   ) )
362        {
363
364                /* call function to set values */
365                IntUartSet(minor, baud, databits, parity, stopbits, hwflow);
366        }
367
368return RTEMS_SUCCESSFUL;
369
370}
371
372/***************************************************************************
373   Function : IntUartInterruptHandler
374
375   Description : This is the interrupt handler for the internal uart. It
376   determines which channel caused the interrupt before queueing any received
377   chars and dequeueing chars waiting for transmission.
378 ***************************************************************************/
379static rtems_isr
380IntUartInterruptHandler(rtems_vector_number v)
381{
382        unsigned int                chan = v - UART_INTC0_IRQ_VECTOR(0);
383        struct IntUartInfoStruct   *info = &IntUartInfo[chan];
384
385        /* check to see if received data */
386        if ( MCF548X_PSC_ISR(chan) & MCF548X_PSC_ISR_RXRDY_FU )
387        {
388                /* read data and put into the receive buffer */
389                while ( MCF548X_PSC_SR(chan) & MCF548X_PSC_SR_RXRDY )
390                {
391
392                   /* put data in rx buffer */
393                        info->rx_buffer[info->rx_in] = *((volatile uint8_t *)&MCF548X_PSC_RB(chan));
394
395           /* check for errors */
396           if ( MCF548X_PSC_SR(chan) & MCF548X_PSC_SR_ERROR )
397                        {
398                                /* clear the error */
399                                MCF548X_PSC_CR(chan) = MCF548X_PSC_CR_RESET_ERROR;
400                        }
401
402                        /* update buffer values */
403                        info->rx_in++;
404
405                        if ( info->rx_in >= RX_BUFFER_SIZE )
406                        {
407                                info->rx_in = 0;
408                        }
409                }
410                /* Make sure the port has been opened */
411                if ( info->ttyp )
412                {
413
414                        /* check to see if task driven */
415                        if ( info->iomode == TERMIOS_TASK_DRIVEN )
416                        {
417                                /* notify rx task that rx buffer has data */
418                                rtems_termios_rxirq_occured(info->ttyp);
419                        }
420                        else
421                        {
422                                /* Push up the received data */
423                                rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer, info->rx_in);
424                                info->rx_in    = 0;
425                        }
426                }
427        }
428
429        /* check to see if data needs to be transmitted */
430        if ( ( info->imr & MCF548X_PSC_IMR_TXRDY ) &&
431                 ( MCF548X_PSC_ISR(chan) & MCF548X_PSC_ISR_TXRDY ) )
432        {
433
434                /* disable tx interrupts */
435                info->imr &= ~MCF548X_PSC_IMR_TXRDY;
436                MCF548X_PSC_IMR(chan) = info->imr;
437
438                /* tell upper level that character has been sent */
439                if ( info->ttyp )
440                        rtems_termios_dequeue_characters(info->ttyp, 1);
441        }
442
443}
444
445/***************************************************************************
446   Function : IntUartInitialize
447
448   Description : This initialises the internal uart hardware for all
449   internal uarts. If the internal uart is to be interrupt driven then the
450   interrupt vectors are hooked.
451 ***************************************************************************/
452static void
453IntUartInitialize(void)
454{
455    unsigned int        chan;
456        struct IntUartInfoStruct   *info;
457        rtems_isr_entry old_handler;
458
459        for ( chan = 0; chan < MAX_UART_INFO; chan++ )
460        {
461                info = &IntUartInfo[chan];
462
463                info->ttyp     = NULL;
464                info->rx_in    = 0;
465                info->rx_out   = 0;
466                info->baud     = -1;
467                info->databits = -1;
468                info->parity   = -1;
469                info->stopbits = -1;
470                info->hwflow   = -1;
471
472                MCF548X_PSC_ACR(chan) = 0;
473                MCF548X_PSC_IMR(chan) = 0;
474                if ( info->iomode != TERMIOS_POLLED )
475                {
476                        rtems_interrupt_catch (IntUartInterruptHandler,
477                                                                   UART_INTC0_IRQ_VECTOR(chan),
478                                                                   &old_handler);
479                }
480
481                /* set uart default values */
482                IntUartSetAttributes(chan, NULL);
483
484                /* unmask interrupt */
485                bsp_interrupt_vector_enable(MCF548X_IRQ_PSC(chan));
486        } /* of chan loop */
487
488
489} /* IntUartInitialise */
490
491/***************************************************************************
492   Function : IntUartInterruptWrite
493
494   Description : This writes a single character to the appropriate uart
495   channel. This is either called during an interrupt or in the user's task
496   to initiate a transmit sequence. Calling this routine enables Tx
497   interrupts.
498 ***************************************************************************/
499static ssize_t
500IntUartInterruptWrite (int minor, const char *buf, size_t len)
501{
502        if (len > 0) {
503                /* write out character */
504                *(volatile uint8_t *)(&MCF548X_PSC_TB(minor)) = *buf;
505
506                /* enable tx interrupt */
507                IntUartInfo[minor].imr |= MCF548X_PSC_IMR_TXRDY;
508                MCF548X_PSC_IMR(minor) = IntUartInfo[minor].imr;
509        }
510
511        return 0;
512}
513
514/***************************************************************************
515   Function : IntUartInterruptOpen
516
517   Description : This enables interrupts when the tty is opened.
518 ***************************************************************************/
519static int
520IntUartInterruptOpen(int major, int minor, void *arg)
521{
522        struct IntUartInfoStruct   *info = &IntUartInfo[minor];
523
524        /* enable the uart */
525        MCF548X_PSC_CR(minor) = (MCF548X_PSC_CR_TX_ENABLED | MCF548X_PSC_CR_RX_ENABLED);
526
527        /* check to see if interrupts need to be enabled */
528        if ( info->iomode != TERMIOS_POLLED )
529        {
530                /* enable rx interrupts */
531                info->imr |= MCF548X_PSC_IMR_RXRDY_FU;
532                MCF548X_PSC_IMR(minor) = info->imr;
533        }
534
535        /* check to see if doing hardware flow control */
536        if ( info->hwflow )
537        {
538                /* assert the RTS line */
539                MCF548X_PSC_OPSET(minor) = MCF548X_PSC_OPSET_RTS;
540        }
541
542        return 0;
543}
544
545
546/***************************************************************************
547   Function : IntUartInterruptClose
548
549   Description : This disables interrupts when the tty is closed.
550 ***************************************************************************/
551static int
552IntUartInterruptClose(int major, int minor, void *arg)
553{
554        struct IntUartInfoStruct   *info = &IntUartInfo[minor];
555
556        /* disable the interrupts and the uart */
557        MCF548X_PSC_IMR(minor) = 0;
558        MCF548X_PSC_CR(minor) = (MCF548X_PSC_CR_TX_ENABLED | MCF548X_PSC_CR_RX_ENABLED);
559
560        /* reset values */
561        info->ttyp     = NULL;
562        info->imr       = 0;
563        info->rx_in    = 0;
564        info->rx_out   = 0;
565
566        return 0;
567}
568
569/***************************************************************************
570   Function : IntUartTaskRead
571
572   Description : This reads all available characters from the internal uart
573   and places them into the termios buffer.  The rx interrupts will be
574   re-enabled after all data has been read.
575 ***************************************************************************/
576static int
577IntUartTaskRead(int minor)
578{
579        char                        buffer[RX_BUFFER_SIZE];
580        int                         count;
581        int                         rx_in;
582        int                         index = 0;
583        struct IntUartInfoStruct   *info  = &IntUartInfo[minor];
584
585        /* determine number of values to copy out */
586        rx_in = info->rx_in;
587        if ( info->rx_out <= rx_in )
588        {
589                count = rx_in - info->rx_out;
590        }
591        else
592        {
593                count = (RX_BUFFER_SIZE - info->rx_out) + rx_in;
594        }
595
596        /* copy data into local buffer from rx buffer */
597        while ( ( index < count ) && ( index < RX_BUFFER_SIZE ) )
598        {
599                /* copy data byte */
600                buffer[index] = info->rx_buffer[info->rx_out];
601                index++;
602
603                /* increment rx buffer values */
604                info->rx_out++;
605                if ( info->rx_out >= RX_BUFFER_SIZE )
606                {
607                        info->rx_out = 0;
608                }
609        }
610
611        /* check to see if buffer is not empty */
612        if ( count > 0 )
613        {
614                /* set characters into termios buffer  */
615                rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count);
616        }
617
618        return EOF;
619}
620
621
622/***************************************************************************
623   Function : IntUartPollRead
624
625   Description : This reads a character from the internal uart. It returns
626   to the caller without blocking if not character is waiting.
627 ***************************************************************************/
628static int
629IntUartPollRead (int minor)
630{
631if (!((MCF548X_PSC_SR(minor) & MCF548X_PSC_SR_RXRDY)))
632                return(-1);
633
634        return *((uint8_t *)&MCF548X_PSC_RB(minor));
635}
636
637
638/***************************************************************************
639   Function : IntUartPollWrite
640
641   Description : This writes out each character in the buffer to the
642   appropriate internal uart channel waiting till each one is sucessfully
643   transmitted.
644 ***************************************************************************/
645static ssize_t
646IntUartPollWrite (int minor, const char *buf, size_t len)
647{
648        size_t retval = len;
649/* loop over buffer */
650        while ( len-- )
651        {
652                /* block until we can transmit */
653                while (!((MCF548X_PSC_SR(minor) & MCF548X_PSC_SR_TXRDY)))
654                        continue;
655                /* transmit data byte */
656                *((uint8_t *)&MCF548X_PSC_TB(minor)) = *buf++;
657        }
658        return retval;
659}
660
661/***************************************************************************
662   Function : console_initialize
663
664   Description : This initialises termios, both sets of uart hardware before
665   registering /dev/tty devices for each channel and the system /dev/console.
666 ***************************************************************************/
667rtems_device_driver console_initialize(
668        rtems_device_major_number  major,
669        rtems_device_minor_number  minor,
670        void  *arg )
671{
672        rtems_status_code status;
673
674
675        /* Set up TERMIOS */
676        rtems_termios_initialize ();
677
678        /* set io modes for the different channels and initialize device */
679    IntUartInfo[minor].iomode = TERMIOS_IRQ_DRIVEN; //TERMIOS_POLLED;
680        IntUartInitialize();
681
682        /* Register the console port */
683        status = rtems_io_register_name ("/dev/console", major, CONSOLE_PORT);
684        if ( status != RTEMS_SUCCESSFUL )
685        {
686                rtems_fatal_error_occurred (status);
687        }
688
689        /* Register the other port */
690        if ( CONSOLE_PORT != 0 )
691        {
692                status = rtems_io_register_name ("/dev/tty00", major, 0);
693                if ( status != RTEMS_SUCCESSFUL )
694                {
695                        rtems_fatal_error_occurred (status);
696                }
697        }
698        if ( CONSOLE_PORT != 1 )
699        {
700                status = rtems_io_register_name ("/dev/tty01", major, 1);
701                if ( status != RTEMS_SUCCESSFUL )
702                {
703                        rtems_fatal_error_occurred (status);
704                }
705        }
706
707        return(RTEMS_SUCCESSFUL);
708}
709
710/***************************************************************************
711   Function : console_open
712
713   Description : This actually opens the device depending on the minor
714   number set during initialisation. The device specific access routines are
715   passed to termios when the devices is opened depending on whether it is
716   polled or not.
717 ***************************************************************************/
718rtems_device_driver console_open(
719        rtems_device_major_number major,
720        rtems_device_minor_number minor,
721        void  * arg)
722{
723    rtems_status_code                status = RTEMS_INVALID_NUMBER;
724        rtems_libio_open_close_args_t   *args   = (rtems_libio_open_close_args_t *)arg;
725        struct IntUartInfoStruct        *info;
726
727        static const rtems_termios_callbacks IntUartPollCallbacks = {
728                NULL,                             /* firstOpen */
729                NULL,                             /* lastClose */
730                IntUartPollRead,          /* pollRead */
731                IntUartPollWrite,         /* write */
732                IntUartSetAttributes, /* setAttributes */
733                NULL,                             /* stopRemoteTx */
734                NULL,                             /* startRemoteTx */
735                TERMIOS_POLLED            /* mode */
736        };
737        static const rtems_termios_callbacks IntUartIntrCallbacks = {
738                IntUartInterruptOpen,  /* firstOpen */
739                IntUartInterruptClose, /* lastClose */
740                NULL,                              /* pollRead */
741                IntUartInterruptWrite, /* write */
742                IntUartSetAttributes,  /* setAttributes */
743                NULL,                              /* stopRemoteTx */
744                NULL,                              /* startRemoteTx */
745                TERMIOS_IRQ_DRIVEN         /* mode */
746        };
747
748        static const rtems_termios_callbacks IntUartTaskCallbacks = {
749                IntUartInterruptOpen,  /* firstOpen */
750                IntUartInterruptClose, /* lastClose */
751                IntUartTaskRead,           /* pollRead */
752                IntUartInterruptWrite, /* write */
753                IntUartSetAttributes,  /* setAttributes */
754                NULL,                              /* stopRemoteTx */
755                NULL,                              /* startRemoteTx */
756                TERMIOS_TASK_DRIVEN        /* mode */
757        };
758
759        /* open the port depending on the minor device number */
760        if ( ( minor >= 0 ) && ( minor < MAX_UART_INFO ) )
761        {
762                info = &IntUartInfo[minor];
763                switch ( info->iomode )
764                {
765                        case TERMIOS_POLLED:
766                                status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks);
767                                break;
768                        case TERMIOS_IRQ_DRIVEN:
769                                status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks);
770                                info->ttyp = args->iop->data1;
771                                break;
772                        case TERMIOS_TASK_DRIVEN:
773                                status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks);
774                                info->ttyp = args->iop->data1;
775                                break;
776                }
777        }
778
779        return( status );
780}
781
782/***************************************************************************
783   Function : console_close
784
785   Description : This closes the device via termios
786 ***************************************************************************/
787rtems_device_driver console_close(
788        rtems_device_major_number major,
789        rtems_device_minor_number minor,
790        void   * arg)
791{
792    return(rtems_termios_close (arg));
793}
794
795/***************************************************************************
796   Function : console_read
797
798   Description : Read from the device via termios
799 ***************************************************************************/
800rtems_device_driver console_read(
801        rtems_device_major_number major,
802        rtems_device_minor_number minor,
803        void  * arg)
804{
805    return(rtems_termios_read (arg));
806}
807
808/***************************************************************************
809   Function : console_write
810
811   Description : Write to the device via termios
812 ***************************************************************************/
813rtems_device_driver console_write(
814        rtems_device_major_number major,
815        rtems_device_minor_number minor,
816        void  * arg)
817{
818    return(rtems_termios_write (arg));
819}
820
821/***************************************************************************
822   Function : console_ioctl
823
824   Description : Pass the IOCtl call to termios
825 ***************************************************************************/
826rtems_device_driver console_control(
827        rtems_device_major_number major,
828        rtems_device_minor_number minor,
829        void  * arg)
830{
831    return( rtems_termios_ioctl (arg) );
832}
Note: See TracBrowser for help on using the repository browser.