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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libbsp/] [powerpc/] [shared/] [console/] [uart.c] - Blame information for rev 562

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*
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
 *  $Id: uart.c,v 1.2 2001-09-27 12:01:06 chris Exp $
8
 */
9
 
10
#include <bsp.h>
11
#include <bsp/irq.h>
12
#include <bsp/uart.h>
13
#include <rtems/libio.h>
14
#include <assert.h>
15
 
16
/*
17
 * Basic 16552 driver
18
 */
19
 
20
struct uart_data
21
{
22
  int hwFlow;
23
  int baud;
24
};
25
 
26
static struct uart_data uart_data[2];
27
 
28
/*
29
 * Macros to read/wirte register of uart, if configuration is
30
 * different just rewrite these macros
31
 */
32
 
33
static inline unsigned char
34
uread(int uart, unsigned int reg)
35
{
36
  register unsigned char val;
37
 
38
  if(uart == 0)
39
    {
40
      inport_byte(COM1_BASE_IO+reg, val);
41
    }
42
  else
43
    {
44
      inport_byte(COM2_BASE_IO+reg, val);
45
    }
46
 
47
  return val;
48
}
49
 
50
static inline void
51
uwrite(int uart, int reg, unsigned int val)
52
{
53
  if(uart == 0)
54
    {
55
      outport_byte(COM1_BASE_IO+reg, val);
56
    }
57
  else
58
    {
59
      outport_byte(COM2_BASE_IO+reg, val);
60
    }
61
}
62
 
63
#ifdef UARTDEBUG
64
    static void
65
uartError(int uart)
66
{
67
  unsigned char uartStatus, dummy;
68
 
69
  uartStatus = uread(uart, LSR);
70
  dummy = uread(uart, RBR);
71
 
72
  if (uartStatus & OE)
73
    printk("********* Over run Error **********\n");
74
  if (uartStatus & PE)
75
    printk("********* Parity Error   **********\n");
76
  if (uartStatus & FE)
77
    printk("********* Framing Error  **********\n");
78
  if (uartStatus & BI)
79
    printk("********* Parity Error   **********\n");
80
  if (uartStatus & ERFIFO)
81
    printk("********* Error receive Fifo **********\n");
82
 
83
}
84
#else
85
inline void uartError(int uart)
86
{
87
  unsigned char uartStatus;
88
 
89
  uartStatus = uread(uart, LSR);
90
  uartStatus = uread(uart, RBR);
91
}
92
#endif
93
 
94
/*
95
 * Uart initialization, it is hardcoded to 8 bit, no parity,
96
 * one stop bit, FIFO, things to be changed
97
 * are baud rate and nad hw flow control,
98
 * and longest rx fifo setting
99
 */
100
void
101
BSP_uart_init(int uart, int baud, int hwFlow)
102
{
103
  unsigned char tmp;
104
 
105
  /* Sanity check */
106
  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
107
 
108
  switch(baud)
109
    {
110
    case 50:
111
    case 75:
112
    case 110:
113
    case 134:
114
    case 300:
115
    case 600:
116
    case 1200:
117
    case 2400:
118
    case 9600:
119
    case 19200:
120
    case 38400:
121
    case 57600:
122
    case 115200:
123
      break;
124
    default:
125
      assert(0);
126
      return;
127
    }
128
 
129
  /* Set DLAB bit to 1 */
130
  uwrite(uart, LCR, DLAB);
131
 
132
  /* Set baud rate */
133
  uwrite(uart, DLL,  (BSPBaseBaud/baud) & 0xff);
134
  uwrite(uart, DLM,  ((BSPBaseBaud/baud) >> 8) & 0xff);
135
 
136
  /* 8-bit, no parity , 1 stop */
137
  uwrite(uart, LCR, CHR_8_BITS);
138
 
139
 
140
  /* Set DTR, RTS and OUT2 high */
141
  uwrite(uart, MCR, DTR | RTS | OUT_2);
142
 
143
  /* Enable FIFO */
144
  uwrite(uart, FCR, FIFO_EN | XMIT_RESET | RCV_RESET | RECEIVE_FIFO_TRIGGER12);
145
 
146
  /* Disable Interrupts */
147
  uwrite(uart, IER, 0);
148
 
149
  /* Read status to clear them */
150
  tmp = uread(uart, LSR);
151
  tmp = uread(uart, RBR);
152
  tmp = uread(uart, MSR);
153
 
154
  /* Remember state */
155
  uart_data[uart].hwFlow     = hwFlow;
156
  uart_data[uart].baud       = baud;
157
  return;
158
}
159
 
160
/*
161
 * Set baud
162
 */
163
void
164
BSP_uart_set_baud(int uart, int baud)
165
{
166
  unsigned char mcr, ier;
167
 
168
  /* Sanity check */
169
  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
170
 
171
  /*
172
   * This function may be called whenever TERMIOS parameters
173
   * are changed, so we have to make sire that baud change is
174
   * indeed required
175
   */
176
 
177
  if(baud == uart_data[uart].baud)
178
    {
179
      return;
180
    }
181
 
182
  mcr = uread(uart, MCR);
183
  ier = uread(uart, IER);
184
 
185
  BSP_uart_init(uart, baud, uart_data[uart].hwFlow);
186
 
187
  uwrite(uart, MCR, mcr);
188
  uwrite(uart, IER, ier);
189
 
190
  return;
191
}
192
 
193
/*
194
 * Enable/disable interrupts
195
 */
196
void
197
BSP_uart_intr_ctrl(int uart, int cmd)
198
{
199
 
200
  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
201
 
202
  switch(cmd)
203
    {
204
    case BSP_UART_INTR_CTRL_DISABLE:
205
      uwrite(uart, IER, INTERRUPT_DISABLE);
206
      break;
207
    case BSP_UART_INTR_CTRL_ENABLE:
208
      if(uart_data[uart].hwFlow)
209
        {
210
          uwrite(uart, IER,
211
                 (RECEIVE_ENABLE  |
212
                  TRANSMIT_ENABLE |
213
                  RECEIVER_LINE_ST_ENABLE |
214
                  MODEM_ENABLE
215
                 )
216
                );
217
        }
218
      else
219
        {
220
          uwrite(uart, IER,
221
                 (RECEIVE_ENABLE  |
222
                  TRANSMIT_ENABLE |
223
                  RECEIVER_LINE_ST_ENABLE
224
                 )
225
                );
226
        }
227
      break;
228
    case BSP_UART_INTR_CTRL_TERMIOS:
229
      if(uart_data[uart].hwFlow)
230
        {
231
          uwrite(uart, IER,
232
                 (RECEIVE_ENABLE  |
233
                  RECEIVER_LINE_ST_ENABLE |
234
                  MODEM_ENABLE
235
                 )
236
                );
237
        }
238
      else
239
        {
240
          uwrite(uart, IER,
241
                 (RECEIVE_ENABLE  |
242
                  RECEIVER_LINE_ST_ENABLE
243
                 )
244
                );
245
        }
246
      break;
247
    case BSP_UART_INTR_CTRL_GDB:
248
      uwrite(uart, IER, RECEIVE_ENABLE);
249
      break;
250
    default:
251
      assert(0);
252
      break;
253
    }
254
 
255
  return;
256
}
257
 
258
void
259
BSP_uart_throttle(int uart)
260
{
261
  unsigned int mcr;
262
 
263
  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
264
 
265
  if(!uart_data[uart].hwFlow)
266
    {
267
      /* Should not happen */
268
      assert(0);
269
      return;
270
    }
271
  mcr = uread (uart, MCR);
272
  /* RTS down */
273
  mcr &= ~RTS;
274
  uwrite(uart, MCR, mcr);
275
 
276
  return;
277
}
278
 
279
void
280
BSP_uart_unthrottle(int uart)
281
{
282
  unsigned int mcr;
283
 
284
  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
285
 
286
  if(!uart_data[uart].hwFlow)
287
    {
288
      /* Should not happen */
289
      assert(0);
290
      return;
291
    }
292
  mcr = uread (uart, MCR);
293
  /* RTS up */
294
  mcr |= RTS;
295
  uwrite(uart, MCR, mcr);
296
 
297
  return;
298
}
299
 
300
/*
301
 * Status function, -1 if error
302
 * detected, 0 if no received chars available,
303
 * 1 if received char available, 2 if break
304
 * is detected, it will eat break and error
305
 * chars. It ignores overruns - we cannot do
306
 * anything about - it execpt count statistics
307
 * and we are not counting it.
308
 */
309
int
310
BSP_uart_polled_status(int uart)
311
{
312
  unsigned char val;
313
 
314
  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
315
 
316
  val = uread(uart, LSR);
317
 
318
  if(val & BI)
319
    {
320
      /* BREAK found, eat character */
321
      uread(uart, RBR);
322
      return BSP_UART_STATUS_BREAK;
323
    }
324
 
325
  if((val & (DR | OE | FE)) ==  1)
326
    {
327
      /* No error, character present */
328
      return BSP_UART_STATUS_CHAR;
329
    }
330
 
331
  if((val & (DR | OE | FE)) == 0)
332
    {
333
      /* Nothing */
334
      return BSP_UART_STATUS_NOCHAR;
335
    }
336
 
337
  /*
338
   * Framing or parity error
339
   * eat character
340
   */
341
  uread(uart, RBR);
342
 
343
  return BSP_UART_STATUS_ERROR;
344
}
345
 
346
 
347
/*
348
 * Polled mode write function
349
 */
350
void
351
BSP_uart_polled_write(int uart, int val)
352
{
353
  unsigned char val1;
354
 
355
  /* Sanity check */
356
  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
357
 
358
  for(;;)
359
    {
360
      if((val1=uread(uart, LSR)) & THRE)
361
        {
362
          break;
363
        }
364
    }
365
 
366
  if(uart_data[uart].hwFlow)
367
    {
368
      for(;;)
369
        {
370
          if(uread(uart, MSR) & CTS)
371
            {
372
              break;
373
            }
374
        }
375
    }
376
 
377
  uwrite(uart, THR, val & 0xff);
378
 
379
  return;
380
}
381
 
382
void
383
BSP_output_char_via_serial(int val)
384
{
385
  BSP_uart_polled_write(BSPConsolePort, val);
386
  if (val == '\n') BSP_uart_polled_write(BSPConsolePort,'\r');
387
}
388
 
389
/*
390
 * Polled mode read function
391
 */
392
int
393
BSP_uart_polled_read(int uart)
394
{
395
  unsigned char val;
396
 
397
  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
398
 
399
  for(;;)
400
    {
401
      if(uread(uart, LSR) & DR)
402
        {
403
          break;
404
        }
405
    }
406
 
407
  val = uread(uart, RBR);
408
 
409
  return (int)(val & 0xff);
410
}
411
 
412
unsigned
413
BSP_poll_char_via_serial()
414
{
415
        return BSP_uart_polled_read(BSPConsolePort);
416
}
417
 
418
 
419
/* ================ Termios support  =================*/
420
 
421
static volatile int  termios_stopped_com1        = 0;
422
static volatile int  termios_tx_active_com1      = 0;
423
static void*         termios_ttyp_com1           = NULL;
424
static char          termios_tx_hold_com1        = 0;
425
static volatile char termios_tx_hold_valid_com1  = 0;
426
 
427
static volatile int  termios_stopped_com2        = 0;
428
static volatile int  termios_tx_active_com2      = 0;
429
static void*         termios_ttyp_com2           = NULL;
430
static char          termios_tx_hold_com2        = 0;
431
static volatile char termios_tx_hold_valid_com2  = 0;
432
 
433
/*
434
 * Set channel parameters
435
 */
436
void
437
BSP_uart_termios_set(int uart, void *ttyp)
438
{
439
  unsigned char val;
440
  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
441
 
442
  if(uart == BSP_UART_COM1)
443
    {
444
      if(uart_data[uart].hwFlow)
445
        {
446
          val = uread(uart, MSR);
447
 
448
          termios_stopped_com1   = (val & CTS) ? 0 : 1;
449
        }
450
      else
451
        {
452
          termios_stopped_com1 = 0;
453
        }
454
      termios_tx_active_com1      = 0;
455
      termios_ttyp_com1           = ttyp;
456
      termios_tx_hold_com1        = 0;
457
      termios_tx_hold_valid_com1  = 0;
458
    }
459
  else
460
    {
461
      if(uart_data[uart].hwFlow)
462
        {
463
          val = uread(uart, MSR);
464
 
465
          termios_stopped_com2   = (val & CTS) ? 0 : 1;
466
        }
467
      else
468
        {
469
          termios_stopped_com2 = 0;
470
        }
471
      termios_tx_active_com2      = 0;
472
      termios_ttyp_com2           = ttyp;
473
      termios_tx_hold_com2        = 0;
474
      termios_tx_hold_valid_com2  = 0;
475
    }
476
 
477
  return;
478
}
479
 
480
int
481
BSP_uart_termios_write_com1(int minor, const char *buf, int len)
482
{
483
  assert(buf != NULL);
484
 
485
  if(len <= 0)
486
    {
487
      return 0;
488
    }
489
 
490
  /* If there TX buffer is busy - something is royally screwed up */
491
  /*   assert((uread(BSP_UART_COM1, LSR) & THRE) != 0); */
492
 
493
 
494
  if(termios_stopped_com1)
495
    {
496
      /* CTS low */
497
      termios_tx_hold_com1       = *buf;
498
      termios_tx_hold_valid_com1 = 1;
499
      return 0;
500
    }
501
 
502
  /* Write character */
503
  uwrite(BSP_UART_COM1, THR, *buf & 0xff);
504
 
505
  /* Enable interrupts if necessary */
506
  if(!termios_tx_active_com1 && uart_data[BSP_UART_COM1].hwFlow)
507
    {
508
      termios_tx_active_com1 = 1;
509
      uwrite(BSP_UART_COM1, IER,
510
             (RECEIVE_ENABLE  |
511
              TRANSMIT_ENABLE |
512
              RECEIVER_LINE_ST_ENABLE |
513
              MODEM_ENABLE
514
             )
515
            );
516
    }
517
  else if(!termios_tx_active_com1)
518
    {
519
      termios_tx_active_com1 = 1;
520
      uwrite(BSP_UART_COM1, IER,
521
             (RECEIVE_ENABLE  |
522
              TRANSMIT_ENABLE |
523
              RECEIVER_LINE_ST_ENABLE
524
             )
525
            );
526
    }
527
 
528
  return 0;
529
}
530
 
531
int
532
BSP_uart_termios_write_com2(int minor, const char *buf, int len)
533
{
534
  assert(buf != NULL);
535
 
536
  if(len <= 0)
537
    {
538
      return 0;
539
    }
540
 
541
 
542
  /* If there TX buffer is busy - something is royally screwed up */
543
  assert((uread(BSP_UART_COM2, LSR) & THRE) != 0);
544
 
545
  if(termios_stopped_com2)
546
    {
547
      /* CTS low */
548
      termios_tx_hold_com2       = *buf;
549
      termios_tx_hold_valid_com2 = 1;
550
      return 0;
551
    }
552
 
553
  /* Write character */
554
 
555
  uwrite(BSP_UART_COM2, THR, *buf & 0xff);
556
 
557
  /* Enable interrupts if necessary */
558
  if(!termios_tx_active_com2 && uart_data[BSP_UART_COM2].hwFlow)
559
    {
560
      termios_tx_active_com2 = 1;
561
      uwrite(BSP_UART_COM2, IER,
562
             (RECEIVE_ENABLE  |
563
              TRANSMIT_ENABLE |
564
              RECEIVER_LINE_ST_ENABLE |
565
              MODEM_ENABLE
566
             )
567
            );
568
    }
569
  else if(!termios_tx_active_com2)
570
    {
571
      termios_tx_active_com2 = 1;
572
      uwrite(BSP_UART_COM2, IER,
573
             (RECEIVE_ENABLE  |
574
              TRANSMIT_ENABLE |
575
              RECEIVER_LINE_ST_ENABLE
576
             )
577
            );
578
    }
579
 
580
  return 0;
581
}
582
 
583
 
584
void
585
BSP_uart_termios_isr_com1(void)
586
{
587
  unsigned char buf[40];
588
  unsigned char val;
589
  int      off, ret, vect;
590
 
591
  off = 0;
592
 
593
  for(;;)
594
    {
595
      vect = uread(BSP_UART_COM1, IIR) & 0xf;
596
 
597
      switch(vect)
598
        {
599
        case MODEM_STATUS :
600
          val = uread(BSP_UART_COM1, MSR);
601
          if(uart_data[BSP_UART_COM1].hwFlow)
602
            {
603
              if(val & CTS)
604
                {
605
                  /* CTS high */
606
                  termios_stopped_com1 = 0;
607
                  if(termios_tx_hold_valid_com1)
608
                    {
609
                      termios_tx_hold_valid_com1 = 0;
610
                      BSP_uart_termios_write_com1(0, &termios_tx_hold_com1,
611
                                                    1);
612
                    }
613
                }
614
              else
615
                {
616
                  /* CTS low */
617
                  termios_stopped_com1 = 1;
618
                }
619
            }
620
          break;
621
        case NO_MORE_INTR :
622
          /* No more interrupts */
623
          if(off != 0)
624
            {
625
              /* Update rx buffer */
626
              rtems_termios_enqueue_raw_characters(termios_ttyp_com1,
627
                                                   (char *)buf,
628
                                                   off);
629
            }
630
          return;
631
        case TRANSMITTER_HODING_REGISTER_EMPTY :
632
          /*
633
           * TX holding empty: we have to disable these interrupts
634
           * if there is nothing more to send.
635
           */
636
 
637
          ret = rtems_termios_dequeue_characters(termios_ttyp_com1, 1);
638
 
639
          /* If nothing else to send disable interrupts */
640
          if(ret == 0 && uart_data[BSP_UART_COM1].hwFlow)
641
            {
642
              uwrite(BSP_UART_COM1, IER,
643
                     (RECEIVE_ENABLE  |
644
                      RECEIVER_LINE_ST_ENABLE |
645
                      MODEM_ENABLE
646
                     )
647
                    );
648
              termios_tx_active_com1 = 0;
649
            }
650
          else if(ret == 0)
651
            {
652
              uwrite(BSP_UART_COM1, IER,
653
                     (RECEIVE_ENABLE  |
654
                      RECEIVER_LINE_ST_ENABLE
655
                     )
656
                    );
657
              termios_tx_active_com1 = 0;
658
            }
659
          break;
660
        case RECEIVER_DATA_AVAIL :
661
        case CHARACTER_TIMEOUT_INDICATION:
662
          /* RX data ready */
663
          assert(off < sizeof(buf));
664
          buf[off++] = uread(BSP_UART_COM1, RBR);
665
          break;
666
        case RECEIVER_ERROR:
667
          /* RX error: eat character */
668
           uartError(BSP_UART_COM1);
669
          break;
670
        default:
671
          /* Should not happen */
672
          assert(0);
673
          return;
674
        }
675
    }
676
}
677
 
678
void
679
BSP_uart_termios_isr_com2()
680
{
681
  unsigned char buf[40];
682
  unsigned char val;
683
  int      off, ret, vect;
684
 
685
  off = 0;
686
 
687
  for(;;)
688
    {
689
      vect = uread(BSP_UART_COM2, IIR) & 0xf;
690
 
691
      switch(vect)
692
        {
693
        case MODEM_STATUS :
694
          val = uread(BSP_UART_COM2, MSR);
695
          if(uart_data[BSP_UART_COM2].hwFlow)
696
            {
697
              if(val & CTS)
698
                {
699
                  /* CTS high */
700
                  termios_stopped_com2 = 0;
701
                  if(termios_tx_hold_valid_com2)
702
                    {
703
                      termios_tx_hold_valid_com2 = 0;
704
                      BSP_uart_termios_write_com2(0, &termios_tx_hold_com2,
705
                                                    1);
706
                    }
707
                }
708
              else
709
                {
710
                  /* CTS low */
711
                  termios_stopped_com2 = 1;
712
                }
713
            }
714
          break;
715
        case NO_MORE_INTR :
716
          /* No more interrupts */
717
          if(off != 0)
718
            {
719
              /* Update rx buffer */
720
              rtems_termios_enqueue_raw_characters(termios_ttyp_com2,
721
                                                   (char *)buf,
722
                                                   off);
723
            }
724
          return;
725
        case TRANSMITTER_HODING_REGISTER_EMPTY :
726
          /*
727
           * TX holding empty: we have to disable these interrupts
728
           * if there is nothing more to send.
729
           */
730
 
731
          ret = rtems_termios_dequeue_characters(termios_ttyp_com2, 1);
732
 
733
          /* If nothing else to send disable interrupts */
734
          if(ret == 0 && uart_data[BSP_UART_COM2].hwFlow)
735
            {
736
              uwrite(BSP_UART_COM2, IER,
737
                     (RECEIVE_ENABLE  |
738
                      RECEIVER_LINE_ST_ENABLE |
739
                      MODEM_ENABLE
740
                     )
741
                    );
742
              termios_tx_active_com2 = 0;
743
            }
744
          else if(ret == 0)
745
            {
746
              uwrite(BSP_UART_COM2, IER,
747
                     (RECEIVE_ENABLE  |
748
                      RECEIVER_LINE_ST_ENABLE
749
                     )
750
                    );
751
              termios_tx_active_com2 = 0;
752
            }
753
          break;
754
        case RECEIVER_DATA_AVAIL :
755
        case CHARACTER_TIMEOUT_INDICATION:
756
          /* RX data ready */
757
          assert(off < sizeof(buf));
758
          buf[off++] = uread(BSP_UART_COM2, RBR);
759
          break;
760
        case RECEIVER_ERROR:
761
          /* RX error: eat character */
762
           uartError(BSP_UART_COM2);
763
          break;
764
        default:
765
          /* Should not happen */
766
          assert(0);
767
          return;
768
        }
769
    }
770
}
771
 
772
 
773
 
774
 
775
 
776
 
777
 
778
 

powered by: WebSVN 2.1.0

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