source: rtems/c/src/lib/libbsp/m68k/genmcf548x/console/console.c @ 6eb1733

4.115
Last change on this file since 6eb1733 was 6eb1733, checked in by Sebastian Huber <sebastian.huber@…>, on 12/06/13 at 07:37:11

bsp/genmcf548x: Use bsp_interrupt_vector_enable()

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