source: rtems/bsps/m68k/genmcf548x/console/console.c @ 947c6645

Last change on this file since 947c6645 was 947c6645, checked in by Christian Mauderer <christian.mauderer@…>, on 03/07/22 at 13:06:23

bsps/m68k: Restore license file

Quite some files in the bsps/m68k/genmcf548x mention a
Freescale_license.txt file. The file has been accidentally removed
during the source reorganization in 2018. This commit restores it and
moves it to the right location for licenses.

Update #4625.

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