Пример #1
0
/* Handle UART interrupts */
static void apbuart_cons_isr(void *arg)
{
	rtems_termios_tty *tty = arg;
	rtems_termios_device_context *base;
	struct console_dev *condev = rtems_termios_get_device_context(tty);
	struct apbuart_priv *uart = condev_get_priv(condev);
	struct apbuart_regs *regs = uart->regs;
	unsigned int status;
	char buf[33];
	int cnt;

	if (uart->mode == TERMIOS_TASK_DRIVEN) {
		if ((status = regs->status) & APBUART_STATUS_DR) {
			rtems_interrupt_lock_context lock_context;

			/* Turn off RX interrupts */
			base = rtems_termios_get_device_context(tty);
			rtems_termios_device_lock_acquire(base, &lock_context);
			regs->ctrl &=
			    ~(APBUART_CTRL_DI | APBUART_CTRL_RI |
			      APBUART_CTRL_RF);
			rtems_termios_device_lock_release(base, &lock_context);
			/* Activate termios RX daemon task */
			rtems_termios_rxirq_occured(tty);
		}
	} else {
		/*
		 * Get all new characters from APBUART RX (FIFO) and store them
		 * on the stack. Then tell termios about the new characters.
		 * Maximum APBUART RX FIFO size is 32 characters.
		 */
		cnt = 0;
		while (
			((status=regs->status) & APBUART_STATUS_DR) &&
			(cnt < sizeof(buf))
		) {
			buf[cnt] = regs->data;
			cnt++;
		}
		if (0 < cnt) {
			/* Tell termios layer about new characters */
			rtems_termios_enqueue_raw_characters(tty, &buf[0], cnt);
		}
	}

	if (uart->sending && (status & APBUART_STATUS_TE)) {
		/* Tell close that we sent everything */
		cnt = uart->sending;

		/*
		 * Tell termios how much we have sent. dequeue() may call
		 * write_interrupt() to refill the transmitter.
		 * write_interrupt() will eventually be called with 0 len to
		 * disable TX interrupts.
		 */
		rtems_termios_dequeue_characters(tty, cnt);
	}
}
Пример #2
0
rtems_timer_service_routine Rx_ISR(
  rtems_id  ignored_id,
  void     *ignored_address
)
{
  uint8_t ch;

  if ( Rx_Index >= Rx_Length )
    return;

  ch = Rx_Buffer[ Rx_Index++ ];
  rtems_termios_enqueue_raw_characters (Ttyp, (char *)&ch, 1);
  #if defined(TASK_DRIVEN)
    rtems_termios_rxirq_occured(Ttyp);
  #endif

  (void) rtems_timer_fire_after( Rx_Timer, 10, Rx_ISR, NULL );
}
Пример #3
0
Файл: uart.c Проект: RTEMS/rtems
void
BSP_uart_termios_isr_com2(void *ignored)
{
  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;
	}
    }
}
Пример #4
0
/***************************************************************************
   Function : IntUartInterruptHandler

   Description : This is the interrupt handler for the internal uart. It
   determines which channel caused the interrupt before queueing any received
   chars and dequeueing chars waiting for transmission.
 ***************************************************************************/
static rtems_isr
IntUartInterruptHandler(rtems_vector_number v)
{
	unsigned int                chan = v - UART_INTC0_IRQ_VECTOR(0);
	struct IntUartInfoStruct   *info = &IntUartInfo[chan];

	/* check to see if received data */
	if ( MCF5282_UART_UISR(chan) & MCF5282_UART_UISR_RXRDY )
	{
		/* read data and put into the receive buffer */
		while ( MCF5282_UART_USR(chan) & MCF5282_UART_USR_RXRDY )
		{

			if ( MCF5282_UART_USR(chan) & MCF5282_UART_USR_ERROR )
			{
				/* clear the error */
				MCF5282_UART_UCR(chan) = MCF5282_UART_UCR_RESET_ERROR;
			}
			/* put data in rx buffer and check for errors */
			info->rx_buffer[info->rx_in] = MCF5282_UART_URB(chan);

			/* update buffer values */
			info->rx_in++;

			if ( info->rx_in >= RX_BUFFER_SIZE )
			{
				info->rx_in = 0;
			}
		}
		/* Make sure the port has been opened */
		if ( info->ttyp )
		{

			/* check to see if task driven */
			if ( info->iomode == TERMIOS_TASK_DRIVEN )
			{
				/* notify rx task that rx buffer has data */
				rtems_termios_rxirq_occured(info->ttyp);
			}
			else
			{
				/* Push up the received data */
				rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer, info->rx_in);
				info->rx_in    = 0;
			}
		}
	}

	/* check to see if data needs to be transmitted */
	if ( ( info->uimr & MCF5282_UART_UIMR_TXRDY ) &&
		 ( MCF5282_UART_UISR(chan) & MCF5282_UART_UISR_TXRDY ) )
	{

		/* disable tx interrupts */
		info->uimr &= ~MCF5282_UART_UIMR_TXRDY;
		MCF5282_UART_UIMR(chan) = info->uimr;

		/* tell upper level that character has been sent */
		if ( info->ttyp )
			rtems_termios_dequeue_characters(info->ttyp, 1);
	}
}