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

📄 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                    *    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 * *  Modifications by Andy Dachs <a.dachs@sstl.co.uk> to add MPC8260 *  support. *  Copyright (c) 2001, Surrey Satellite Technology Ltd *    SCC1 and SSC2 are used on MPC8260ADS board *    SMCs are unused * *  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.3.2.1 2003/09/04 18:45:53 joel Exp $ */#include <rtems.h>#include <rtems/libio.h>#include <mpc8260.h>#include <mpc8260/console.h>#include <mpc8260/cpm.h>#include <stdlib.h>#include <unistd.h>#include <termios.h>#include <bsp/irq.h>#include <rtems/bspIo.h>   /* for printk *//* 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 m8260BufferDescriptor_t *RxBd[NUM_PORTS], *TxBd[NUM_PORTS];/* Used to track termios private data for callbacks */struct rtems_termios_tty *ttyp[NUM_PORTS];#if 0/* Used to record previous ISR */static rtems_isr_entry old_handler[NUM_PORTS];#endif/* * Device-specific routines */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 rtems_isr m8xx_smc1_interrupt_handler();static rtems_isr m8xx_smc2_interrupt_handler();static rtems_isr m8xx_scc1_interrupt_handler();static rtems_isr m8xx_scc2_interrupt_handler();static rtems_isr m8xx_scc3_interrupt_handler();static rtems_isr m8xx_scc4_interrupt_handler();/* * 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) {   switch( minor ) {      case SMC1_MINOR:        /* SMC1 can only choose between BRG1 and 7 */        brg = m8xx_get_brg( M8260_SMC1_BRGS, baud*16 ) + 1; 	m8260.cmxsmr &= ~0x30;	m8260.cmxsmr |= (brg==1? 0x00: 0x10 );        break;      case SMC2_MINOR:        /* SMC2 can only choose between BRG2 and 8 */	brg = m8xx_get_brg(  M8260_SMC2_BRGS, baud*16 ) + 1;	 	m8260.cmxsmr &= ~0x30;	m8260.cmxsmr |= (brg==2? 0x00: 0x01 );        break;    }  }   /* 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) );*/      m8260.smc1.smcmr = clen | cstopb | parenb | parodd | cread;      break;    case SMC2_MINOR:      /* CHECK THIS *//*      m8xx.simode = ( (m8xx.simode & 0x8fffffff) | (brg << 28) );*/      m8260.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( M8260_SCC_BRGS, baud*16 );	    m8260.cmxscr &= ~(0xFF000000 >> (8*(minor-SCC1_MINOR)) );    m8260.cmxscr |= ((brg<<(3+8*(3-(minor-SCC1_MINOR)))) &		     (brg<<(8*(3-(minor-SCC1_MINOR)))));  }  /* 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 SCC1_MINOR:/*      m8xx.sicr = ( (m8xx.sicr & 0xffffc0ff) | (brg << 11) | (brg << 8) );*/      m8260.scc1.psmr = ( (cstopb | csize | parenb | parodd) | (m8260.scc1.psmr & 0x8fe0) );      break;    case SCC2_MINOR:/*      m8xx.sicr = ( (m8xx.sicr & 0xffffc0ff) | (brg << 11) | (brg << 8) );*/      m8260.scc2.psmr = ( (cstopb | csize | parenb | parodd) | (m8260.scc2.psmr & 0x8fe0) );      break;    case SCC3_MINOR:/*      m8xx.sicr = ( (m8xx.sicr & 0xffc0ffff) | (brg << 19) | (brg << 16) );*/      m8260.scc3.psmr = ( (cstopb | csize | parenb | parodd) | (m8260.scc3.psmr & 0x8fe0) );      break;    case SCC4_MINOR:/*      m8xx.sicr = ( (m8xx.sicr & 0xc0ffffff) | (brg << 27) | (brg << 24) );*/      m8260.scc4.psmr = ( (cstopb | csize | parenb | parodd) | (m8260.scc4.psmr & 0x8fe0) );      break;  }  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;  switch (minor) {    case SMC1_MINOR:    case SMC2_MINOR:      return m8xx_smc_set_attributes( minor, t );    case SCC1_MINOR:    case SCC2_MINOR:    case SCC3_MINOR:    case SCC4_MINOR:      return m8xx_scc_set_attributes( minor, t );  }  return 0;}/* * Interrupt handlers */static voidm8xx_scc1_interrupt_handler (){  int nb_overflow;  /*   * Buffer received?   */  if ((m8260.scc1.sccm & M8260_SCCE_RX) && (m8260.scc1.scce & M8260_SCCE_RX)) {    m8260.scc1.scce = M8260_SCCE_RX;    /* Clear the event */    /* Check that the buffer is ours */    if ((RxBd[SCC1_MINOR]->status & M8260_BD_EMPTY) == 0) {      rtems_cache_invalidate_multiple_data_lines(        (const void *) RxBd[SCC1_MINOR]->buffer,        RxBd[SCC1_MINOR]->length );      nb_overflow = rtems_termios_enqueue_raw_characters(        (void *)ttyp[SCC1_MINOR],        (char *)RxBd[SCC1_MINOR]->buffer,        (int)RxBd[SCC1_MINOR]->length );      RxBd[SCC1_MINOR]->status = M8260_BD_EMPTY | M8260_BD_WRAP |                                 M8260_BD_INTERRUPT;    }  }  /*   * Buffer transmitted?   */

⌨️ 快捷键说明

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