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

📄 console-generic.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  General Serial I/O functions. * *  This file contains the functions for performing serial I/O. *  The actual system calls (console_*) should be in the BSP part *  of the source tree. That way different BSPs can use whichever *  SMCs and SCCs they want. Originally, all the stuff was in *  this file, and it caused problems with one BSP using SCC2 *  as /dev/console, others using SMC1 for /dev/console, etc. * *  On-chip resources used: *   resource   minor                note *    SMC1       0 *    SMC2       1 *    SCC1       2                   N/A. Hardwired as ethernet port *    SCC2       3 *    SCC3       4 *    SCC4       5 *    BRG1 *    BRG2 *    BRG3 *    BRG4 *  Author: Jay Monkman (jmonkman@frasca.com) *  Copyright (C) 1998 by Frasca International, Inc. * *  Derived from c/src/lib/libbsp/m68k/gen360/console/console.c written by: *    W. Eric Norum *    Saskatchewan Accelerator Laboratory *    University of Saskatchewan *    Saskatoon, Saskatchewan, CANADA *    eric@skatter.usask.ca * *  COPYRIGHT (c) 1989-1998. *  On-Line Applications Research Corporation (OAR). * *  Modifications by Darlene Stewart <Darlene.Stewart@iit.nrc.ca> *  and Charles-Antoine Gauthier <charles.gauthier@iit.nrc.ca> *  Copyright (c) 1999, National Research Council of Canada * *  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: console-generic.c,v 1.14.2.1 2003/09/04 18:45:53 joel Exp $ */#include <rtems.h>#include <rtems/libio.h>#include <mpc8xx.h>#include <mpc8xx/console.h>#include <mpc8xx/cpm.h>#include <stdlib.h>#include <unistd.h>#include <termios.h>#include <bsp/irq.h>#include <rtems/bspIo.h>   /* for printk */int BSP_irq_enabled_at_cpm(const rtems_irq_symbolic_name irqLine);extern rtems_cpu_table Cpu_table;/* BSP supplied routine */extern int mbx8xx_console_get_configuration();/* * Interrupt-driven input buffer */#define RXBUFSIZE       16/* *  I/O buffers and pointers to buffer descriptors. *  Currently, single buffered input is done. This will work only *  if the Rx interrupts are serviced quickly. * *  TODO: Add a least double buffering for safety. */static volatile char rxBuf[NUM_PORTS][RXBUFSIZE];static volatile char txBuf[NUM_PORTS];/* SCC/SMC buffer descriptors */static volatile m8xxBufferDescriptor_t *RxBd[NUM_PORTS], *TxBd[NUM_PORTS];/* Used to track the usage of the baud rate generators */static unsigned long brg_spd[4];static char  brg_used[4];/* Used to track termios private data for callbacks */struct rtems_termios_tty *ttyp[NUM_PORTS];/* * Device-specific routines */static int m8xx_get_brg_cd(int);static unsigned char m8xx_get_brg_clk(int);void m8xx_console_reserve_resources(rtems_configuration_table *);static int m8xx_smc_set_attributes(int, const struct termios*);static int m8xx_scc_set_attributes(int, const struct termios*);static void m8xx_smc1_interrupt_handler(void);static void m8xx_smc2_interrupt_handler(void);static void m8xx_scc2_interrupt_handler(void);#if defined(mpc860)static void m8xx_scc3_interrupt_handler(void);static void m8xx_scc4_interrupt_handler(void);#endif/* * Compute baud-rate-generator configuration register value */static intm8xx_get_brg_cd (int baud){  int divisor;  int div16 = 0;  divisor = ((Cpu_table.clock_speed / 16) + (baud / 2)) / baud;  if (divisor > 4096) {    div16 = 1;    divisor = (divisor + 8) / 16;  }  return M8xx_BRG_EN | M8xx_BRG_EXTC_BRGCLK |    ((divisor - 1) << 1) | div16;}/*  *  This function will fail if more that 4 baud rates have been selected *  at any time since the OS started. It needs to be fixed. FIXME */static unsignedchar m8xx_get_brg_clk(int baud){  int i;  /* first try to find a BRG that is already at the right speed */  for ( i = 0; i < 4; i++ ) {    if ( brg_spd[i] == baud ) {      break;    }  }  if ( i == 4 ) { /* I guess we didn't find one */    for ( i = 0; i < 4; i++ ) {      if ( brg_used[i] == 0 ) {        break;      }    }  }  if (i != 4) {    brg_used[i]++;    brg_spd[i]=baud;    switch (i) {    case 0:      m8xx.brgc1 = M8xx_BRG_RST;      m8xx.brgc1 = m8xx_get_brg_cd(baud);      break;    case 1:      m8xx.brgc2 = M8xx_BRG_RST;      m8xx.brgc2 = m8xx_get_brg_cd(baud);      break;    case 2:      m8xx.brgc3 = M8xx_BRG_RST;      m8xx.brgc3 = m8xx_get_brg_cd(baud);      break;    case 3:      m8xx.brgc4 = M8xx_BRG_RST;      m8xx.brgc4 = m8xx_get_brg_cd(baud);      break;    }    return i;  }  else    return 0xff;}/* * Hardware-dependent portion of tcsetattr(). */static intm8xx_smc_set_attributes (int minor, const struct termios *t){  int baud, brg=0, csize=0, ssize, psize;  rtems_unsigned16 clen=0, cstopb, parenb, parodd, cread;   /* Baud rate */  switch (t->c_cflag & CBAUD) {  default:      baud = -1;      break;  case B50:     baud = 50;      break;  case B75:     baud = 75;      break;  case B110:    baud = 110;     break;  case B134:    baud = 134;     break;  case B150:    baud = 150;     break;  case B200:    baud = 200;     break;  case B300:    baud = 300;     break;  case B600:    baud = 600;     break;  case B1200:   baud = 1200;    break;  case B1800:   baud = 1800;    break;  case B2400:   baud = 2400;    break;  case B4800:   baud = 4800;    break;  case B9600:   baud = 9600;    break;  case B19200:  baud = 19200;   break;  case B38400:  baud = 38400;   break;  case B57600:  baud = 57600;   break;  case B115200: baud = 115200;  break;  case B230400: baud = 230400;  break;  case B460800: baud = 460800;  break;  }  if (baud > 0)    brg = m8xx_get_brg_clk(baud);     /* 4 BRGs, 6 serial ports - hopefully */                                      /*  at least 2 ports will be the same */   /* Number of data bits */  switch ( t->c_cflag & CSIZE ) {    case CS5:     csize = 5;       break;    case CS6:     csize = 6;       break;    case CS7:     csize = 7;       break;    case CS8:     csize = 8;       break;  }  /* Stop bits */  if ( t->c_cflag & CSTOPB ) {    cstopb = 0x0400;              /* Two stop bits */    ssize  = 2;  } else {    cstopb = 0x0000;              /* One stop bit */    ssize  = 1;  }  /* Parity */  if ( t->c_cflag & PARENB ) {    parenb = 0x0200;              /* Parity enabled on Tx and Rx */    psize  = 1;  } else {    parenb = 0x0000;              /* No parity on Tx and Rx */    psize  = 0;  }    if ( t->c_cflag & PARODD )    parodd = 0x0000;              /* Odd parity */  else    parodd = 0x0100;  /*    * Character Length = start + data + parity + stop - 1   */   switch ( 1 + csize + psize + ssize - 1 ) {    case 6:     clen = 0x3000;       break;    case 7:     clen = 0x3800;       break;    case 8:     clen = 0x4000;       break;    case 9:     clen = 0x4800;       break;    case 10:    clen = 0x5000;       break;    case 11:    clen = 0x5800;       break;  }  if ( t->c_cflag & CREAD )    cread = 0x0023;		/* UART normal operation, enable Rx and Tx */  else    cread = 0x0021;		/* UART normal operation, enable Tx */      /* Write the SIMODE/SMCMR registers */  switch (minor) {    case SMC1_MINOR:      m8xx.simode = ( (m8xx.simode & 0xffff8fff) | (brg << 12) );      m8xx.smc1.smcmr = clen | cstopb | parenb | parodd | cread;      break;    case SMC2_MINOR:      m8xx.simode = ( (m8xx.simode & 0x8fffffff) | (brg << 28) );      m8xx.smc2.smcmr = clen | cstopb | parenb | parodd | cread;      break;  }  return 0;}static intm8xx_scc_set_attributes (int minor, const struct termios *t){  int baud, brg=0;  rtems_unsigned16 csize=0, cstopb, parenb, parodd;  /* Baud rate */  switch (t->c_cflag & CBAUD) {  default:      baud = -1;      break;  case B50:     baud = 50;      break;  case B75:     baud = 75;      break;  case B110:    baud = 110;     break;  case B134:    baud = 134;     break;  case B150:    baud = 150;     break;  case B200:    baud = 200;     break;  case B300:    baud = 300;     break;  case B600:    baud = 600;     break;  case B1200:   baud = 1200;    break;  case B1800:   baud = 1800;    break;  case B2400:   baud = 2400;    break;  case B4800:   baud = 4800;    break;  case B9600:   baud = 9600;    break;  case B19200:  baud = 19200;   break;  case B38400:  baud = 38400;   break;  case B57600:  baud = 57600;   break;  case B115200: baud = 115200;  break;  case B230400: baud = 230400;  break;  case B460800: baud = 460800;  break;  }  if (baud > 0)    brg = m8xx_get_brg_clk(baud);     /* 4 BRGs, 5 serial ports - hopefully */                                      /*  at least 2 ports will be the same */                                      /*  Write the SICR register below */      /* Number of data bits */  switch ( t->c_cflag & CSIZE ) {    case CS5:     csize = 0x0000;       break;    case CS6:     csize = 0x1000;       break;    case CS7:     csize = 0x2000;       break;    case CS8:     csize = 0x3000;       break;  }  /* Stop bits */  if ( t->c_cflag & CSTOPB )    cstopb = 0x4000;              /* Two stop bits */  else    cstopb = 0x0000;              /* One stop bit */      /* Parity */  if ( t->c_cflag & PARENB )    parenb = 0x0010;              /* Parity enabled on Tx and Rx */  else    parenb = 0x0000;              /* No parity on Tx and Rx */      if ( t->c_cflag & PARODD )    parodd = 0x0000;              /* Odd parity */  else    parodd = 0x000a;  /* Write the SICR/PSMR Registers */  switch (minor) {    case SCC2_MINOR:      m8xx.sicr = ( (m8xx.sicr & 0xffffc0ff) | (brg << 11) | (brg << 8) );      m8xx.scc2.psmr = ( (cstopb | csize | parenb | parodd) | (m8xx.scc2.psmr & 0x8fe0) );      break;  #if defined(mpc860)    case SCC3_MINOR:      m8xx.sicr = ( (m8xx.sicr & 0xffc0ffff) | (brg << 19) | (brg << 16) );      m8xx.scc3.psmr = ( (cstopb | csize | parenb | parodd) | (m8xx.scc3.psmr & 0x8fe0) );      break;    case SCC4_MINOR:      m8xx.sicr = ( (m8xx.sicr & 0xc0ffffff) | (brg << 27) | (brg << 24) );      m8xx.scc4.psmr = ( (cstopb | csize | parenb | parodd) | (m8xx.scc4.psmr & 0x8fe0) );      break;  #endif  }    return 0;}int m8xx_uart_setAttributes(  int minor,  const struct termios *t){  /*   * Check that port number is valid   */  if ( (minor < SMC1_MINOR) || (minor > NUM_PORTS-1) )     return 0;

⌨️ 快捷键说明

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