⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uart.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * This software is Copyright (C) 1998 by T.sqware - all rights limited * It is provided in to the public domain "as is", can be freely modified * as far as this copyight notice is kept unchanged, but does not imply * an endorsement by T.sqware of the product in which it is included. * *  $Id: uart.c,v 1.11 2002/07/16 22:30:11 joel Exp $ */#include <stdio.h>#include <bsp.h>#include <irq.h>#include <uart.h>#include <rtems/libio.h>#include <rtems/termiostypes.h>#include <termios.h>#include <assert.h>/* * Basic 16552 driver */struct uart_data{  int ioMode;  int hwFlow;  unsigned int  ier;  unsigned long baud;  unsigned long databits;  unsigned long parity;  unsigned long stopbits;};static struct uart_data uart_data[2];/*  * Macros to read/write register of uart, if configuration is * different just rewrite these macros */ static inline unsigned charuread(int uart, unsigned int reg){  register unsigned char val;  if (uart == 0) {    inport_byte(COM1_BASE_IO+reg, val);  } else {    inport_byte(COM2_BASE_IO+reg, val);  }  return val;}static inline void      uwrite(int uart, int reg, unsigned int val){  if (uart == 0) {    outport_byte(COM1_BASE_IO+reg, val);  } else {    outport_byte(COM2_BASE_IO+reg, val);  }}#ifdef UARTDEBUG    static voiduartError(int uart){  unsigned char uartStatus, dummy;  uartStatus = uread(uart, LSR);  dummy = uread(uart, RBR);  if (uartStatus & OE)    printk("********* Over run Error **********\n");  if (uartStatus & PE)    printk("********* Parity Error   **********\n");  if (uartStatus & FE)    printk("********* Framing Error  **********\n");  if (uartStatus & BI)    printk("********* Parity Error   **********\n");  if (uartStatus & ERFIFO)    printk("********* Error receive Fifo **********\n");}#elseinline void uartError(int uart){  unsigned char uartStatus;    uartStatus = uread(uart, LSR);  uartStatus = uread(uart, RBR);}#endif/*  * Uart initialization, it is hardcoded to 8 bit, no parity, * one stop bit, FIFO, things to be changed * are baud rate and nad hw flow control, * and longest rx fifo setting */voidBSP_uart_init(  int uart,  unsigned long baud,  unsigned long databits,  unsigned long parity,  unsigned long stopbits,  int hwFlow){  unsigned char tmp;    /* Sanity check */  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);    switch(baud)    {    case 50:    case 75:    case 110:    case 134:    case 300:    case 600:    case 1200:    case 2400:    case 9600:    case 19200:    case 38400:    case 57600:    case 115200:      break;    default:      assert(0);      return;    }    /* Set DLAB bit to 1 */  uwrite(uart, LCR, DLAB);    /* Set baud rate */  uwrite(uart, DLL,  (BSPBaseBaud/baud) & 0xff);   uwrite(uart, DLM,  ((BSPBaseBaud/baud) >> 8) & 0xff);   /* 8-bit, no parity , 1 stop */  uwrite(uart, LCR, databits | parity | stopbits);    /* Set DTR, RTS and OUT2 high */  uwrite(uart, MCR, DTR | RTS | OUT_2);  /* Enable FIFO */  uwrite(uart, FCR, FIFO_EN | XMIT_RESET | RCV_RESET | RECEIVE_FIFO_TRIGGER12);   /* Disable Interrupts */  uwrite(uart, IER, 0);  /* Read status to clear them */  tmp = uread(uart, LSR);  tmp = uread(uart, RBR);  tmp = uread(uart, MSR);  /* Remember state */  uart_data[uart].baud       = baud;  uart_data[uart].databits   = databits;  uart_data[uart].parity     = parity;  uart_data[uart].stopbits   = stopbits;  uart_data[uart].hwFlow     = hwFlow;  return;}/*  * Set baud */voidBSP_uart_set_baud(   int uart,  unsigned long baud){  /* Sanity check */  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);  BSP_uart_set_attributes( uart, baud, uart_data[uart].databits,     uart_data[uart].parity, uart_data[uart].stopbits );}/* *  Set all attributes */voidBSP_uart_set_attributes(  int uart,  unsigned long baud,  unsigned long databits,  unsigned long parity,  unsigned long stopbits){  unsigned char mcr, ier;  /* Sanity check */  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);    /*    * This function may be called whenever TERMIOS parameters   * are changed, so we have to make sure that baud change is    * indeed required   */  if( (baud     == uart_data[uart].baud)     &&      (databits == uart_data[uart].databits) &&      (parity   == uart_data[uart].parity)   &&      (stopbits == uart_data[uart].stopbits) )    {      return;    }  mcr = uread(uart, MCR);  ier = uread(uart, IER);  BSP_uart_init(uart, baud, databits, parity, stopbits, uart_data[uart].hwFlow);  uwrite(uart, MCR, mcr);  uwrite(uart, IER, ier);    return;}/* * Enable/disable interrupts  */void BSP_uart_intr_ctrl(int uart, int cmd){  int iStatus = (int)INTERRUPT_DISABLE;  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);  switch(cmd)    {    case BSP_UART_INTR_CTRL_ENABLE:      iStatus |= (RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE | TRANSMIT_ENABLE);      if ( uart_data[uart].hwFlow ) {        iStatus |= MODEM_ENABLE;      }      break;    case BSP_UART_INTR_CTRL_TERMIOS:      iStatus |= (RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE);      if ( uart_data[uart].hwFlow ) {        iStatus |= MODEM_ENABLE;      }      break;    case BSP_UART_INTR_CTRL_GDB:      iStatus |= RECEIVE_ENABLE;      break;    }  uart_data[uart].ier = iStatus;  uwrite(uart, IER, iStatus);   return;}voidBSP_uart_throttle(int uart){  unsigned int mcr;    assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);  if(!uart_data[uart].hwFlow)    {      /* Should not happen */      assert(0);      return;    }  mcr = uread (uart, MCR);  /* RTS down */  mcr &= ~RTS;  uwrite(uart, MCR, mcr);  return;}voidBSP_uart_unthrottle(int uart){  unsigned int mcr;  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);  if(!uart_data[uart].hwFlow)    {      /* Should not happen */      assert(0);      return;    }  mcr = uread (uart, MCR);  /* RTS up */  mcr |= RTS;  uwrite(uart, MCR, mcr);  return;}/* * Status function, -1 if error * detected, 0 if no received chars available, * 1 if received char available, 2 if break * is detected, it will eat break and error  * chars. It ignores overruns - we cannot do  * anything about - it execpt count statistics * and we are not counting it. */int BSP_uart_polled_status(int uart){  unsigned char val;  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);  val = uread(uart, LSR);  if(val & BI)    {      /* BREAK found, eat character */      uread(uart, RBR);      return BSP_UART_STATUS_BREAK;    }  if((val & (DR | OE | FE)) ==  1)    {      /* No error, character present */       return BSP_UART_STATUS_CHAR;    }  if((val & (DR | OE | FE)) == 0)    {      /* Nothing */      return BSP_UART_STATUS_NOCHAR;    }  /*    * Framing or parity error   * eat character   */  uread(uart, RBR);   return BSP_UART_STATUS_ERROR;}/* * Polled mode write function */void BSP_uart_polled_write(int uart, int val){  unsigned char val1;    /* Sanity check */  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);    for(;;)    {      if((val1=uread(uart, LSR)) & THRE)	{	  break;	}    }  if(uart_data[uart].hwFlow)    {      for(;;)	{	  if(uread(uart, MSR) & CTS)	    {	      break;	    }	}    }  uwrite(uart, THR, val & 0xff);        /*   * Wait for character to be transmitted.   * This ensures that printk and printf play nicely together   * when using the same serial port.   * Yes, there's a performance hit here, but if we're doing   * polled writes to a serial port we're probably not that   * interested in efficiency anyway.....   */  for(;;)    {      if((val1=uread(uart, LSR)) & THRE)      {      break;      }    }  return;}voidBSP_output_char_via_serial(int val){  BSP_uart_polled_write(BSPConsolePort, val);  if (val == '\n') BSP_uart_polled_write(BSPConsolePort,'\r');}/*  * Polled mode read function */int BSP_uart_polled_read(int uart){  unsigned char val;  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);    for(;;)    {      if(uread(uart, LSR) & DR)	{	  break;	}    }    val = uread(uart, RBR);  return (int)(val & 0xff);}unsigned BSP_poll_char_via_serial(){	return BSP_uart_polled_read(BSPConsolePort);}/* ================ Termios support  =================*/static volatile int  termios_stopped_com1        = 0;static volatile int  termios_tx_active_com1      = 0;static void*	     termios_ttyp_com1           = NULL;static char          termios_tx_hold_com1        = 0;static volatile char termios_tx_hold_valid_com1  = 0;static volatile int  termios_stopped_com2        = 0;static volatile int  termios_tx_active_com2      = 0;static void*	     termios_ttyp_com2           = NULL;static char          termios_tx_hold_com2        = 0;static volatile char termios_tx_hold_valid_com2  = 0;static void ( *driver_input_handler_com1 )( void *,  char *, int ) = 0;static void ( *driver_input_handler_com2 )( void *,  char *, int ) = 0;/* * This routine sets the handler to handle the characters received * from the serial port. */void uart_set_driver_handler( int port, void ( *handler )( void *,  char *, int ) ){  switch( port )  {    case BSP_UART_COM1:     driver_input_handler_com1 = handler;     break;    case BSP_UART_COM2:     driver_input_handler_com2 = handler;     break;  }}/* * Set channel parameters  */voidBSP_uart_termios_set(int uart, void *ttyp){  struct rtems_termios_tty *p = (struct rtems_termios_tty *)ttyp;  unsigned char val;  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);    if(uart == BSP_UART_COM1)    {      uart_data[uart].ioMode = p->device.outputUsesInterrupts;      if(uart_data[uart].hwFlow)	{	  val = uread(uart, MSR);	  termios_stopped_com1   = (val & CTS) ? 0 : 1;	}      else	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -