OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [c/] [src/] [lib/] [libbsp/] [i386/] [shared/] [comm/] [uart.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1026 ivang
/*
2
 * This software is Copyright (C) 1998 by T.sqware - all rights limited
3
 * It is provided in to the public domain "as is", can be freely modified
4
 * as far as this copyight notice is kept unchanged, but does not imply
5
 * an endorsement by T.sqware of the product in which it is included.
6
 *
7
 *  uart.c,v 1.11 2002/07/16 22:30:11 joel Exp
8
 */
9
 
10
#include <stdio.h>
11
#include <bsp.h>
12
#include <irq.h>
13
#include <uart.h>
14
#include <rtems/libio.h>
15
#include <rtems/termiostypes.h>
16
#include <termios.h>
17
#include <assert.h>
18
 
19
/*
20
 * Basic 16552 driver
21
 */
22
 
23
struct uart_data
24
{
25
  int ioMode;
26
  int hwFlow;
27
  unsigned int  ier;
28
  unsigned long baud;
29
  unsigned long databits;
30
  unsigned long parity;
31
  unsigned long stopbits;
32
};
33
 
34
static struct uart_data uart_data[2];
35
 
36
/*
37
 * Macros to read/write register of uart, if configuration is
38
 * different just rewrite these macros
39
 */
40
 
41
static inline unsigned char
42
uread(int uart, unsigned int reg)
43
{
44
  register unsigned char val;
45
 
46
  if (uart == 0) {
47
    inport_byte(COM1_BASE_IO+reg, val);
48
  } else {
49
    inport_byte(COM2_BASE_IO+reg, val);
50
  }
51
 
52
  return val;
53
}
54
 
55
static inline void
56
uwrite(int uart, int reg, unsigned int val)
57
{
58
  if (uart == 0) {
59
    outport_byte(COM1_BASE_IO+reg, val);
60
  } else {
61
    outport_byte(COM2_BASE_IO+reg, val);
62
  }
63
}
64
 
65
#ifdef UARTDEBUG
66
    static void
67
uartError(int uart)
68
{
69
  unsigned char uartStatus, dummy;
70
 
71
  uartStatus = uread(uart, LSR);
72
  dummy = uread(uart, RBR);
73
 
74
  if (uartStatus & OE)
75
    printk("********* Over run Error **********\n");
76
  if (uartStatus & PE)
77
    printk("********* Parity Error   **********\n");
78
  if (uartStatus & FE)
79
    printk("********* Framing Error  **********\n");
80
  if (uartStatus & BI)
81
    printk("********* Parity Error   **********\n");
82
  if (uartStatus & ERFIFO)
83
    printk("********* Error receive Fifo **********\n");
84
 
85
}
86
#else
87
inline void uartError(int uart)
88
{
89
  unsigned char uartStatus;
90
 
91
  uartStatus = uread(uart, LSR);
92
  uartStatus = uread(uart, RBR);
93
}
94
#endif
95
 
96
/*
97
 * Uart initialization, it is hardcoded to 8 bit, no parity,
98
 * one stop bit, FIFO, things to be changed
99
 * are baud rate and nad hw flow control,
100
 * and longest rx fifo setting
101
 */
102
void
103
BSP_uart_init
104
(
105
  int uart,
106
  unsigned long baud,
107
  unsigned long databits,
108
  unsigned long parity,
109
  unsigned long stopbits,
110
  int hwFlow
111
)
112
{
113
  unsigned char tmp;
114
 
115
  /* Sanity check */
116
  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
117
 
118
  switch(baud)
119
    {
120
    case 50:
121
    case 75:
122
    case 110:
123
    case 134:
124
    case 300:
125
    case 600:
126
    case 1200:
127
    case 2400:
128
    case 9600:
129
    case 19200:
130
    case 38400:
131
    case 57600:
132
    case 115200:
133
      break;
134
    default:
135
      assert(0);
136
      return;
137
    }
138
 
139
  /* Set DLAB bit to 1 */
140
  uwrite(uart, LCR, DLAB);
141
 
142
  /* Set baud rate */
143
  uwrite(uart, DLL,  (BSPBaseBaud/baud) & 0xff);
144
  uwrite(uart, DLM,  ((BSPBaseBaud/baud) >> 8) & 0xff);
145
 
146
  /* 8-bit, no parity , 1 stop */
147
  uwrite(uart, LCR, databits | parity | stopbits);
148
 
149
 
150
  /* Set DTR, RTS and OUT2 high */
151
  uwrite(uart, MCR, DTR | RTS | OUT_2);
152
 
153
  /* Enable FIFO */
154
  uwrite(uart, FCR, FIFO_EN | XMIT_RESET | RCV_RESET | RECEIVE_FIFO_TRIGGER12);
155
 
156
  /* Disable Interrupts */
157
  uwrite(uart, IER, 0);
158
 
159
  /* Read status to clear them */
160
  tmp = uread(uart, LSR);
161
  tmp = uread(uart, RBR);
162
  tmp = uread(uart, MSR);
163
 
164
  /* Remember state */
165
  uart_data[uart].baud       = baud;
166
  uart_data[uart].databits   = databits;
167
  uart_data[uart].parity     = parity;
168
  uart_data[uart].stopbits   = stopbits;
169
  uart_data[uart].hwFlow     = hwFlow;
170
  return;
171
}
172
 
173
/*
174
 * Set baud
175
 */
176
 
177
void
178
BSP_uart_set_baud(
179
  int uart,
180
  unsigned long baud
181
)
182
{
183
  /* Sanity check */
184
  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
185
 
186
  BSP_uart_set_attributes( uart, baud, uart_data[uart].databits,
187
    uart_data[uart].parity, uart_data[uart].stopbits );
188
}
189
 
190
/*
191
 *  Set all attributes
192
 */
193
 
194
void
195
BSP_uart_set_attributes
196
(
197
  int uart,
198
  unsigned long baud,
199
  unsigned long databits,
200
  unsigned long parity,
201
  unsigned long stopbits
202
)
203
{
204
  unsigned char mcr, ier;
205
 
206
  /* Sanity check */
207
  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
208
 
209
  /*
210
   * This function may be called whenever TERMIOS parameters
211
   * are changed, so we have to make sure that baud change is
212
   * indeed required
213
   */
214
 
215
  if( (baud     == uart_data[uart].baud)     &&
216
      (databits == uart_data[uart].databits) &&
217
      (parity   == uart_data[uart].parity)   &&
218
      (stopbits == uart_data[uart].stopbits) )
219
    {
220
      return;
221
    }
222
 
223
  mcr = uread(uart, MCR);
224
  ier = uread(uart, IER);
225
 
226
  BSP_uart_init(uart, baud, databits, parity, stopbits, uart_data[uart].hwFlow);
227
 
228
  uwrite(uart, MCR, mcr);
229
  uwrite(uart, IER, ier);
230
 
231
  return;
232
}
233
 
234
/*
235
 * Enable/disable interrupts
236
 */
237
void
238
BSP_uart_intr_ctrl(int uart, int cmd)
239
{
240
  int iStatus = (int)INTERRUPT_DISABLE;
241
 
242
  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
243
 
244
  switch(cmd)
245
    {
246
    case BSP_UART_INTR_CTRL_ENABLE:
247
      iStatus |= (RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE | TRANSMIT_ENABLE);
248
      if ( uart_data[uart].hwFlow ) {
249
        iStatus |= MODEM_ENABLE;
250
      }
251
      break;
252
    case BSP_UART_INTR_CTRL_TERMIOS:
253
      iStatus |= (RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE);
254
      if ( uart_data[uart].hwFlow ) {
255
        iStatus |= MODEM_ENABLE;
256
      }
257
      break;
258
    case BSP_UART_INTR_CTRL_GDB:
259
      iStatus |= RECEIVE_ENABLE;
260
      break;
261
    }
262
 
263
  uart_data[uart].ier = iStatus;
264
  uwrite(uart, IER, iStatus);
265
 
266
  return;
267
}
268
 
269
void
270
BSP_uart_throttle(int uart)
271
{
272
  unsigned int mcr;
273
 
274
  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
275
 
276
  if(!uart_data[uart].hwFlow)
277
    {
278
      /* Should not happen */
279
      assert(0);
280
      return;
281
    }
282
  mcr = uread (uart, MCR);
283
  /* RTS down */
284
  mcr &= ~RTS;
285
  uwrite(uart, MCR, mcr);
286
 
287
  return;
288
}
289
 
290
void
291
BSP_uart_unthrottle(int uart)
292
{
293
  unsigned int mcr;
294
 
295
  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
296
 
297
  if(!uart_data[uart].hwFlow)
298
    {
299
      /* Should not happen */
300
      assert(0);
301
      return;
302
    }
303
  mcr = uread (uart, MCR);
304
  /* RTS up */
305
  mcr |= RTS;
306
  uwrite(uart, MCR, mcr);
307
 
308
  return;
309
}
310
 
311
/*
312
 * Status function, -1 if error
313
 * detected, 0 if no received chars available,
314
 * 1 if received char available, 2 if break
315
 * is detected, it will eat break and error
316
 * chars. It ignores overruns - we cannot do
317
 * anything about - it execpt count statistics
318
 * and we are not counting it.
319
 */
320
int
321
BSP_uart_polled_status(int uart)
322
{
323
  unsigned char val;
324
 
325
  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
326
 
327
  val = uread(uart, LSR);
328
 
329
  if(val & BI)
330
    {
331
      /* BREAK found, eat character */
332
      uread(uart, RBR);
333
      return BSP_UART_STATUS_BREAK;
334
    }
335
 
336
  if((val & (DR | OE | FE)) ==  1)
337
    {
338
      /* No error, character present */
339
      return BSP_UART_STATUS_CHAR;
340
    }
341
 
342
  if((val & (DR | OE | FE)) == 0)
343
    {
344
      /* Nothing */
345
      return BSP_UART_STATUS_NOCHAR;
346
    }
347
 
348
  /*
349
   * Framing or parity error
350
   * eat character
351
   */
352
  uread(uart, RBR);
353
 
354
  return BSP_UART_STATUS_ERROR;
355
}
356
 
357
 
358
/*
359
 * Polled mode write function
360
 */
361
void
362
BSP_uart_polled_write(int uart, int val)
363
{
364
  unsigned char val1;
365
 
366
  /* Sanity check */
367
  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
368
 
369
  for(;;)
370
    {
371
      if((val1=uread(uart, LSR)) & THRE)
372
        {
373
          break;
374
        }
375
    }
376
 
377
  if(uart_data[uart].hwFlow)
378
    {
379
      for(;;)
380
        {
381
          if(uread(uart, MSR) & CTS)
382
            {
383
              break;
384
            }
385
        }
386
    }
387
 
388
  uwrite(uart, THR, val & 0xff);
389
 
390
  /*
391
   * Wait for character to be transmitted.
392
   * This ensures that printk and printf play nicely together
393
   * when using the same serial port.
394
   * Yes, there's a performance hit here, but if we're doing
395
   * polled writes to a serial port we're probably not that
396
   * interested in efficiency anyway.....
397
   */
398
  for(;;)
399
    {
400
      if((val1=uread(uart, LSR)) & THRE)
401
      {
402
      break;
403
      }
404
    }
405
 
406
  return;
407
}
408
 
409
void
410
BSP_output_char_via_serial(int val)
411
{
412
  BSP_uart_polled_write(BSPConsolePort, val);
413
  if (val == '\n') BSP_uart_polled_write(BSPConsolePort,'\r');
414
}
415
 
416
/*
417
 * Polled mode read function
418
 */
419
int
420
BSP_uart_polled_read(int uart)
421
{
422
  unsigned char val;
423
 
424
  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
425
 
426
  for(;;)
427
    {
428
      if(uread(uart, LSR) & DR)
429
        {
430
          break;
431
        }
432
    }
433
 
434
  val = uread(uart, RBR);
435
 
436
  return (int)(val & 0xff);
437
}
438
 
439
unsigned
440
BSP_poll_char_via_serial()
441
{
442
        return BSP_uart_polled_read(BSPConsolePort);
443
}
444
 
445
 
446
/* ================ Termios support  =================*/
447
 
448
static volatile int  termios_stopped_com1        = 0;
449
static volatile int  termios_tx_active_com1      = 0;
450
static void*         termios_ttyp_com1           = NULL;
451
static char          termios_tx_hold_com1        = 0;
452
static volatile char termios_tx_hold_valid_com1  = 0;
453
 
454
static volatile int  termios_stopped_com2        = 0;
455
static volatile int  termios_tx_active_com2      = 0;
456
static void*         termios_ttyp_com2           = NULL;
457
static char          termios_tx_hold_com2        = 0;
458
static volatile char termios_tx_hold_valid_com2  = 0;
459
 
460
static void ( *driver_input_handler_com1 )( void *,  char *, int ) = 0;
461
static void ( *driver_input_handler_com2 )( void *,  char *, int ) = 0;
462
 
463
/*
464
 * This routine sets the handler to handle the characters received
465
 * from the serial port.
466
 */
467
void uart_set_driver_handler( int port, void ( *handler )( void *,  char *, int ) )
468
{
469
  switch( port )
470
  {
471
    case BSP_UART_COM1:
472
     driver_input_handler_com1 = handler;
473
     break;
474
 
475
    case BSP_UART_COM2:
476
     driver_input_handler_com2 = handler;
477
     break;
478
  }
479
}
480
 
481
 
482
/*
483
 * Set channel parameters
484
 */
485
void
486
BSP_uart_termios_set(int uart, void *ttyp)
487
{
488
  struct rtems_termios_tty *p = (struct rtems_termios_tty *)ttyp;
489
  unsigned char val;
490
  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
491
 
492
  if(uart == BSP_UART_COM1)
493
    {
494
      uart_data[uart].ioMode = p->device.outputUsesInterrupts;
495
      if(uart_data[uart].hwFlow)
496
        {
497
          val = uread(uart, MSR);
498
 
499
          termios_stopped_com1   = (val & CTS) ? 0 : 1;
500
        }
501
      else
502
        {
503
          termios_stopped_com1 = 0;
504
        }
505
      termios_tx_active_com1      = 0;
506
      termios_ttyp_com1           = ttyp;
507
      termios_tx_hold_com1        = 0;
508
      termios_tx_hold_valid_com1  = 0;
509
    }
510
  else
511
    {
512
      uart_data[uart].ioMode = p->device.outputUsesInterrupts;
513
      if(uart_data[uart].hwFlow)
514
        {
515
          val = uread(uart, MSR);
516
 
517
          termios_stopped_com2   = (val & CTS) ? 0 : 1;
518
        }
519
      else
520
        {
521
          termios_stopped_com2 = 0;
522
        }
523
      termios_tx_active_com2      = 0;
524
      termios_ttyp_com2           = ttyp;
525
      termios_tx_hold_com2        = 0;
526
      termios_tx_hold_valid_com2  = 0;
527
    }
528
 
529
  return;
530
}
531
 
532
int
533
BSP_uart_termios_read_com1(int uart)
534
{
535
  int     off = (int)0;
536
  char    buf[40];
537
 
538
  /* read bytes */
539
  while (( off < sizeof(buf) ) && ( uread(BSP_UART_COM1, LSR) & DR )) {
540
    buf[off++] = uread(BSP_UART_COM1, RBR);
541
  }
542
 
543
  /* write out data */
544
  if ( off > 0 ) {
545
    rtems_termios_enqueue_raw_characters(termios_ttyp_com1, buf, off);
546
  }
547
 
548
  /* enable receive interrupts */
549
  uart_data[BSP_UART_COM1].ier |= (RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE);
550
  uwrite(BSP_UART_COM1, IER, uart_data[BSP_UART_COM1].ier);
551
 
552
  return ( EOF );
553
}
554
 
555
int
556
BSP_uart_termios_read_com2(int uart)
557
{
558
  int     off = (int)0;
559
  char    buf[40];
560
 
561
  /* read current byte */
562
  while (( off < sizeof(buf) ) && ( uread(BSP_UART_COM2, LSR) & DR )) {
563
    buf[off++] = uread(BSP_UART_COM2, RBR);
564
  }
565
 
566
  /* write out data */
567
  if ( off > 0 ) {
568
    rtems_termios_enqueue_raw_characters(termios_ttyp_com2, buf, off);
569
  }
570
 
571
  /* enable receive interrupts */
572
  uart_data[BSP_UART_COM2].ier |= (RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE);
573
  uwrite(BSP_UART_COM2, IER, uart_data[BSP_UART_COM2].ier);
574
 
575
  return ( EOF );
576
}
577
 
578
int
579
BSP_uart_termios_write_com1(int minor, const char *buf, int len)
580
{
581
  assert(buf != NULL);
582
 
583
  if(len <= 0)
584
    {
585
      return 0;
586
    }
587
 
588
  /* If there TX buffer is busy - something is royally screwed up */
589
  assert((uread(BSP_UART_COM1, LSR) & THRE) != 0);
590
 
591
  if(termios_stopped_com1)
592
    {
593
      /* CTS low */
594
      termios_tx_hold_com1       = *buf;
595
      termios_tx_hold_valid_com1 = 1;
596
      return 0;
597
    }
598
 
599
  /* Write character */
600
  uwrite(BSP_UART_COM1, THR, *buf & 0xff);
601
 
602
  /* Enable interrupts if necessary */
603
  if ( !termios_tx_active_com1 ) {
604
    termios_tx_active_com1 = 1;
605
    uart_data[BSP_UART_COM1].ier |= TRANSMIT_ENABLE;
606
    uwrite(BSP_UART_COM1, IER, uart_data[BSP_UART_COM1].ier);
607
  }
608
 
609
  return 0;
610
}
611
 
612
int
613
BSP_uart_termios_write_com2(int minor, const char *buf, int len)
614
{
615
  assert(buf != NULL);
616
 
617
  if(len <= 0)
618
    {
619
      return 0;
620
    }
621
 
622
 
623
  /* If there TX buffer is busy - something is royally screwed up */
624
  assert((uread(BSP_UART_COM2, LSR) & THRE) != 0);
625
 
626
  if(termios_stopped_com2)
627
    {
628
      /* CTS low */
629
      termios_tx_hold_com2       = *buf;
630
      termios_tx_hold_valid_com2 = 1;
631
      return 0;
632
    }
633
 
634
  /* Write character */
635
  uwrite(BSP_UART_COM2, THR, *buf & 0xff);
636
 
637
  /* Enable interrupts if necessary */
638
  if ( !termios_tx_active_com2 ) {
639
    termios_tx_active_com2 = 1;
640
    uart_data[BSP_UART_COM2].ier |= TRANSMIT_ENABLE;
641
    uwrite(BSP_UART_COM2, IER, uart_data[BSP_UART_COM2].ier);
642
  }
643
 
644
  return 0;
645
}
646
 
647
 
648
void
649
BSP_uart_termios_isr_com1(void)
650
{
651
  unsigned char buf[40];
652
  unsigned char val;
653
  int      off, ret, vect;
654
 
655
  off = 0;
656
 
657
  for(;;)
658
    {
659
      vect = uread(BSP_UART_COM1, IIR) & 0xf;
660
 
661
      switch(vect)
662
        {
663
        case MODEM_STATUS :
664
          val = uread(BSP_UART_COM1, MSR);
665
          if(uart_data[BSP_UART_COM1].hwFlow)
666
            {
667
              if(val & CTS)
668
                {
669
                  /* CTS high */
670
                  termios_stopped_com1 = 0;
671
                  if(termios_tx_hold_valid_com1)
672
                    {
673
                      termios_tx_hold_valid_com1 = 0;
674
                      BSP_uart_termios_write_com1(0, &termios_tx_hold_com1,
675
                                                    1);
676
                    }
677
                }
678
              else
679
                {
680
                  /* CTS low */
681
                  termios_stopped_com1 = 1;
682
                }
683
            }
684
          break;
685
        case NO_MORE_INTR :
686
          /* No more interrupts */
687
          if(off != 0)
688
            {
689
              /* Update rx buffer */
690
         if( driver_input_handler_com1 )
691
         {
692
             driver_input_handler_com1( termios_ttyp_com1, (char *)buf, off );
693
         }
694
         else
695
         {
696
            /* Update rx buffer */
697
                 rtems_termios_enqueue_raw_characters(termios_ttyp_com1, (char *)buf, off );
698
         }
699
            }
700
          return;
701
        case TRANSMITTER_HODING_REGISTER_EMPTY :
702
          /*
703
           * TX holding empty: we have to disable these interrupts
704
           * if there is nothing more to send.
705
           */
706
 
707
          /* If nothing else to send disable interrupts */
708
          ret = rtems_termios_dequeue_characters(termios_ttyp_com1, 1);
709
          if ( ret == 0 ) {
710
            termios_tx_active_com1 = 0;
711
            uart_data[BSP_UART_COM1].ier &= ~(TRANSMIT_ENABLE);
712
            uwrite(BSP_UART_COM1, IER, uart_data[BSP_UART_COM1].ier);
713
          }
714
          break;
715
        case RECEIVER_DATA_AVAIL :
716
        case CHARACTER_TIMEOUT_INDICATION:
717
          if ( uart_data[BSP_UART_COM1].ioMode == TERMIOS_TASK_DRIVEN ) {
718
            /* ensure interrupts are enabled */
719
            if ( uart_data[BSP_UART_COM1].ier & RECEIVE_ENABLE ) {
720
              /* disable interrupts and notify termios */
721
              uart_data[BSP_UART_COM1].ier &= ~(RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE);
722
              uwrite(BSP_UART_COM1, IER, uart_data[BSP_UART_COM1].ier);
723
              rtems_termios_rxirq_occured(termios_ttyp_com1);
724
            }
725
          }
726
          else {
727
            /* RX data ready */
728
            assert(off < sizeof(buf));
729
            buf[off++] = uread(BSP_UART_COM1, RBR);
730
          }
731
          break;
732
        case RECEIVER_ERROR:
733
          /* RX error: eat character */
734
           uartError(BSP_UART_COM1);
735
          break;
736
        default:
737
          /* Should not happen */
738
          assert(0);
739
          return;
740
        }
741
    }
742
}
743
 
744
void
745
BSP_uart_termios_isr_com2()
746
{
747
  unsigned char buf[40];
748
  unsigned char val;
749
  int      off, ret, vect;
750
 
751
  off = 0;
752
 
753
  for(;;)
754
    {
755
      vect = uread(BSP_UART_COM2, IIR) & 0xf;
756
 
757
      switch(vect)
758
        {
759
        case MODEM_STATUS :
760
          val = uread(BSP_UART_COM2, MSR);
761
          if(uart_data[BSP_UART_COM2].hwFlow)
762
            {
763
              if(val & CTS)
764
                {
765
                  /* CTS high */
766
                  termios_stopped_com2 = 0;
767
                  if(termios_tx_hold_valid_com2)
768
                    {
769
                      termios_tx_hold_valid_com2 = 0;
770
                      BSP_uart_termios_write_com2(0, &termios_tx_hold_com2,
771
                                                    1);
772
                    }
773
                }
774
              else
775
                {
776
                  /* CTS low */
777
                  termios_stopped_com2 = 1;
778
                }
779
            }
780
          break;
781
        case NO_MORE_INTR :
782
          /* No more interrupts */
783
          if(off != 0)
784
            {
785
              /* Update rx buffer */
786
         if( driver_input_handler_com2 )
787
         {
788
             driver_input_handler_com2( termios_ttyp_com2, (char *)buf, off );
789
         }
790
         else
791
         {
792
                rtems_termios_enqueue_raw_characters(termios_ttyp_com2, (char *)buf, off);
793
         }
794
            }
795
          return;
796
        case TRANSMITTER_HODING_REGISTER_EMPTY :
797
          /*
798
           * TX holding empty: we have to disable these interrupts
799
           * if there is nothing more to send.
800
           */
801
 
802
          /* If nothing else to send disable interrupts */
803
          ret = rtems_termios_dequeue_characters(termios_ttyp_com2, 1);
804
          if ( ret == 0 ) {
805
            termios_tx_active_com2 = 0;
806
            uart_data[BSP_UART_COM2].ier &= ~(TRANSMIT_ENABLE);
807
            uwrite(BSP_UART_COM2, IER, uart_data[BSP_UART_COM2].ier);
808
          }
809
          break;
810
        case RECEIVER_DATA_AVAIL :
811
        case CHARACTER_TIMEOUT_INDICATION:
812
          if ( uart_data[BSP_UART_COM2].ioMode == TERMIOS_TASK_DRIVEN ) {
813
            /* ensure interrupts are enabled */
814
            if ( uart_data[BSP_UART_COM2].ier & RECEIVE_ENABLE ) {
815
              /* disable interrupts and notify termios */
816
              uart_data[BSP_UART_COM2].ier &= ~(RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE);
817
              uwrite(BSP_UART_COM2, IER, uart_data[BSP_UART_COM2].ier);
818
              rtems_termios_rxirq_occured(termios_ttyp_com2);
819
            }
820
          }
821
          else {
822
            /* RX data ready */
823
            assert(off < sizeof(buf));
824
            buf[off++] = uread(BSP_UART_COM2, RBR);
825
          }
826
          break;
827
        case RECEIVER_ERROR:
828
          /* RX error: eat character */
829
           uartError(BSP_UART_COM2);
830
          break;
831
        default:
832
          /* Should not happen */
833
          assert(0);
834
          return;
835
        }
836
    }
837
}
838
 
839
 
840
/* ================= GDB support     ===================*/
841
static int sav[4] __attribute__ ((unused));
842
 
843
/*
844
 * Interrupt service routine for COM1 - all,
845
 * it does it check whether ^C is received
846
 * if yes it will flip TF bit before returning
847
 * Note: it should be installed as raw interrupt
848
 * handler
849
 */
850
 
851
asm (".p2align 4");
852
asm (".text");
853
asm (".globl BSP_uart_dbgisr_com1");
854
asm ("BSP_uart_dbgisr_com1:");
855
asm ("    movl %eax, sav");          /* Save eax */
856
asm ("    movl %ebx, sav + 4");      /* Save ebx */
857
asm ("    movl %edx, sav + 8");      /* Save edx */
858
 
859
asm ("    movl $0, %ebx");           /* Clear flag */
860
 
861
/*
862
 * We know that only receive related interrupts
863
 * are available, eat chars
864
 */
865
asm ("uart_dbgisr_com1_1:");
866
asm ("    movw $0x3FD, %dx");
867
asm ("    inb  %dx, %al"); /* Read LSR */
868
asm ("    andb $1, %al");
869
asm ("    cmpb $0, %al");
870
asm ("    je   uart_dbgisr_com1_2");
871
asm ("    movw $0x3F8, %dx");
872
asm ("    inb  %dx, %al");    /* Get input character */
873
asm ("    cmpb $3, %al");
874
asm ("    jne  uart_dbgisr_com1_1");
875
 
876
/* ^C received, set flag */
877
asm ("    movl $1, %ebx");
878
asm ("    jmp uart_dbgisr_com1_1");
879
 
880
/* All chars read */
881
asm ("uart_dbgisr_com1_2:");
882
 
883
/* If flag is set we have to tweak TF */
884
asm ("   cmpl $0, %ebx");
885
asm ("   je   uart_dbgisr_com1_3");
886
 
887
/* Flag is set */
888
asm ("   movl sav+4, %ebx");     /* Restore ebx */
889
asm ("   movl sav+8, %edx");     /* Restore edx */
890
 
891
/* Set TF bit */
892
asm ("   popl  %eax");           /* Pop eip */
893
asm ("   movl  %eax, sav + 4");  /* Save it */
894
asm ("   popl  %eax");           /* Pop cs */
895
asm ("   movl  %eax, sav + 8");  /* Save it */
896
asm ("   popl  %eax");           /* Pop flags */
897
asm ("   orl   $0x100, %eax");   /* Modify it */
898
asm ("   pushl %eax");           /* Push it back */
899
asm ("   movl  sav+8, %eax");    /* Put back cs */
900
asm ("   pushl %eax");
901
asm ("   movl  sav+4, %eax");    /* Put back eip */
902
asm ("   pushl %eax");
903
 
904
/* Acknowledge IRQ */
905
asm ("   movb  $0x20, %al");
906
asm ("   outb  %al, $0x20");
907
asm ("   movl  sav, %eax");      /* Restore eax */
908
asm ("   iret");                 /* Done */
909
 
910
/* Flag is not set */
911
asm("uart_dbgisr_com1_3:");
912
asm ("   movl sav+4, %ebx");     /* Restore ebx */
913
asm ("   movl sav+8, %edx");     /* Restore edx */
914
 
915
/* Acknowledge irq */
916
asm ("   movb  $0x20, %al");
917
asm ("   outb  %al, $0x20");
918
asm ("   movl  sav, %eax");      /* Restore eax */
919
asm ("   iret");                 /* Done */
920
 
921
 
922
/*
923
 * Interrupt service routine for COM2 - all,
924
 * it does it check whether ^C is received
925
 * if yes it will flip TF bit before returning
926
 * Note: it has to be installed as raw interrupt
927
 * handler
928
 */
929
asm (".p2align 4");
930
asm (".text");
931
asm (".globl BSP_uart_dbgisr_com2");
932
asm ("BSP_uart_dbgisr_com2:");
933
asm ("    movl %eax, sav");          /* Save eax */
934
asm ("    movl %ebx, sav + 4");      /* Save ebx */
935
asm ("    movl %edx, sav + 8");      /* Save edx */
936
 
937
asm ("    movl $0, %ebx");           /* Clear flag */
938
 
939
/*
940
 * We know that only receive related interrupts
941
 * are available, eat chars
942
 */
943
asm ("uart_dbgisr_com2_1:");
944
asm ("    movw $0x2FD, %dx");
945
asm ("    inb  %dx, %al"); /* Read LSR */
946
asm ("    andb $1, %al");
947
asm ("    cmpb $0, %al");
948
asm ("    je   uart_dbgisr_com2_2");
949
asm ("    movw $0x2F8, %dx");
950
asm ("    inb  %dx, %al");    /* Get input character */
951
asm ("    cmpb $3, %al");
952
asm ("    jne  uart_dbgisr_com2_1");
953
 
954
/* ^C received, set flag */
955
asm ("    movl $1, %ebx");
956
asm ("    jmp uart_dbgisr_com2_1");
957
 
958
/* All chars read */
959
asm ("uart_dbgisr_com2_2:");
960
 
961
/* If flag is set we have to tweak TF */
962
asm ("   cmpl $0, %ebx");
963
asm ("   je   uart_dbgisr_com2_3");
964
 
965
/* Flag is set */
966
asm ("   movl sav+4, %ebx");     /* Restore ebx */
967
asm ("   movl sav+8, %edx");     /* Restore edx */
968
 
969
/* Set TF bit */
970
asm ("   popl  %eax");           /* Pop eip */
971
asm ("   movl  %eax, sav + 4");  /* Save it */
972
asm ("   popl  %eax");           /* Pop cs */
973
asm ("   movl  %eax, sav + 8");  /* Save it */
974
asm ("   popl  %eax");           /* Pop flags */
975
asm ("   orl   $0x100, %eax");   /* Modify it */
976
asm ("   pushl %eax");           /* Push it back */
977
asm ("   movl  sav+8, %eax");    /* Put back cs */
978
asm ("   pushl %eax");
979
asm ("   movl  sav+4, %eax");    /* Put back eip */
980
asm ("   pushl %eax");
981
 
982
/* Acknowledge IRQ */
983
asm ("   movb  $0x20, %al");
984
asm ("   outb  %al, $0x20");
985
asm ("   movl  sav, %eax");      /* Restore eax */
986
asm ("   iret");                 /* Done */
987
 
988
/* Flag is not set */
989
asm("uart_dbgisr_com2_3:");
990
asm ("   movl sav+4, %ebx");     /* Restore ebx */
991
asm ("   movl sav+8, %edx");     /* Restore edx */
992
 
993
/* Acknowledge irq */
994
asm ("   movb  $0x20, %al");
995
asm ("   outb  %al, $0x20");
996
asm ("   movl  sav, %eax");      /* Restore eax */
997
asm ("   iret");                 /* Done */
998
 
999
 
1000
 
1001
 
1002
 
1003
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.