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

📄 mg5uart.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  This file contains the termios TTY driver for the UART found *  on the Synova Mongoose-V. * *  COPYRIGHT (c) 1989-2001. *  On-Line Applications Research Corporation (OAR). * *  The license and distribution terms for this file may be *  found in the file LICENSE in this distribution or at *  http://www.rtems.com/license/LICENSE. * *  $Id: mg5uart.c,v 1.4.6.1 2003/09/04 18:45:49 joel Exp $ */#include <rtems.h>#include <rtems/libio.h>#include <stdlib.h>#include <libchip/serial.h>#include <libchip/mg5uart.h>#include <libchip/sersupp.h>#include <libcpu/mongoose-v.h>extern void set_vector( rtems_isr_entry, rtems_vector_number, int );/* *  Indices of registers *//* *  Per chip context control */typedef struct _mg5uart_context{  int            mate;} mg5uart_context;/* *  Define MG5UART_STATIC to nothing while debugging so the entry points *  will show up in the symbol table. */#define MG5UART_STATIC/* #define MG5UART_STATIC static */#define MG5UART_SETREG( _base, _register, _value ) \        MONGOOSEV_WRITE_REGISTER( _base, _register, _value )#define MG5UART_GETREG( _base, _register ) \        MONGOOSEV_READ_REGISTER( _base, _register )/* *  Console Device Driver Support Functions */MG5UART_STATIC int mg5uart_baud_rate(  int           minor,  int           baud,  unsigned int *code);MG5UART_STATIC void mg5uart_enable_interrupts(  int minor,  int mask);/* *  mg5uart_set_attributes * *  This function sets the UART channel to reflect the requested termios *  port settings. */MG5UART_STATIC int mg5uart_set_attributes(  int minor,  const struct termios *t){  unsigned32             pMG5UART_port;  unsigned32             pMG5UART;  unsigned32             cmd, cmdSave;  unsigned32             baudcmd;  unsigned32             shift;  rtems_interrupt_level  Irql;  pMG5UART      = Console_Port_Tbl[minor].ulCtrlPort1;  pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2;  /*   *  Set the baud rate   */  if (mg5uart_baud_rate( minor, t->c_cflag, &baudcmd ) == -1)    return -1;  /*   *  Base settings   */  /*   *  Base settings   */  cmd = MONGOOSEV_UART_CMD_RX_ENABLE | MONGOOSEV_UART_CMD_TX_ENABLE;  /*   *  Parity   */  if (t->c_cflag & PARENB) {    cmd |= MONGOOSEV_UART_CMD_PARITY_ENABLE;    if (t->c_cflag & PARODD)      cmd |= MONGOOSEV_UART_CMD_PARITY_ODD;    else      cmd |= MONGOOSEV_UART_CMD_PARITY_EVEN;  } else {    cmd |= MONGOOSEV_UART_CMD_PARITY_DISABLE;  }  /*   *  Character Size   */  if (t->c_cflag & CSIZE) {    switch (t->c_cflag & CSIZE) {      case CS5:      case CS6:      case CS7:        return -1;        break;      case CS8:        /* Mongoose-V only supports CS8 */        break;    }  } /* else default to CS8 */  /*   *  Stop Bits   */#if 0  if (t->c_cflag & CSTOPB) {    /* 2 stop bits not supported by Mongoose-V uart */    return -1;  }#endif  /*   *  XXX what about CTS/RTS   */  /* XXX */  /*   *  Now write the registers   */  if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )    shift = MONGOOSEV_UART0_CMD_SHIFT;  else    shift = MONGOOSEV_UART1_CMD_SHIFT;  rtems_interrupt_disable(Irql);  cmdSave = MG5UART_GETREG( pMG5UART, MG5UART_COMMAND_REGISTER );  MG5UART_SETREG( pMG5UART, 		  MG5UART_COMMAND_REGISTER, 		  (cmdSave & ~(MONGOOSEV_UART_ALL_STATUS_BITS << shift)) | (cmd << shift) );  MG5UART_SETREG( pMG5UART_port, MG5UART_BAUD_RATE, baudcmd );  rtems_interrupt_enable(Irql);  return 0;}/* *  mg5uart_initialize_context * *  This function sets the default values of the per port context structure. */MG5UART_STATIC void mg5uart_initialize_context(  int               minor,  mg5uart_context  *pmg5uartContext){  int          port;  unsigned int pMG5UART;  unsigned int pMG5UART_port;  pMG5UART      = Console_Port_Tbl[minor].ulCtrlPort1;  pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2;  pmg5uartContext->mate = -1;  for (port=0 ; port<Console_Port_Count ; port++ ) {    if ( Console_Port_Tbl[port].ulCtrlPort1 == pMG5UART &&         Console_Port_Tbl[port].ulCtrlPort2 != pMG5UART_port ) {      pmg5uartContext->mate = port;      break;    }  }}/* *  mg5uart_init * *  This function initializes the DUART to a quiecsent state. */MG5UART_STATIC void mg5uart_init(int minor){  unsigned32            pMG5UART_port;  unsigned32            pMG5UART;  unsigned32		cmdSave;  unsigned32		shift;  mg5uart_context        *pmg5uartContext;  pmg5uartContext = (mg5uart_context *) malloc(sizeof(mg5uart_context));  Console_Port_Data[minor].pDeviceContext = (void *)pmg5uartContext;  mg5uart_initialize_context( minor, pmg5uartContext );  pMG5UART      = Console_Port_Tbl[minor].ulCtrlPort1;  pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2;  if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )     shift = MONGOOSEV_UART0_CMD_SHIFT;  else     shift = MONGOOSEV_UART1_CMD_SHIFT;  /*   *  Disable the uart and leave this port disabled.   */  cmdSave = MG5UART_GETREG(pMG5UART, MG5UART_COMMAND_REGISTER) & ~(MONGOOSEV_UART_ALL_STATUS_BITS << shift);  MG5UART_SETREG( pMG5UART, MG5UART_COMMAND_REGISTER, cmdSave );  /*   *  Disable interrupts on RX and TX for this port   */  mg5uart_enable_interrupts( minor, MG5UART_DISABLE_ALL );}/* *  mg5uart_open * *  This function opens a port for communication. * *  Default state is 9600 baud, 8 bits, No parity, and 1 stop bit. */MG5UART_STATIC int mg5uart_open(  int      major,  int      minor,  void    *arg){  unsigned32    pMG5UART;  unsigned32    pMG5UART_port;  unsigned32	vector;  unsigned32    cmd, cmdSave;  unsigned32    baudcmd;  unsigned32    shift;  rtems_interrupt_level  Irql;  pMG5UART      = Console_Port_Tbl[minor].ulCtrlPort1;  pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2;  vector        = Console_Port_Tbl[minor].ulIntVector;  if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )    shift = MONGOOSEV_UART0_CMD_SHIFT;  else    shift = MONGOOSEV_UART1_CMD_SHIFT;  /* XXX default baud rate could be from configuration table */  (void) mg5uart_baud_rate( minor, B19200, &baudcmd );  /*   *  Set the DUART channel to a default useable state   *  B19200, 8Nx since there is no stop bit control.   */  cmd = MONGOOSEV_UART_CMD_TX_ENABLE | MONGOOSEV_UART_CMD_RX_ENABLE;  rtems_interrupt_disable(Irql);  cmdSave = MG5UART_GETREG( pMG5UART, MG5UART_COMMAND_REGISTER );  MG5UART_SETREG( pMG5UART_port, MG5UART_BAUD_RATE, baudcmd );  MG5UART_SETREG( pMG5UART, 		  MG5UART_COMMAND_REGISTER, 		  cmd = (cmdSave & ~(MONGOOSEV_UART_ALL_STATUS_BITS << shift)) | (cmd << shift) );  rtems_interrupt_enable(Irql);  return RTEMS_SUCCESSFUL;}/* *  mg5uart_close * *  This function shuts down the requested port. */MG5UART_STATIC int mg5uart_close(  int      major,  int      minor,  void    *arg){  unsigned32    pMG5UART;  unsigned32    pMG5UART_port;  unsigned32	cmd, cmdSave;  unsigned32    shift;  rtems_interrupt_level  Irql;  pMG5UART      = Console_Port_Tbl[minor].ulCtrlPort1;  pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2;  /*   *  Disable interrupts from this channel and then disable it totally.   */  /* XXX interrupts */  cmd = MONGOOSEV_UART_CMD_TX_DISABLE | MONGOOSEV_UART_CMD_RX_DISABLE;  if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )    shift = MONGOOSEV_UART0_CMD_SHIFT;  else    shift = MONGOOSEV_UART1_CMD_SHIFT;  rtems_interrupt_disable(Irql);  cmdSave = MG5UART_GETREG( pMG5UART, MG5UART_COMMAND_REGISTER );  MG5UART_SETREG( pMG5UART, 		  MG5UART_COMMAND_REGISTER,  		  (cmdSave & ~(MONGOOSEV_UART_ALL_STATUS_BITS << shift)) | (cmd << shift) );  rtems_interrupt_enable(Irql);  return(RTEMS_SUCCESSFUL);}/* *  mg5uart_write_polled * *  This routine polls out the requested character. */MG5UART_STATIC void mg5uart_write_polled(  int   minor,  char  c){  unsigned32              pMG5UART;  unsigned32              pMG5UART_port;  unsigned32              status;  int                     shift;  int                     timeout;  pMG5UART      = Console_Port_Tbl[minor].ulCtrlPort1;  pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2;  if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )    shift = MONGOOSEV_UART0_IRQ_SHIFT;  else    shift = MONGOOSEV_UART1_IRQ_SHIFT;  /*   * wait for transmitter holding register to be empty   */  timeout = 2000;  while( --timeout )   {    status = MG5UART_GETREG(pMG5UART, MG5UART_STATUS_REGISTER) >> shift;    /*    if ( (status & (MONGOOSEV_UART_TX_READY | MONGOOSEV_UART_TX_EMPTY)) ==            (MONGOOSEV_UART_TX_READY | MONGOOSEV_UART_TX_EMPTY) )      break;    */    if( (status & (MONGOOSEV_UART_TX_READY | MONGOOSEV_UART_TX_EMPTY)) )       break;    /*     * Yield while we wait     */#if 0     if(_System_state_Is_up(_System_state_Get()))      {       rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);     }#endif  }  /*   * transmit character   */  MG5UART_SETREG(pMG5UART_port, MG5UART_TX_BUFFER, c);}/* *  mg5uart_isr_XXX * *  This is the single interrupt entry point which parcels interrupts *  out to the handlers for specific sources and makes sure that the *  shared handler gets the right arguments. * *  NOTE: Yes .. this is ugly but it provides 5 interrupt source

⌨️ 快捷键说明

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