source: rtems/c/src/lib/libbsp/arm/shared/comm/uart.c @ 936c8d6

4.115
Last change on this file since 936c8d6 was 9b4422a2, checked in by Joel Sherrill <joel.sherrill@…>, on 05/03/12 at 15:09:24

Remove All CVS Id Strings Possible Using a Script

Script does what is expected and tries to do it as
smartly as possible.

+ remove occurrences of two blank comment lines

next to each other after Id string line removed.

+ remove entire comment blocks which only exited to

contain CVS Ids

+ If the processing left a blank line at the top of

a file, it was removed.

  • Property mode set to 100644
File size: 10.9 KB
RevLine 
[08330bf]1/*
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 *  COPYRIGHT (c) 2000 Canon Research France SA.
8 *  Emmanuel Raguet, mailto:raguet@crf.canon.fr
9 *
10 * The license and distribution terms for this file may be
[15ca4e7]11 * found in the file LICENSE in this distribution or at
[85aa609]12 * http://www.rtems.com/license/LICENSE.
[08330bf]13 */
14
15#include <bsp.h>
16#include <irq.h>
17#include <registers.h>
18#include <uart.h>
19#include <rtems/libio.h>
20#include <assert.h>
21
22/*
23 * Basic 16552 driver
24 */
25
26struct uart_data
27{
28  int hwFlow;
29  int baud;
30};
31
32static struct uart_data uart_data[2];
33
[6128a4a]34/*
[08330bf]35 * Macros to read/wirte register of uart, if configuration is
36 * different just rewrite these macros
[6128a4a]37 */
[08330bf]38
39static inline unsigned char
40uread(int uart, unsigned int reg)
41{
42  register unsigned char val;
43
44  val = Regs[reg];
[6128a4a]45
[08330bf]46  return val;
47}
48
[6128a4a]49static inline void
[08330bf]50uwrite(int uart, int reg, unsigned int val)
51{
52
53  Regs[reg] = val;
54
55}
56
57#ifdef UARTDEBUG
58    static void
59uartError(int uart)
60{
61  unsigned char uartStatus, dummy;
62
63  uartStatus = uread(uart, LSR);
64  dummy = uread(uart, RBR);
65
66  if (uartStatus & OE)
67    printk("********* Over run Error **********\n");
68  if (uartStatus & PE)
69    printk("********* Parity Error   **********\n");
70  if (uartStatus & FE)
71    printk("********* Framing Error  **********\n");
72  if (uartStatus & BI)
73    printk("********* Parity Error   **********\n");
74  if (uartStatus & ERFIFO)
75    printk("********* Error receive Fifo **********\n");
76
77}
78#else
79inline void uartError(int uart)
80{
81  unsigned char uartStatus;
[6128a4a]82
[08330bf]83  uartStatus = uread(uart, LSR);
84  uartStatus = uread(uart, RBR);
85}
86#endif
87
[6128a4a]88/*
[08330bf]89 * Uart initialization, it is hardcoded to 8 bit, no parity,
90 * one stop bit, FIFO, things to be changed
91 * are baud rate and nad hw flow control,
92 * and longest rx fifo setting
93 */
94void
95BSP_uart_init(int uart, int baud, int hwFlow)
96{
97  unsigned char tmp;
[6128a4a]98
[08330bf]99  /* Sanity check */
100  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
[6128a4a]101
[08330bf]102  switch(baud)
103    {
104    case 50:
105    case 75:
106    case 110:
107    case 134:
108    case 300:
109    case 600:
110    case 1200:
111    case 2400:
112    case 9600:
113    case 19200:
114    case 38400:
115    case 57600:
116    case 115200:
117      break;
118    default:
119      assert(0);
120      return;
121    }
[6128a4a]122
[08330bf]123  /* Enable UART block */
124  uwrite(uart, CNT, UART_ENABLE | PAD_ENABLE);
125
126  /* Set DLAB bit to 1 */
127  uwrite(uart, LCR, DLAB);
[6128a4a]128
[08330bf]129  /* Set baud rate */
[6128a4a]130  uwrite(uart, DLL,  (BSPBaseBaud/baud) & 0xff);
131  uwrite(uart, DLM,  ((BSPBaseBaud/baud) >> 8) & 0xff);
[08330bf]132
133  /* 8-bit, no parity , 1 stop */
134  uwrite(uart, LCR, CHR_8_BITS);
[6128a4a]135
[08330bf]136  /* Enable FIFO */
137  uwrite(uart, FCR, FIFO_EN | XMIT_RESET | RCV_RESET | RECEIVE_FIFO_TRIGGER12);
138
139  /* Disable Interrupts */
140  uwrite(uart, IER, 0);
141
142  /* Read status to clear them */
143  tmp = uread(uart, LSR);
144  tmp = uread(uart, RBR);
145
146  /* Remember state */
147  uart_data[uart].hwFlow     = hwFlow;
148  uart_data[uart].baud       = baud;
149  return;
150}
151
[6128a4a]152/*
[08330bf]153 * Set baud
154 */
155void
156BSP_uart_set_baud(int uart, int baud)
157{
158  unsigned char  ier;
159
160  /* Sanity check */
161  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
[6128a4a]162
163  /*
[08330bf]164   * This function may be called whenever TERMIOS parameters
[6128a4a]165   * are changed, so we have to make sure that baud change is
[08330bf]166   * indeed required
167   */
168
169  if(baud == uart_data[uart].baud)
170    {
171      return;
172    }
173
174  ier = uread(uart, IER);
175
176  BSP_uart_init(uart, baud, uart_data[uart].hwFlow);
177
178  uwrite(uart, IER, ier);
[6128a4a]179
[08330bf]180  return;
181}
182
183/*
[6128a4a]184 * Enable/disable interrupts
[08330bf]185 */
[6128a4a]186void
[08330bf]187BSP_uart_intr_ctrl(int uart, int cmd)
188{
189
190  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
191
192  switch(cmd)
193    {
194    case BSP_UART_INTR_CTRL_DISABLE:
195      uwrite(uart, IER, INTERRUPT_DISABLE);
196      break;
197    case BSP_UART_INTR_CTRL_ENABLE:
198      uwrite(uart, IER,
199             (RECEIVE_ENABLE  |
200              TRANSMIT_ENABLE |
201              RECEIVER_LINE_ST_ENABLE
202              )
203             );
204      break;
205    case BSP_UART_INTR_CTRL_TERMIOS:
206      uwrite(uart, IER,
207             (RECEIVE_ENABLE  |
208              RECEIVER_LINE_ST_ENABLE
209              )
210             );
211      break;
212    case BSP_UART_INTR_CTRL_GDB:
213      uwrite(uart, IER, RECEIVE_ENABLE);
214      break;
215    default:
216      assert(0);
217      break;
218    }
[6128a4a]219
[08330bf]220  return;
221}
222
223/*
224 * Status function, -1 if error
225 * detected, 0 if no received chars available,
226 * 1 if received char available, 2 if break
[6128a4a]227 * is detected, it will eat break and error
228 * chars. It ignores overruns - we cannot do
[08330bf]229 * anything about - it execpt count statistics
230 * and we are not counting it.
231 */
[6128a4a]232int
[08330bf]233BSP_uart_polled_status(int uart)
234{
235  unsigned char val;
236
237  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
238
239  val = uread(uart, LSR);
240
241  if(val & BI)
242    {
243      /* BREAK found, eat character */
244      uread(uart, RBR);
245      return BSP_UART_STATUS_BREAK;
246    }
247
248  if((val & (DR | OE | FE)) ==  1)
249    {
[6128a4a]250      /* No error, character present */
[08330bf]251      return BSP_UART_STATUS_CHAR;
252    }
253
254  if((val & (DR | OE | FE)) == 0)
255    {
256      /* Nothing */
257      return BSP_UART_STATUS_NOCHAR;
258    }
259
[6128a4a]260  /*
[08330bf]261   * Framing or parity error
262   * eat character
263   */
264  uread(uart, RBR);
[6128a4a]265
[08330bf]266  return BSP_UART_STATUS_ERROR;
267}
268
269/*
270 * Polled mode write function
271 */
[6128a4a]272void
[08330bf]273BSP_uart_polled_write(int uart, int val)
274{
275  unsigned char val1;
[6128a4a]276
[08330bf]277  /* Sanity check */
278  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
[6128a4a]279
[08330bf]280  for(;;)
281    {
[6128a4a]282      if((val1=uread(uart, LSR)) & THRE)
[08330bf]283        {
284          break;
285        }
286    }
287
288  uwrite(uart, THR, val & 0xff);
[6128a4a]289
[08330bf]290  return;
291}
292
293void
294BSP_output_char_via_serial(int val)
295{
296  BSP_uart_polled_write(BSPConsolePort, val);
297  if (val == '\n') BSP_uart_polled_write(BSPConsolePort,'\r');
298}
299
[6128a4a]300/*
[08330bf]301 * Polled mode read function
302 */
[6128a4a]303int
[08330bf]304BSP_uart_polled_read(int uart)
305{
306  unsigned char val;
307
308  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
[6128a4a]309
[08330bf]310  for(;;)
311    {
312      if(uread(uart, LSR) & DR)
313        {
314          break;
315        }
316    }
[6128a4a]317
[08330bf]318  val = uread(uart, RBR);
319
320  return (int)(val & 0xff);
321}
322
[6128a4a]323unsigned
[08330bf]324BSP_poll_char_via_serial()
325{
326        return BSP_uart_polled_read(BSPConsolePort);
327}
328
329/* ================ Termios support  =================*/
330
331static volatile int  termios_stopped_com1        = 0;
332static volatile int  termios_tx_active_com1      = 0;
333static void*         termios_ttyp_com1           = NULL;
334static char          termios_tx_hold_com1        = 0;
335static volatile char termios_tx_hold_valid_com1  = 0;
336
337static volatile int  termios_stopped_com2        = 0;
338static volatile int  termios_tx_active_com2      = 0;
339static void*         termios_ttyp_com2           = NULL;
340static char          termios_tx_hold_com2        = 0;
341static volatile char termios_tx_hold_valid_com2  = 0;
342
343/*
[6128a4a]344 * Set channel parameters
[08330bf]345 */
346void
347BSP_uart_termios_set(int uart, void *ttyp)
348{
349  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
[6128a4a]350
[08330bf]351  if(uart == BSP_UART_COM1)
352    {
353      termios_stopped_com1 = 0;
354      termios_tx_active_com1      = 0;
355      termios_ttyp_com1           = ttyp;
[6128a4a]356      termios_tx_hold_com1        = 0;
[08330bf]357      termios_tx_hold_valid_com1  = 0;
358    }
359  else
360    {
361      termios_stopped_com2 = 0;
362      termios_tx_active_com2      = 0;
363      termios_ttyp_com2           = ttyp;
[6128a4a]364      termios_tx_hold_com2        = 0;
[08330bf]365      termios_tx_hold_valid_com2  = 0;
366    }
367
368  return;
369}
370
371int
372BSP_uart_termios_write_com1(int minor, const char *buf, int len)
373{
374  assert(buf != NULL);
375
376  if(len <= 0)
377    {
378      return 0;
379    }
380
381  /* If there TX buffer is busy - something is royally screwed up */
[6128a4a]382  assert((uread(BSP_UART_COM1, LSR) & THRE) != 0);
[08330bf]383
384  if(termios_stopped_com1)
385    {
386      /* CTS low */
387      termios_tx_hold_com1       = *buf;
388      termios_tx_hold_valid_com1 = 1;
389      return 0;
390    }
391
392  /* Write character */
393  uwrite(BSP_UART_COM1, THR, *buf & 0xff);
394
395  /* Enable interrupts if necessary */
396  if(!termios_tx_active_com1)
397    {
398      termios_tx_active_com1 = 1;
[6128a4a]399      uwrite(BSP_UART_COM1, IER,
[08330bf]400             (RECEIVE_ENABLE  |
401              TRANSMIT_ENABLE |
402              RECEIVER_LINE_ST_ENABLE
403             )
404            );
405    }
406
407  return 0;
408}
409
410int
411BSP_uart_termios_write_com2(int minor, const char *buf, int len)
412{
413  assert(buf != NULL);
414
415  if(len <= 0)
416    {
417      return 0;
418    }
419
420  /* If there TX buffer is busy - something is royally screwed up */
421  assert((uread(BSP_UART_COM2, LSR) & THRE) != 0);
422
423  if(termios_stopped_com2)
424    {
425      /* CTS low */
426      termios_tx_hold_com2       = *buf;
427      termios_tx_hold_valid_com2 = 1;
428      return 0;
429    }
430
431  /* Write character */
432
433  uwrite(BSP_UART_COM2, THR, *buf & 0xff);
434
435  /* Enable interrupts if necessary */
436  if(!termios_tx_active_com2)
437    {
438      termios_tx_active_com2 = 1;
439      uwrite(BSP_UART_COM2, IER,
440             (RECEIVE_ENABLE  |
441              TRANSMIT_ENABLE |
442              RECEIVER_LINE_ST_ENABLE
443             )
444            );
445    }
446
447  return 0;
448}
449
450void
451BSP_uart_termios_isr_com1(void)
452{
453  unsigned char buf[40];
454  int      off, ret, vect;
455
456  off = 0;
457
458  for(;;)
459    {
460      vect = uread(BSP_UART_COM1, IIR) & 0xf;
[6128a4a]461
[08330bf]462      switch(vect)
463        {
464        case NO_MORE_INTR :
465          /* No more interrupts */
466          if(off != 0)
467            {
468              /* Update rx buffer */
469              rtems_termios_enqueue_raw_characters(termios_ttyp_com1,
470                                                   (char *)buf,
471                                                   off);
472            }
473          return;
474        case TRANSMITTER_HODING_REGISTER_EMPTY :
[6128a4a]475          /*
476           * TX holding empty: we have to disable these interrupts
477           * if there is nothing more to send.
[08330bf]478           */
479
480          ret = rtems_termios_dequeue_characters(termios_ttyp_com1, 1);
481
482          /* If nothing else to send disable interrupts */
483          if(ret == 0)
484            {
485              uwrite(BSP_UART_COM1, IER,
486                     (RECEIVE_ENABLE  |
487                      RECEIVER_LINE_ST_ENABLE
488                     )
489                    );
490              termios_tx_active_com1 = 0;
491            }
492          break;
493        case RECEIVER_DATA_AVAIL :
494        case CHARACTER_TIMEOUT_INDICATION:
495          /* RX data ready */
496          assert(off < sizeof(buf));
497          buf[off++] = uread(BSP_UART_COM1, RBR);
498          break;
499        case RECEIVER_ERROR:
500          /* RX error: eat character */
501           uartError(BSP_UART_COM1);
502          break;
503        default:
504          /* Should not happen */
505          assert(0);
506          return;
507        }
508    }
509}
[6128a4a]510
[08330bf]511void
512BSP_uart_termios_isr_com2()
513{
514  unsigned char buf[40];
515  int      off, ret, vect;
516
517  off = 0;
518
519  for(;;)
520    {
521      vect = uread(BSP_UART_COM2, IIR) & 0xf;
[6128a4a]522
[08330bf]523      switch(vect)
524        {
525        case NO_MORE_INTR :
526          /* No more interrupts */
527          if(off != 0)
528            {
529              /* Update rx buffer */
530              rtems_termios_enqueue_raw_characters(termios_ttyp_com2,
531                                                   (char *)buf,
532                                                   off);
533            }
534          return;
535        case TRANSMITTER_HODING_REGISTER_EMPTY :
[6128a4a]536          /*
537           * TX holding empty: we have to disable these interrupts
[08330bf]538           * if there is nothing more to send.
539           */
540
541          ret = rtems_termios_dequeue_characters(termios_ttyp_com2, 1);
542
543          /* If nothing else to send disable interrupts */
544          if(ret == 0)
545            {
546              uwrite(BSP_UART_COM2, IER,
547                     (RECEIVE_ENABLE  |
548                      RECEIVER_LINE_ST_ENABLE
549                     )
550                    );
551              termios_tx_active_com2 = 0;
552            }
553          break;
554        case RECEIVER_DATA_AVAIL :
555        case CHARACTER_TIMEOUT_INDICATION:
556          /* RX data ready */
557          assert(off < sizeof(buf));
558          buf[off++] = uread(BSP_UART_COM2, RBR);
559          break;
560        case RECEIVER_ERROR:
561          /* RX error: eat character */
562           uartError(BSP_UART_COM2);
563          break;
564        default:
565          /* Should not happen */
566          assert(0);
567          return;
568        }
569    }
570}
Note: See TracBrowser for help on using the repository browser.