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

📄 uart.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
	  termios_stopped_com1 = 0;	}      termios_tx_active_com1      = 0;      termios_ttyp_com1           = ttyp;      termios_tx_hold_com1        = 0;       termios_tx_hold_valid_com1  = 0;    }  else    {      uart_data[uart].ioMode = p->device.outputUsesInterrupts;      if(uart_data[uart].hwFlow)	{	  val = uread(uart, MSR);	  termios_stopped_com2   = (val & CTS) ? 0 : 1;	}      else	{	  termios_stopped_com2 = 0;	}      termios_tx_active_com2      = 0;      termios_ttyp_com2           = ttyp;      termios_tx_hold_com2        = 0;       termios_tx_hold_valid_com2  = 0;    }  return;}intBSP_uart_termios_read_com1(int uart){  int     off = (int)0;  char    buf[40];  /* read bytes */  while (( off < sizeof(buf) ) && ( uread(BSP_UART_COM1, LSR) & DR )) {    buf[off++] = uread(BSP_UART_COM1, RBR);  }  /* write out data */  if ( off > 0 ) {    rtems_termios_enqueue_raw_characters(termios_ttyp_com1, buf, off);  }  /* enable receive interrupts */  uart_data[BSP_UART_COM1].ier |= (RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE);  uwrite(BSP_UART_COM1, IER, uart_data[BSP_UART_COM1].ier);  return ( EOF );}intBSP_uart_termios_read_com2(int uart){  int     off = (int)0;  char    buf[40];  /* read current byte */  while (( off < sizeof(buf) ) && ( uread(BSP_UART_COM2, LSR) & DR )) {    buf[off++] = uread(BSP_UART_COM2, RBR);  }  /* write out data */  if ( off > 0 ) {    rtems_termios_enqueue_raw_characters(termios_ttyp_com2, buf, off);  }  /* enable receive interrupts */  uart_data[BSP_UART_COM2].ier |= (RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE);  uwrite(BSP_UART_COM2, IER, uart_data[BSP_UART_COM2].ier);  return ( EOF );}intBSP_uart_termios_write_com1(int minor, const char *buf, int len){  assert(buf != NULL);  if(len <= 0)    {      return 0;    }  /* If there TX buffer is busy - something is royally screwed up */  assert((uread(BSP_UART_COM1, LSR) & THRE) != 0);  if(termios_stopped_com1)    {      /* CTS low */      termios_tx_hold_com1       = *buf;      termios_tx_hold_valid_com1 = 1;      return 0;    }  /* Write character */  uwrite(BSP_UART_COM1, THR, *buf & 0xff);  /* Enable interrupts if necessary */  if ( !termios_tx_active_com1 ) {    termios_tx_active_com1 = 1;    uart_data[BSP_UART_COM1].ier |= TRANSMIT_ENABLE;    uwrite(BSP_UART_COM1, IER, uart_data[BSP_UART_COM1].ier);  }  return 0;}intBSP_uart_termios_write_com2(int minor, const char *buf, int len){  assert(buf != NULL);  if(len <= 0)    {      return 0;    }  /* If there TX buffer is busy - something is royally screwed up */  assert((uread(BSP_UART_COM2, LSR) & THRE) != 0);  if(termios_stopped_com2)    {      /* CTS low */      termios_tx_hold_com2       = *buf;      termios_tx_hold_valid_com2 = 1;      return 0;    }  /* Write character */  uwrite(BSP_UART_COM2, THR, *buf & 0xff);  /* Enable interrupts if necessary */  if ( !termios_tx_active_com2 ) {    termios_tx_active_com2 = 1;    uart_data[BSP_UART_COM2].ier |= TRANSMIT_ENABLE;    uwrite(BSP_UART_COM2, IER, uart_data[BSP_UART_COM2].ier);  }  return 0;}voidBSP_uart_termios_isr_com1(void){  unsigned char buf[40];  unsigned char val;  int      off, ret, vect;  off = 0;  for(;;)    {      vect = uread(BSP_UART_COM1, IIR) & 0xf;            switch(vect)	{	case MODEM_STATUS :	  val = uread(BSP_UART_COM1, MSR);	  if(uart_data[BSP_UART_COM1].hwFlow)	    {	      if(val & CTS)		{		  /* CTS high */		  termios_stopped_com1 = 0;		  if(termios_tx_hold_valid_com1)		    {		      termios_tx_hold_valid_com1 = 0;		      BSP_uart_termios_write_com1(0, &termios_tx_hold_com1,						    1);		    }		}	      else		{		  /* CTS low */		  termios_stopped_com1 = 1;		}	    }	  break;	case NO_MORE_INTR :	  /* No more interrupts */	  if(off != 0)	    {	      /* Update rx buffer */         if( driver_input_handler_com1 )         {             driver_input_handler_com1( termios_ttyp_com1, (char *)buf, off );         }          else         {            /* Update rx buffer */	         rtems_termios_enqueue_raw_characters(termios_ttyp_com1, (char *)buf, off );         }	    }	  return;	case TRANSMITTER_HODING_REGISTER_EMPTY :	  /* 	   * TX holding empty: we have to disable these interrupts 	   * if there is nothing more to send. 	   */	  /* If nothing else to send disable interrupts */	  ret = rtems_termios_dequeue_characters(termios_ttyp_com1, 1);          if ( ret == 0 ) {            termios_tx_active_com1 = 0;            uart_data[BSP_UART_COM1].ier &= ~(TRANSMIT_ENABLE);            uwrite(BSP_UART_COM1, IER, uart_data[BSP_UART_COM1].ier);          }	  break;	case RECEIVER_DATA_AVAIL :	case CHARACTER_TIMEOUT_INDICATION:          if ( uart_data[BSP_UART_COM1].ioMode == TERMIOS_TASK_DRIVEN ) {            /* ensure interrupts are enabled */            if ( uart_data[BSP_UART_COM1].ier & RECEIVE_ENABLE ) {              /* disable interrupts and notify termios */              uart_data[BSP_UART_COM1].ier &= ~(RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE);              uwrite(BSP_UART_COM1, IER, uart_data[BSP_UART_COM1].ier);              rtems_termios_rxirq_occured(termios_ttyp_com1);            }          }          else {	    /* RX data ready */	    assert(off < sizeof(buf));	    buf[off++] = uread(BSP_UART_COM1, RBR);          }	  break;	case RECEIVER_ERROR:	  /* RX error: eat character */	   uartError(BSP_UART_COM1);	  break;	default:	  /* Should not happen */	  assert(0);	  return;	}    }}	  voidBSP_uart_termios_isr_com2(){  unsigned char buf[40];  unsigned char val;  int      off, ret, vect;  off = 0;  for(;;)    {      vect = uread(BSP_UART_COM2, IIR) & 0xf;            switch(vect)	{	case MODEM_STATUS :	  val = uread(BSP_UART_COM2, MSR);	  if(uart_data[BSP_UART_COM2].hwFlow)	    {	      if(val & CTS)		{		  /* CTS high */		  termios_stopped_com2 = 0;		  if(termios_tx_hold_valid_com2)		    {		      termios_tx_hold_valid_com2 = 0;		      BSP_uart_termios_write_com2(0, &termios_tx_hold_com2,						    1);		    }		}	      else		{		  /* CTS low */		  termios_stopped_com2 = 1;		}	    }	  break;	case NO_MORE_INTR :	  /* No more interrupts */	  if(off != 0)	    {	      /* Update rx buffer */         if( driver_input_handler_com2 )         {             driver_input_handler_com2( termios_ttyp_com2, (char *)buf, off );         }          else         {	        rtems_termios_enqueue_raw_characters(termios_ttyp_com2, (char *)buf, off);         }	    }	  return;	case TRANSMITTER_HODING_REGISTER_EMPTY :	  /* 	   * TX holding empty: we have to disable these interrupts 	   * if there is nothing more to send.	   */	  /* If nothing else to send disable interrupts */	  ret = rtems_termios_dequeue_characters(termios_ttyp_com2, 1);          if ( ret == 0 ) {            termios_tx_active_com2 = 0;            uart_data[BSP_UART_COM2].ier &= ~(TRANSMIT_ENABLE);            uwrite(BSP_UART_COM2, IER, uart_data[BSP_UART_COM2].ier);          }	  break;	case RECEIVER_DATA_AVAIL :	case CHARACTER_TIMEOUT_INDICATION:          if ( uart_data[BSP_UART_COM2].ioMode == TERMIOS_TASK_DRIVEN ) {            /* ensure interrupts are enabled */            if ( uart_data[BSP_UART_COM2].ier & RECEIVE_ENABLE ) {              /* disable interrupts and notify termios */              uart_data[BSP_UART_COM2].ier &= ~(RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE);              uwrite(BSP_UART_COM2, IER, uart_data[BSP_UART_COM2].ier);              rtems_termios_rxirq_occured(termios_ttyp_com2);            }          }          else {	    /* RX data ready */	    assert(off < sizeof(buf));	    buf[off++] = uread(BSP_UART_COM2, RBR);          }	  break;	case RECEIVER_ERROR:	  /* RX error: eat character */	   uartError(BSP_UART_COM2);	  break;	default:	  /* Should not happen */	  assert(0);	  return;	}    }}	    /* ================= GDB support     ===================*/ static int sav[4] __attribute__ ((unused));/* * Interrupt service routine for COM1 - all,  * it does it check whether ^C is received * if yes it will flip TF bit before returning * Note: it should be installed as raw interrupt * handler */asm (".p2align 4");asm (".text");asm (".globl BSP_uart_dbgisr_com1");asm ("BSP_uart_dbgisr_com1:");asm ("    movl %eax, sav");          /* Save eax */asm ("    movl %ebx, sav + 4");      /* Save ebx */asm ("    movl %edx, sav + 8");      /* Save edx */asm ("    movl $0, %ebx");           /* Clear flag *//*  * We know that only receive related interrupts * are available, eat chars */asm ("uart_dbgisr_com1_1:");asm ("    movw $0x3FD, %dx");asm ("    inb  %dx, %al"); /* Read LSR */asm ("    andb $1, %al");asm ("    cmpb $0, %al");asm ("    je   uart_dbgisr_com1_2");asm ("    movw $0x3F8, %dx");asm ("    inb  %dx, %al");    /* Get input character */asm ("    cmpb $3, %al");asm ("    jne  uart_dbgisr_com1_1");/* ^C received, set flag */ asm ("    movl $1, %ebx");asm ("    jmp uart_dbgisr_com1_1");/* All chars read */asm ("uart_dbgisr_com1_2:");/* If flag is set we have to tweak TF */asm ("   cmpl $0, %ebx");asm ("   je   uart_dbgisr_com1_3");/* Flag is set */asm ("   movl sav+4, %ebx");     /* Restore ebx */asm ("   movl sav+8, %edx");     /* Restore edx *//* Set TF bit */asm ("   popl  %eax");           /* Pop eip */asm ("   movl  %eax, sav + 4");  /* Save it */asm ("   popl  %eax");           /* Pop cs */asm ("   movl  %eax, sav + 8");  /* Save it */asm ("   popl  %eax");           /* Pop flags */asm ("   orl   $0x100, %eax");   /* Modify it */asm ("   pushl %eax");           /* Push it back */asm ("   movl  sav+8, %eax");    /* Put back cs */asm ("   pushl %eax");asm ("   movl  sav+4, %eax");    /* Put back eip */asm ("   pushl %eax");/* Acknowledge IRQ */asm ("   movb  $0x20, %al");asm ("   outb  %al, $0x20");asm ("   movl  sav, %eax");      /* Restore eax */asm ("   iret");                 /* Done *//* Flag is not set */asm("uart_dbgisr_com1_3:");asm ("   movl sav+4, %ebx");     /* Restore ebx */asm ("   movl sav+8, %edx");     /* Restore edx *//* Acknowledge irq */asm ("   movb  $0x20, %al");asm ("   outb  %al, $0x20");asm ("   movl  sav, %eax");      /* Restore eax */asm ("   iret");                 /* Done *//* * Interrupt service routine for COM2 - all,  * it does it check whether ^C is received * if yes it will flip TF bit before returning * Note: it has to be installed as raw interrupt  * handler */asm (".p2align 4");asm (".text");asm (".globl BSP_uart_dbgisr_com2");asm ("BSP_uart_dbgisr_com2:");asm ("    movl %eax, sav");          /* Save eax */asm ("    movl %ebx, sav + 4");      /* Save ebx */asm ("    movl %edx, sav + 8");      /* Save edx */asm ("    movl $0, %ebx");           /* Clear flag *//*  * We know that only receive related interrupts * are available, eat chars */asm ("uart_dbgisr_com2_1:");asm ("    movw $0x2FD, %dx");asm ("    inb  %dx, %al"); /* Read LSR */asm ("    andb $1, %al");asm ("    cmpb $0, %al");asm ("    je   uart_dbgisr_com2_2");asm ("    movw $0x2F8, %dx");asm ("    inb  %dx, %al");    /* Get input character */asm ("    cmpb $3, %al");asm ("    jne  uart_dbgisr_com2_1");/* ^C received, set flag */ asm ("    movl $1, %ebx");asm ("    jmp uart_dbgisr_com2_1");/* All chars read */asm ("uart_dbgisr_com2_2:");/* If flag is set we have to tweak TF */asm ("   cmpl $0, %ebx");asm ("   je   uart_dbgisr_com2_3");/* Flag is set */asm ("   movl sav+4, %ebx");     /* Restore ebx */asm ("   movl sav+8, %edx");     /* Restore edx *//* Set TF bit */asm ("   popl  %eax");           /* Pop eip */asm ("   movl  %eax, sav + 4");  /* Save it */asm ("   popl  %eax");           /* Pop cs */asm ("   movl  %eax, sav + 8");  /* Save it */asm ("   popl  %eax");           /* Pop flags */asm ("   orl   $0x100, %eax");   /* Modify it */asm ("   pushl %eax");           /* Push it back */asm ("   movl  sav+8, %eax");    /* Put back cs */asm ("   pushl %eax");asm ("   movl  sav+4, %eax");    /* Put back eip */asm ("   pushl %eax");/* Acknowledge IRQ */asm ("   movb  $0x20, %al");asm ("   outb  %al, $0x20");asm ("   movl  sav, %eax");      /* Restore eax */asm ("   iret");                 /* Done *//* Flag is not set */asm("uart_dbgisr_com2_3:");asm ("   movl sav+4, %ebx");     /* Restore ebx */asm ("   movl sav+8, %edx");     /* Restore edx *//* Acknowledge irq */asm ("   movb  $0x20, %al");asm ("   outb  %al, $0x20");asm ("   movl  sav, %eax");      /* Restore eax */asm ("   iret");                 /* Done */

⌨️ 快捷键说明

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