source: rtems/c/src/lib/libcpu/mips/mongoosev/duart/mg5uart.c @ 25eab8f

4.115
Last change on this file since 25eab8f was 25eab8f, checked in by Ralf Corsepius <ralf.corsepius@…>, on Jan 30, 2011 at 5:42:26 PM

2011-01-30 Ralf Corsépius <ralf.corsepius@…>

  • mongoosev/duart/mg5uart.c: Fix type mismatch.
  • Property mode set to 100644
File size: 18.7 KB
Line 
1/*
2 *  This file contains the termios TTY driver for the UART found
3 *  on the Synova Mongoose-V.
4 *
5 *  COPYRIGHT (c) 1989-2001.
6 *  On-Line Applications Research Corporation (OAR).
7 *
8 *  The license and distribution terms for this file may be
9 *  found in the file LICENSE in this distribution or at
10 *  http://www.rtems.com/license/LICENSE.
11 *
12 *  $Id$
13 */
14
15#include <rtems.h>
16#include <rtems/libio.h>
17#include <stdlib.h>
18
19#include <libchip/serial.h>
20#include <libchip/mg5uart.h>
21#include <libchip/sersupp.h>
22#include <libcpu/mongoose-v.h>
23
24extern void set_vector( rtems_isr_entry, rtems_vector_number, int );
25
26/*
27 *  Indices of registers
28 */
29
30/*
31 *  Per chip context control
32 */
33
34typedef struct _mg5uart_context
35{
36  int            mate;
37} mg5uart_context;
38
39/*
40 *  Define MG5UART_STATIC to nothing while debugging so the entry points
41 *  will show up in the symbol table.
42 */
43
44#define MG5UART_STATIC
45
46/* #define MG5UART_STATIC static */
47
48
49
50#define MG5UART_SETREG( _base, _register, _value ) \
51        MONGOOSEV_WRITE_REGISTER( _base, _register, _value )
52
53#define MG5UART_GETREG( _base, _register ) \
54        MONGOOSEV_READ_REGISTER( _base, _register )
55
56
57/*
58 *  Console Device Driver Support Functions
59 */
60
61MG5UART_STATIC int mg5uart_baud_rate(
62  int        minor,
63  uint32_t   baud,
64  uint32_t  *code
65);
66
67MG5UART_STATIC void mg5uart_enable_interrupts(
68  int minor,
69  int mask
70);
71
72/*
73 *  mg5uart_set_attributes
74 *
75 *  This function sets the UART channel to reflect the requested termios
76 *  port settings.
77 */
78
79MG5UART_STATIC int mg5uart_set_attributes(
80  int minor,
81  const struct termios *t
82)
83{
84  uint32_t               pMG5UART_port;
85  uint32_t               pMG5UART;
86  uint32_t               cmd, cmdSave;
87  uint32_t               baudcmd;
88  uint32_t               shift;
89  rtems_interrupt_level  Irql;
90
91  pMG5UART      = Console_Port_Tbl[minor].ulCtrlPort1;
92  pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2;
93
94  /*
95   *  Set the baud rate
96   */
97
98  if (mg5uart_baud_rate( minor, t->c_cflag, &baudcmd ) == -1)
99    return -1;
100
101  /*
102   *  Base settings
103   */
104
105  /*
106   *  Base settings
107   */
108
109  cmd = MONGOOSEV_UART_CMD_RX_ENABLE | MONGOOSEV_UART_CMD_TX_ENABLE;
110
111  /*
112   *  Parity
113   */
114
115  if (t->c_cflag & PARENB) {
116    cmd |= MONGOOSEV_UART_CMD_PARITY_ENABLE;
117    if (t->c_cflag & PARODD)
118      cmd |= MONGOOSEV_UART_CMD_PARITY_ODD;
119    else
120      cmd |= MONGOOSEV_UART_CMD_PARITY_EVEN;
121  } else {
122    cmd |= MONGOOSEV_UART_CMD_PARITY_DISABLE;
123  }
124
125  /*
126   *  Character Size
127   */
128
129  if (t->c_cflag & CSIZE) {
130    switch (t->c_cflag & CSIZE) {
131      case CS5:
132      case CS6:
133      case CS7:
134        return -1;
135        break;
136      case CS8:
137        /* Mongoose-V only supports CS8 */
138        break;
139
140    }
141  } /* else default to CS8 */
142
143  /*
144   *  Stop Bits
145   */
146
147#if 0
148  if (t->c_cflag & CSTOPB) {
149    /* 2 stop bits not supported by Mongoose-V uart */
150    return -1;
151  }
152#endif
153
154  /*
155   *  XXX what about CTS/RTS
156   */
157
158  /* XXX */
159
160  /*
161   *  Now write the registers
162   */
163
164  if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )
165    shift = MONGOOSEV_UART0_CMD_SHIFT;
166  else
167    shift = MONGOOSEV_UART1_CMD_SHIFT;
168
169
170
171  rtems_interrupt_disable(Irql);
172
173  cmdSave = MG5UART_GETREG( pMG5UART, MG5UART_COMMAND_REGISTER );
174
175  MG5UART_SETREG( pMG5UART,
176                  MG5UART_COMMAND_REGISTER,
177                  (cmdSave & ~(MONGOOSEV_UART_ALL_STATUS_BITS << shift)) | (cmd << shift) );
178
179  MG5UART_SETREG( pMG5UART_port, MG5UART_BAUD_RATE, baudcmd );
180
181  rtems_interrupt_enable(Irql);
182  return 0;
183}
184
185/*
186 *  mg5uart_initialize_context
187 *
188 *  This function sets the default values of the per port context structure.
189 */
190
191MG5UART_STATIC void mg5uart_initialize_context(
192  int               minor,
193  mg5uart_context  *pmg5uartContext
194)
195{
196  int          port;
197  unsigned int pMG5UART;
198  unsigned int pMG5UART_port;
199
200  pMG5UART      = Console_Port_Tbl[minor].ulCtrlPort1;
201  pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2;
202
203  pmg5uartContext->mate = -1;
204
205  for (port=0 ; port<Console_Port_Count ; port++ ) {
206    if ( Console_Port_Tbl[port].ulCtrlPort1 == pMG5UART &&
207         Console_Port_Tbl[port].ulCtrlPort2 != pMG5UART_port ) {
208      pmg5uartContext->mate = port;
209      break;
210    }
211  }
212
213}
214
215/*
216 *  mg5uart_init
217 *
218 *  This function initializes the DUART to a quiecsent state.
219 */
220
221MG5UART_STATIC void mg5uart_init(int minor)
222{
223  uint32_t              pMG5UART_port;
224  uint32_t              pMG5UART;
225  uint32_t              cmdSave;
226  uint32_t              shift;
227
228  mg5uart_context        *pmg5uartContext;
229
230  pmg5uartContext = (mg5uart_context *) malloc(sizeof(mg5uart_context));
231
232  Console_Port_Data[minor].pDeviceContext = (void *)pmg5uartContext;
233
234  mg5uart_initialize_context( minor, pmg5uartContext );
235
236  pMG5UART      = Console_Port_Tbl[minor].ulCtrlPort1;
237  pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2;
238
239  if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )
240     shift = MONGOOSEV_UART0_CMD_SHIFT;
241  else
242     shift = MONGOOSEV_UART1_CMD_SHIFT;
243
244  /*
245   *  Disable the uart and leave this port disabled.
246   */
247
248  cmdSave = MG5UART_GETREG(pMG5UART, MG5UART_COMMAND_REGISTER) & ~(MONGOOSEV_UART_ALL_STATUS_BITS << shift);
249
250  MG5UART_SETREG( pMG5UART, MG5UART_COMMAND_REGISTER, cmdSave );
251
252  /*
253   *  Disable interrupts on RX and TX for this port
254   */
255  mg5uart_enable_interrupts( minor, MG5UART_DISABLE_ALL );
256}
257
258/*
259 *  mg5uart_open
260 *
261 *  This function opens a port for communication.
262 *
263 *  Default state is 9600 baud, 8 bits, No parity, and 1 stop bit.
264 */
265
266MG5UART_STATIC int mg5uart_open(
267  int      major,
268  int      minor,
269  void    *arg
270)
271{
272  uint32_t      pMG5UART;
273  uint32_t      pMG5UART_port;
274  uint32_t      vector;
275  uint32_t      cmd, cmdSave;
276  uint32_t      baudcmd;
277  uint32_t      shift;
278
279  rtems_interrupt_level  Irql;
280
281  pMG5UART      = Console_Port_Tbl[minor].ulCtrlPort1;
282  pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2;
283  vector        = Console_Port_Tbl[minor].ulIntVector;
284
285  if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )
286    shift = MONGOOSEV_UART0_CMD_SHIFT;
287  else
288    shift = MONGOOSEV_UART1_CMD_SHIFT;
289
290
291  /* XXX default baud rate could be from configuration table */
292
293  (void) mg5uart_baud_rate( minor, B19200, &baudcmd );
294
295  /*
296   *  Set the DUART channel to a default useable state
297   *  B19200, 8Nx since there is no stop bit control.
298   */
299
300  cmd = MONGOOSEV_UART_CMD_TX_ENABLE | MONGOOSEV_UART_CMD_RX_ENABLE;
301
302  rtems_interrupt_disable(Irql);
303
304  cmdSave = MG5UART_GETREG( pMG5UART, MG5UART_COMMAND_REGISTER );
305
306  MG5UART_SETREG( pMG5UART_port, MG5UART_BAUD_RATE, baudcmd );
307
308  MG5UART_SETREG( pMG5UART,
309                  MG5UART_COMMAND_REGISTER,
310                  cmd = (cmdSave & ~(MONGOOSEV_UART_ALL_STATUS_BITS << shift)) | (cmd << shift) );
311
312  rtems_interrupt_enable(Irql);
313
314  return RTEMS_SUCCESSFUL;
315}
316
317/*
318 *  mg5uart_close
319 *
320 *  This function shuts down the requested port.
321 */
322
323MG5UART_STATIC int mg5uart_close(
324  int      major,
325  int      minor,
326  void    *arg
327)
328{
329  uint32_t      pMG5UART;
330  uint32_t      pMG5UART_port;
331  uint32_t      cmd, cmdSave;
332  uint32_t      shift;
333  rtems_interrupt_level  Irql;
334
335  pMG5UART      = Console_Port_Tbl[minor].ulCtrlPort1;
336  pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2;
337
338  /*
339   *  Disable interrupts from this channel and then disable it totally.
340   */
341
342  /* XXX interrupts */
343
344  cmd = MONGOOSEV_UART_CMD_TX_DISABLE | MONGOOSEV_UART_CMD_RX_DISABLE;
345
346  if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )
347    shift = MONGOOSEV_UART0_CMD_SHIFT;
348  else
349    shift = MONGOOSEV_UART1_CMD_SHIFT;
350
351
352  rtems_interrupt_disable(Irql);
353  cmdSave = MG5UART_GETREG( pMG5UART, MG5UART_COMMAND_REGISTER );
354
355  MG5UART_SETREG( pMG5UART,
356                  MG5UART_COMMAND_REGISTER,
357                  (cmdSave & ~(MONGOOSEV_UART_ALL_STATUS_BITS << shift)) | (cmd << shift) );
358  rtems_interrupt_enable(Irql);
359
360  return(RTEMS_SUCCESSFUL);
361}
362
363
364
365
366/*
367 *  mg5uart_write_polled
368 *
369 *  This routine polls out the requested character.
370 */
371
372MG5UART_STATIC void mg5uart_write_polled(
373  int   minor,
374  char  c
375)
376{
377  uint32_t                pMG5UART;
378  uint32_t                pMG5UART_port;
379  uint32_t                status;
380  int                     shift;
381  int                     timeout;
382
383  pMG5UART      = Console_Port_Tbl[minor].ulCtrlPort1;
384  pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2;
385
386  if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )
387    shift = MONGOOSEV_UART0_IRQ_SHIFT;
388  else
389    shift = MONGOOSEV_UART1_IRQ_SHIFT;
390
391  /*
392   * wait for transmitter holding register to be empty
393   */
394  timeout = 2000;
395
396  while( --timeout )
397  {
398    status = MG5UART_GETREG(pMG5UART, MG5UART_STATUS_REGISTER) >> shift;
399
400    /*
401    if ( (status & (MONGOOSEV_UART_TX_READY | MONGOOSEV_UART_TX_EMPTY)) ==
402            (MONGOOSEV_UART_TX_READY | MONGOOSEV_UART_TX_EMPTY) )
403      break;
404    */
405
406    if( (status & (MONGOOSEV_UART_TX_READY | MONGOOSEV_UART_TX_EMPTY)) )
407       break;
408
409    /*
410     * Yield while we wait
411     */
412
413#if 0
414     if(_System_state_Is_up(_System_state_Get()))
415     {
416       rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
417     }
418#endif
419  }
420
421  /*
422   * transmit character
423   */
424
425  MG5UART_SETREG(pMG5UART_port, MG5UART_TX_BUFFER, c);
426}
427
428
429
430
431/*
432 *  mg5uart_isr_XXX
433 *
434 *  This is the single interrupt entry point which parcels interrupts
435 *  out to the handlers for specific sources and makes sure that the
436 *  shared handler gets the right arguments.
437 *
438 *  NOTE: Yes .. this is ugly but it provides 5 interrupt source
439 *  wrappers which are nearly functionally identical.
440 */
441
442
443extern void mips_default_isr(int vector);
444
445#define __ISR(_TYPE, _OFFSET) \
446  MG5UART_STATIC void mg5uart_process_isr_ ## _TYPE ( \
447    int  minor \
448  ); \
449  \
450  MG5UART_STATIC rtems_isr mg5uart_isr_ ## _TYPE ( \
451    rtems_vector_number vector \
452  ) \
453  { \
454    int   minor; \
455    \
456    for(minor=0 ; minor<Console_Port_Count ; minor++) { \
457      if( Console_Port_Tbl[minor].deviceType == SERIAL_MG5UART && \
458          vector == Console_Port_Tbl[minor].ulIntVector + _OFFSET ) { \
459        mg5uart_process_isr_ ## _TYPE (minor); \
460        return; \
461      } \
462    } \
463    mips_default_isr( vector ); \
464  }
465
466__ISR(rx_frame_error, MG5UART_IRQ_RX_FRAME_ERROR)
467__ISR(rx_overrun_error, MG5UART_IRQ_RX_OVERRUN_ERROR)
468__ISR(tx_empty, MG5UART_IRQ_TX_EMPTY)
469__ISR(tx_ready, MG5UART_IRQ_TX_READY)
470__ISR(rx_ready, MG5UART_IRQ_RX_READY)
471
472
473MG5UART_STATIC void mg5uart_process_isr_rx_error(
474   int  minor,
475   uint32_t   mask
476)
477{
478  uint32_t                pMG5UART;
479  int                     shift;
480
481  pMG5UART      = Console_Port_Tbl[minor].ulCtrlPort1;
482
483  if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )
484    shift = MONGOOSEV_UART0_IRQ_SHIFT;
485  else
486    shift = MONGOOSEV_UART1_IRQ_SHIFT;
487
488  /* now clear the error */
489
490  MG5UART_SETREG(
491     pMG5UART,
492     MG5UART_STATUS_REGISTER,
493     mask << shift );
494}
495
496
497MG5UART_STATIC void mg5uart_process_isr_rx_frame_error(
498  int  minor
499)
500{
501   mg5uart_process_isr_rx_error( minor, MONGOOSEV_UART_RX_FRAME_ERROR );
502}
503
504MG5UART_STATIC void mg5uart_process_isr_rx_overrun_error(
505  int  minor
506)
507{
508   mg5uart_process_isr_rx_error( minor, MONGOOSEV_UART_RX_OVERRUN_ERROR );
509}
510
511
512
513
514
515
516
517
518MG5UART_STATIC void mg5uart_process_tx_isr(
519   int        minor,
520   uint32_t   source
521)
522{
523   uint32_t        pMG5UART;
524   int             shift;
525
526   pMG5UART      = Console_Port_Tbl[minor].ulCtrlPort1;
527
528   mg5uart_enable_interrupts(minor, MG5UART_ENABLE_ALL_EXCEPT_TX);
529
530   if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )
531      shift = MONGOOSEV_UART0_IRQ_SHIFT;
532   else
533      shift = MONGOOSEV_UART1_IRQ_SHIFT;
534
535   MG5UART_SETREG(
536      pMG5UART,
537      MG5UART_STATUS_REGISTER,
538      source << shift );
539
540   if( rtems_termios_dequeue_characters( Console_Port_Data[minor].termios_data, 1) )
541   {
542      mg5uart_enable_interrupts(minor, MG5UART_ENABLE_ALL);
543      return;
544   }
545
546   /*
547    *  There are no more characters to transmit.  The tx interrupts are be cleared
548    *  by writing data to the uart, so just disable the tx interrupt sources.
549    */
550
551   Console_Port_Data[minor].bActive = FALSE;
552
553   /* mg5uart_enable_interrupts(minor, MG5UART_ENABLE_ALL_EXCEPT_TX); */
554}
555
556
557
558MG5UART_STATIC void mg5uart_process_isr_tx_empty(
559  int  minor
560)
561{
562   /* mg5uart_process_tx_isr( minor, MONGOOSEV_UART_TX_EMPTY ); */
563}
564
565MG5UART_STATIC void mg5uart_process_isr_tx_ready(
566  int  minor
567)
568{
569   mg5uart_process_tx_isr( minor, MONGOOSEV_UART_TX_READY );
570}
571
572
573
574
575
576MG5UART_STATIC void mg5uart_process_isr_rx_ready(
577  int  minor
578)
579{
580  uint32_t   pMG5UART_port;
581  char       c;
582
583  pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2;
584
585  /* reading the RX buffer automatically resets the interrupt flag */
586
587  c = (char) MG5UART_GETREG(pMG5UART_port, MG5UART_RX_BUFFER);
588
589  rtems_termios_enqueue_raw_characters(
590     Console_Port_Data[minor].termios_data,
591     &c, 1 );
592}
593
594
595
596
597
598
599/*
600 *  mg5uart_initialize_interrupts
601 *
602 *  This routine initializes the console's receive and transmit
603 *  ring buffers and loads the appropriate vectors to handle the interrupts.
604 */
605
606MG5UART_STATIC void mg5uart_initialize_interrupts(int minor)
607{
608  unsigned long v;
609  mg5uart_init(minor);
610
611  Console_Port_Data[minor].bActive = FALSE;
612  v = Console_Port_Tbl[minor].ulIntVector;
613
614  set_vector(mg5uart_isr_rx_frame_error,   v + MG5UART_IRQ_RX_FRAME_ERROR, 1);
615  set_vector(mg5uart_isr_rx_overrun_error, v + MG5UART_IRQ_RX_OVERRUN_ERROR, 1);
616  set_vector(mg5uart_isr_tx_empty,         v + MG5UART_IRQ_TX_EMPTY, 1);
617  set_vector(mg5uart_isr_tx_ready,         v + MG5UART_IRQ_TX_READY, 1);
618  set_vector(mg5uart_isr_rx_ready,         v + MG5UART_IRQ_RX_READY, 1);
619
620  mg5uart_enable_interrupts(minor, MG5UART_ENABLE_ALL_EXCEPT_TX);
621}
622
623
624
625
626
627/*
628 *  mg5uart_write_support_int
629 *
630 *  Console Termios output entry point when using interrupt driven output.
631 */
632
633MG5UART_STATIC int mg5uart_write_support_int(
634  int         minor,
635  const char *buf,
636  size_t      len
637)
638{
639  uint32_t        Irql;
640  uint32_t        pMG5UART_port;
641
642  pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2;
643
644  /*
645   *  We are using interrupt driven output and termios only sends us
646   *  one character at a time.
647   */
648
649  if ( !len )
650     return 0;
651
652  /*
653   *  Put the character out and enable interrupts if necessary.
654   */
655
656  rtems_interrupt_disable(Irql);
657
658  MG5UART_SETREG(pMG5UART_port, MG5UART_TX_BUFFER, *buf);
659
660  if( Console_Port_Data[minor].bActive == FALSE )
661  {
662     Console_Port_Data[minor].bActive = TRUE;
663     mg5uart_enable_interrupts(minor, MG5UART_ENABLE_ALL);
664  }
665
666  rtems_interrupt_enable(Irql);
667  return 1;
668}
669
670
671
672
673/*
674 *  mg5uart_write_support_polled
675 *
676 *  Console Termios output entry point when using polled output.
677 *
678 */
679
680MG5UART_STATIC ssize_t mg5uart_write_support_polled(
681  int         minor,
682  const char *buf,
683  size_t      len
684)
685{
686  int nwrite = 0;
687
688  /*
689   * poll each byte in the string out of the port.
690   */
691  while (nwrite < len)
692  {
693    mg5uart_write_polled(minor, *buf++);
694    nwrite++;
695  }
696
697  /*
698   * return the number of bytes written.
699   */
700  return nwrite;
701}
702
703/*
704 *  mg5uart_inbyte_nonblocking_polled
705 *
706 *  Console Termios polling input entry point.
707 */
708
709MG5UART_STATIC int mg5uart_inbyte_nonblocking_polled(
710  int minor
711)
712{
713  uint32_t                pMG5UART;
714  uint32_t                pMG5UART_port;
715  uint32_t                status;
716  uint32_t                tmp,shift;
717
718  pMG5UART      = Console_Port_Tbl[minor].ulCtrlPort1;
719  pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2;
720
721  if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )
722    shift = MONGOOSEV_UART0_IRQ_SHIFT;
723  else
724    shift = MONGOOSEV_UART1_IRQ_SHIFT;
725
726  /* reset overrrun or framing errors */
727  status = MG5UART_GETREG(pMG5UART, MG5UART_STATUS_REGISTER) >> shift;
728
729  if( (tmp = (status & 0x3)) )
730  {
731     MG5UART_SETREG(pMG5UART, MG5UART_STATUS_REGISTER, (tmp << shift) );
732     status = MG5UART_GETREG(pMG5UART, MG5UART_STATUS_REGISTER) >> shift;
733  }
734
735  if ( status & MONGOOSEV_UART_RX_READY )
736  {
737     return (int) MG5UART_GETREG(pMG5UART_port, MG5UART_RX_BUFFER);
738  }
739  else
740  {
741     return -1;
742  }
743}
744
745/*
746 *  mg5uart_baud_rate
747 */
748
749MG5UART_STATIC int mg5uart_baud_rate(
750  int           minor,
751  uint32_t      baud,
752  uint32_t     *code
753)
754{
755  uint32_t   clock;
756  uint32_t   tmp_code;
757  uint32_t   baud_requested;
758
759  baud_requested = baud & CBAUD;
760  if (!baud_requested)
761    baud_requested = B9600;              /* default to 9600 baud */
762
763  baud_requested = rtems_termios_baud_to_number( baud_requested );
764
765  clock = (uint32_t) Console_Port_Tbl[minor].ulClock;
766  if (!clock)
767    rtems_fatal_error_occurred(RTEMS_INVALID_NUMBER);
768
769  /*
770   *  Formula is Code = round(ClockFrequency / Baud - 1).
771   *
772   *  Since this is integer math, we will divide by twice the baud and
773   *  check the remaining odd bit.
774   */
775
776  tmp_code = (clock / baud_requested) - 1;
777
778  /*
779   *  From section 12.7, "Keep C>100 for best receiver operation."
780   *  That is 100 cycles which is not a lot of instructions.  It is
781   *  reasonable to think that the Mongoose-V could not keep
782   *  up with C < 100.
783   */
784
785  if ( tmp_code < 100 )
786    return RTEMS_INVALID_NUMBER;
787
788  /*
789   *  upper word is receiver baud and lower word is transmitter baud
790   */
791
792  *code = (tmp_code << 16) | tmp_code;
793
794  return 0;
795}
796
797
798
799
800/*
801 *  mg5uart_enable_interrupts
802 *
803 *  This function enables specific interrupt sources on the DUART.
804 */
805
806MG5UART_STATIC void mg5uart_enable_interrupts(
807  int minor,
808  int mask
809)
810{
811  uint32_t              pMG5UART;
812  uint32_t              maskSave;
813  uint32_t              shift;
814  rtems_interrupt_level  Irql;
815
816  pMG5UART = Console_Port_Tbl[minor].ulCtrlPort1;
817
818  /*
819   *  Enable interrupts on RX and TX -- not break
820   */
821
822  if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )
823    shift = MONGOOSEV_UART0_IRQ_SHIFT;
824  else
825    shift = MONGOOSEV_UART1_IRQ_SHIFT;
826
827
828  rtems_interrupt_disable(Irql);
829
830  maskSave = MG5UART_GETREG( pMG5UART, MG5UART_INTERRUPT_MASK_REGISTER );
831
832  MG5UART_SETREG(
833     pMG5UART,
834     MG5UART_INTERRUPT_MASK_REGISTER,
835     (maskSave & ~(MONGOOSEV_UART_ALL_STATUS_BITS << shift)) | (mask << shift) );
836
837  rtems_interrupt_enable(Irql);
838}
839
840
841
842/*
843 * Flow control is only supported when using interrupts
844 */
845
846console_fns mg5uart_fns =
847{
848  libchip_serial_default_probe,   /* deviceProbe */
849  mg5uart_open,                   /* deviceFirstOpen */
850  NULL,                           /* deviceLastClose */
851  NULL,                           /* deviceRead */
852  mg5uart_write_support_int,      /* deviceWrite */
853  mg5uart_initialize_interrupts,  /* deviceInitialize */
854  mg5uart_write_polled,           /* deviceWritePolled */
855  mg5uart_set_attributes,         /* deviceSetAttributes */
856  TRUE                            /* deviceOutputUsesInterrupts */
857};
858
859console_fns mg5uart_fns_polled =
860{
861  libchip_serial_default_probe,        /* deviceProbe */
862  mg5uart_open,                        /* deviceFirstOpen */
863  mg5uart_close,                       /* deviceLastClose */
864  mg5uart_inbyte_nonblocking_polled,   /* deviceRead */
865  mg5uart_write_support_polled,        /* deviceWrite */
866  mg5uart_init,                        /* deviceInitialize */
867  mg5uart_write_polled,                /* deviceWritePolled */
868  mg5uart_set_attributes,              /* deviceSetAttributes */
869  FALSE,                               /* deviceOutputUsesInterrupts */
870};
Note: See TracBrowser for help on using the repository browser.