source: rtems/c/src/lib/libcpu/mips/mongoosev/duart/mg5uart.c @ 35f97010

4.104.114.84.95
Last change on this file since 35f97010 was 35f97010, checked in by Ralf Corsepius <ralf.corsepius@…>, on Mar 31, 2004 at 2:02:23 AM

2004-03-30 Ralf Corsepius <ralf_corsepius@…>

  • clock/ckinit.c, clock/clock.h, mongoosev/duart/mg5uart.c, mongoosev/duart/mg5uart.h, mongoosev/duart/mg5uart_reg.c, mongoosev/include/mongoose-v.h, mongoosev/vectorisrs/vectorisrs.c, shared/interrupts/vectorexceptions.c, timer/timer.c, tx39/include/tx3904.h: Convert to using c99 fixed size types.
  • Property mode set to 100644
File size: 18.8 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  int           baud,
64  unsigned int *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
443#define __ISR(_TYPE, _OFFSET) \
444  MG5UART_STATIC void mg5uart_process_isr_ ## _TYPE ( \
445    int  minor \
446  ); \
447  \
448  MG5UART_STATIC rtems_isr mg5uart_isr_ ## _TYPE ( \
449    rtems_vector_number vector \
450  ) \
451  { \
452    int   minor; \
453    extern void mips_default_isr(int vector); \
454   \
455    for(minor=0 ; minor<Console_Port_Count ; minor++) { \
456      if( Console_Port_Tbl[minor].deviceType == SERIAL_MG5UART && \
457          vector == Console_Port_Tbl[minor].ulIntVector + _OFFSET ) { \
458        mg5uart_process_isr_ ## _TYPE (minor); \
459        return; \
460      } \
461    } \
462    mips_default_isr( vector ); \
463  }
464
465__ISR(rx_frame_error, MG5UART_IRQ_RX_FRAME_ERROR)
466__ISR(rx_overrun_error, MG5UART_IRQ_RX_OVERRUN_ERROR)
467__ISR(tx_empty, MG5UART_IRQ_TX_EMPTY)
468__ISR(tx_ready, MG5UART_IRQ_TX_READY)
469__ISR(rx_ready, MG5UART_IRQ_RX_READY)
470
471
472
473
474
475MG5UART_STATIC void mg5uart_process_isr_rx_error(
476   int  minor, 
477   uint32_t   mask
478)
479{
480  uint32_t                pMG5UART;
481  int                     shift;
482
483  pMG5UART      = Console_Port_Tbl[minor].ulCtrlPort1;
484
485  if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )
486    shift = MONGOOSEV_UART0_IRQ_SHIFT;
487  else
488    shift = MONGOOSEV_UART1_IRQ_SHIFT;
489
490  /* now clear the error */
491
492  MG5UART_SETREG(
493     pMG5UART,
494     MG5UART_STATUS_REGISTER,
495     mask << shift );
496}
497
498
499MG5UART_STATIC void mg5uart_process_isr_rx_frame_error(
500  int  minor
501)
502{
503   mg5uart_process_isr_rx_error( minor, MONGOOSEV_UART_RX_FRAME_ERROR );
504}
505
506MG5UART_STATIC void mg5uart_process_isr_rx_overrun_error(
507  int  minor
508)
509{
510   mg5uart_process_isr_rx_error( minor, MONGOOSEV_UART_RX_OVERRUN_ERROR );
511}
512
513
514
515
516
517
518
519
520MG5UART_STATIC void mg5uart_process_tx_isr(
521   int        minor,
522   uint32_t   source
523)
524{
525   uint32_t        pMG5UART;
526   int             shift;
527   
528   pMG5UART      = Console_Port_Tbl[minor].ulCtrlPort1;
529
530   mg5uart_enable_interrupts(minor, MG5UART_ENABLE_ALL_EXCEPT_TX);
531
532   if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )
533      shift = MONGOOSEV_UART0_IRQ_SHIFT;
534   else
535      shift = MONGOOSEV_UART1_IRQ_SHIFT;
536     
537   MG5UART_SETREG(
538      pMG5UART,
539      MG5UART_STATUS_REGISTER,
540      source << shift );
541
542   if( rtems_termios_dequeue_characters( Console_Port_Data[minor].termios_data, 1) )
543   {
544      mg5uart_enable_interrupts(minor, MG5UART_ENABLE_ALL);
545      return;
546   }
547
548   /*
549    *  There are no more characters to transmit.  The tx interrupts are be cleared
550    *  by writing data to the uart, so just disable the tx interrupt sources.
551    */
552 
553   Console_Port_Data[minor].bActive = FALSE;
554
555   /* mg5uart_enable_interrupts(minor, MG5UART_ENABLE_ALL_EXCEPT_TX); */
556}
557
558
559
560MG5UART_STATIC void mg5uart_process_isr_tx_empty(
561  int  minor
562)
563{
564   /* mg5uart_process_tx_isr( minor, MONGOOSEV_UART_TX_EMPTY ); */
565}
566
567MG5UART_STATIC void mg5uart_process_isr_tx_ready(
568  int  minor
569)
570{
571   mg5uart_process_tx_isr( minor, MONGOOSEV_UART_TX_READY );
572}
573
574
575
576
577
578MG5UART_STATIC void mg5uart_process_isr_rx_ready(
579  int  minor
580)
581{
582  uint32_t                pMG5UART_port;
583  unsigned char           c;
584
585  pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2;
586
587  /* reading the RX buffer automatically resets the interrupt flag */
588
589  c = (unsigned char) MG5UART_GETREG(pMG5UART_port, MG5UART_RX_BUFFER);
590
591  rtems_termios_enqueue_raw_characters(
592     Console_Port_Data[minor].termios_data,
593     &c, 1 );
594}
595
596
597
598
599
600
601/*
602 *  mg5uart_initialize_interrupts
603 *
604 *  This routine initializes the console's receive and transmit
605 *  ring buffers and loads the appropriate vectors to handle the interrupts.
606 */
607
608MG5UART_STATIC void mg5uart_initialize_interrupts(int minor)
609{
610  unsigned long v;
611  mg5uart_init(minor);
612
613  Console_Port_Data[minor].bActive = FALSE;
614  v = Console_Port_Tbl[minor].ulIntVector;
615
616  set_vector(mg5uart_isr_rx_frame_error,   v + MG5UART_IRQ_RX_FRAME_ERROR, 1);
617  set_vector(mg5uart_isr_rx_overrun_error, v + MG5UART_IRQ_RX_OVERRUN_ERROR, 1);
618  set_vector(mg5uart_isr_tx_empty,         v + MG5UART_IRQ_TX_EMPTY, 1);
619  set_vector(mg5uart_isr_tx_ready,         v + MG5UART_IRQ_TX_READY, 1);
620  set_vector(mg5uart_isr_rx_ready,         v + MG5UART_IRQ_RX_READY, 1);
621
622  mg5uart_enable_interrupts(minor, MG5UART_ENABLE_ALL_EXCEPT_TX);
623}
624
625
626
627
628
629/*
630 *  mg5uart_write_support_int
631 *
632 *  Console Termios output entry point when using interrupt driven output.
633 */
634
635MG5UART_STATIC int mg5uart_write_support_int(
636  int         minor,
637  const char *buf,
638  int         len
639)
640{
641  uint32_t        Irql;
642  uint32_t        pMG5UART_port;
643
644  pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2;
645
646  /*
647   *  We are using interrupt driven output and termios only sends us
648   *  one character at a time.
649   */
650
651  if ( !len )
652     return 0;
653
654  /*
655   *  Put the character out and enable interrupts if necessary.
656   */
657
658  rtems_interrupt_disable(Irql);
659
660  MG5UART_SETREG(pMG5UART_port, MG5UART_TX_BUFFER, *buf);
661
662  if( Console_Port_Data[minor].bActive == FALSE ) 
663  {
664     Console_Port_Data[minor].bActive = TRUE;
665     mg5uart_enable_interrupts(minor, MG5UART_ENABLE_ALL);
666  }
667
668  rtems_interrupt_enable(Irql);
669  return 1;
670}
671
672
673
674
675/*
676 *  mg5uart_write_support_polled
677 *
678 *  Console Termios output entry point when using polled output.
679 *
680 */
681
682MG5UART_STATIC int mg5uart_write_support_polled(
683  int         minor,
684  const char *buf,
685  int         len
686)
687{
688  int nwrite = 0;
689
690  /*
691   * poll each byte in the string out of the port.
692   */
693  while (nwrite < len) 
694  {
695    mg5uart_write_polled(minor, *buf++);
696    nwrite++;
697  }
698
699  /*
700   * return the number of bytes written.
701   */
702  return nwrite;
703}
704
705/*
706 *  mg5uart_inbyte_nonblocking_polled
707 *
708 *  Console Termios polling input entry point.
709 */
710
711MG5UART_STATIC int mg5uart_inbyte_nonblocking_polled(
712  int minor
713)
714{
715  uint32_t                pMG5UART;
716  uint32_t                pMG5UART_port;
717  uint32_t                status;
718  uint32_t                tmp,shift;
719
720  pMG5UART      = Console_Port_Tbl[minor].ulCtrlPort1;
721  pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2;
722
723  if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )
724    shift = MONGOOSEV_UART0_IRQ_SHIFT;
725  else
726    shift = MONGOOSEV_UART1_IRQ_SHIFT;
727
728  /* reset overrrun or framing errors */
729  status = MG5UART_GETREG(pMG5UART, MG5UART_STATUS_REGISTER) >> shift;
730
731  if( (tmp = (status & 0x3)) )
732  {
733     MG5UART_SETREG(pMG5UART, MG5UART_STATUS_REGISTER, (tmp << shift) );
734     status = MG5UART_GETREG(pMG5UART, MG5UART_STATUS_REGISTER) >> shift;
735  }
736
737  if ( status & MONGOOSEV_UART_RX_READY ) 
738  {
739     return (int) MG5UART_GETREG(pMG5UART_port, MG5UART_RX_BUFFER);
740  } 
741  else 
742  {
743     return -1;
744  }
745}
746
747/*
748 *  mg5uart_baud_rate
749 */
750
751MG5UART_STATIC int mg5uart_baud_rate(
752  int           minor,
753  int           baud,
754  unsigned int *code
755)
756{
757  uint32_t   clock;
758  uint32_t   tmp_code;
759  uint32_t   baud_requested;
760
761  baud_requested = baud & CBAUD;
762  if (!baud_requested)
763    baud_requested = B9600;              /* default to 9600 baud */
764
765  baud_requested = termios_baud_to_number( baud_requested );
766
767  clock = (uint32_t  ) Console_Port_Tbl[minor].ulClock;
768  if (!clock)
769    rtems_fatal_error_occurred(RTEMS_INVALID_NUMBER);
770
771  /*
772   *  Formula is Code = round(ClockFrequency / Baud - 1).
773   *
774   *  Since this is integer math, we will divide by twice the baud and
775   *  check the remaining odd bit.
776   */
777
778  tmp_code = (clock / baud_requested) - 1;
779
780  /*
781   *  From section 12.7, "Keep C>100 for best receiver operation."
782   *  That is 100 cycles which is not a lot of instructions.  It is
783   *  reasonable to think that the Mongoose-V could not keep
784   *  up with C < 100.
785   */
786
787  if ( tmp_code < 100 )
788    return RTEMS_INVALID_NUMBER;
789
790  /*
791   *  upper word is receiver baud and lower word is transmitter baud
792   */
793
794  *code = (tmp_code << 16) | tmp_code;
795
796  return 0;
797}
798
799
800
801
802/*
803 *  mg5uart_enable_interrupts
804 *
805 *  This function enables specific interrupt sources on the DUART.
806 */
807
808MG5UART_STATIC void mg5uart_enable_interrupts(
809  int minor,
810  int mask
811)
812{
813  uint32_t              pMG5UART;
814  uint32_t              maskSave;
815  uint32_t              shift;
816  rtems_interrupt_level  Irql;
817
818  pMG5UART = Console_Port_Tbl[minor].ulCtrlPort1;
819
820  /*
821   *  Enable interrupts on RX and TX -- not break
822   */
823
824  if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )
825    shift = MONGOOSEV_UART0_IRQ_SHIFT;
826  else
827    shift = MONGOOSEV_UART1_IRQ_SHIFT;
828
829
830  rtems_interrupt_disable(Irql);
831
832  maskSave = MG5UART_GETREG( pMG5UART, MG5UART_INTERRUPT_MASK_REGISTER );
833
834  MG5UART_SETREG(
835     pMG5UART,
836     MG5UART_INTERRUPT_MASK_REGISTER,
837     (maskSave & ~(MONGOOSEV_UART_ALL_STATUS_BITS << shift)) | (mask << shift) );
838
839  rtems_interrupt_enable(Irql);
840}
841
842
843
844/*
845 * Flow control is only supported when using interrupts
846 */
847
848console_fns mg5uart_fns =
849{
850  libchip_serial_default_probe,   /* deviceProbe */
851  mg5uart_open,                   /* deviceFirstOpen */
852  NULL,                           /* deviceLastClose */
853  NULL,                           /* deviceRead */
854  mg5uart_write_support_int,      /* deviceWrite */
855  mg5uart_initialize_interrupts,  /* deviceInitialize */
856  mg5uart_write_polled,           /* deviceWritePolled */
857  mg5uart_set_attributes,         /* deviceSetAttributes */
858  TRUE                            /* deviceOutputUsesInterrupts */
859};
860
861console_fns mg5uart_fns_polled =
862{
863  libchip_serial_default_probe,        /* deviceProbe */
864  mg5uart_open,                        /* deviceFirstOpen */
865  mg5uart_close,                       /* deviceLastClose */
866  mg5uart_inbyte_nonblocking_polled,   /* deviceRead */
867  mg5uart_write_support_polled,        /* deviceWrite */
868  mg5uart_init,                        /* deviceInitialize */
869  mg5uart_write_polled,                /* deviceWritePolled */
870  mg5uart_set_attributes,              /* deviceSetAttributes */
871  FALSE,                               /* deviceOutputUsesInterrupts */
872};
873
874
Note: See TracBrowser for help on using the repository browser.