OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [stable_0_2_0_rc3/] [or1ksim/] [peripheral/] [16450.c] - Diff between revs 1557 and 1563

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 1557 Rev 1563
Line 97... Line 97...
  if(!(uart->regs.ier & UART_IER_MSI))
  if(!(uart->regs.ier & UART_IER_MSI))
    return;
    return;
 
 
  if((uart->regs.iir & UART_IIR_NO_INT) || (uart->regs.iir == UART_IIR_MSI)) {
  if((uart->regs.iir & UART_IIR_NO_INT) || (uart->regs.iir == UART_IIR_MSI)) {
    TRACE("Raiseing modem status interrupt\n");
    TRACE("Raiseing modem status interrupt\n");
    uart_clear_int(uart, uart->regs.iir);
 
 
 
 
    if((uart->regs.iir != UART_IIR_MSI) && (uart->regs.iir != UART_IIR_NO_INT)) {
 
      uart_clear_int(uart, uart->regs.iir);
 
      uart->regs.iir = UART_IIR_MSI;
 
    } else {
    uart->regs.iir = UART_IIR_MSI;
    uart->regs.iir = UART_IIR_MSI;
    SCHED_ADD(uart_int_msi, dat, UART_CLOCK_DIVIDER);
    SCHED_ADD(uart_int_msi, dat, UART_CLOCK_DIVIDER);
    report_interrupt(uart->irq);
    report_interrupt(uart->irq);
  }
  }
}
}
 
}
 
 
static void uart_int_thri(void *dat)
static void uart_int_thri(void *dat)
{
{
  struct dev_16450 *uart = dat;
  struct dev_16450 *uart = dat;
 
 
Line 117... Line 121...
    return;
    return;
 
 
  if((uart->regs.iir & UART_IIR_NO_INT) || (uart->regs.iir == UART_IIR_MSI) ||
  if((uart->regs.iir & UART_IIR_NO_INT) || (uart->regs.iir == UART_IIR_MSI) ||
     (uart->regs.iir == UART_IIR_THRI)) {
     (uart->regs.iir == UART_IIR_THRI)) {
    TRACE("Raiseing transmitter holding register interrupt\n");
    TRACE("Raiseing transmitter holding register interrupt\n");
    uart_clear_int(uart, uart->regs.iir);
 
 
 
 
    if((uart->regs.iir != UART_IIR_THRI) && (uart->regs.iir != UART_IIR_NO_INT)) {
 
      uart_clear_int(uart, uart->regs.iir);
 
      uart->regs.iir = UART_IIR_THRI;
 
    } else {
    uart->regs.iir = UART_IIR_THRI;
    uart->regs.iir = UART_IIR_THRI;
    SCHED_ADD(uart_int_thri, dat, UART_CLOCK_DIVIDER);
    SCHED_ADD(uart_int_thri, dat, UART_CLOCK_DIVIDER);
    report_interrupt(uart->irq);
    report_interrupt(uart->irq);
  }
  }
}
}
 
}
 
 
static void uart_int_cti(void *dat)
static void uart_int_cti(void *dat)
{
{
  struct dev_16450 *uart = dat;
  struct dev_16450 *uart = dat;
 
 
Line 136... Line 144...
  if(!(uart->regs.ier & UART_IER_RDI))
  if(!(uart->regs.ier & UART_IER_RDI))
    return;
    return;
 
 
  if((uart->regs.iir != UART_IIR_RLSI) && (uart->regs.iir != UART_IIR_RDI)) {
  if((uart->regs.iir != UART_IIR_RLSI) && (uart->regs.iir != UART_IIR_RDI)) {
    TRACE("Raiseing character timeout interrupt\n");
    TRACE("Raiseing character timeout interrupt\n");
    uart_clear_int(uart, uart->regs.iir);
 
 
 
 
    if((uart->regs.iir != UART_IIR_CTI) && (uart->regs.iir != UART_IIR_NO_INT)) {
 
      uart_clear_int(uart, uart->regs.iir);
 
      uart->regs.iir = UART_IIR_CTI;
 
    } else {
    uart->regs.iir = UART_IIR_CTI;
    uart->regs.iir = UART_IIR_CTI;
    SCHED_ADD(uart_int_cti, dat, UART_CLOCK_DIVIDER);
    SCHED_ADD(uart_int_cti, dat, UART_CLOCK_DIVIDER);
    report_interrupt(uart->irq);
    report_interrupt(uart->irq);
  }
  }
}
}
 
}
 
 
static void uart_int_rdi(void *dat)
static void uart_int_rdi(void *dat)
{
{
  struct dev_16450 *uart = dat;
  struct dev_16450 *uart = dat;
 
 
Line 155... Line 167...
  if(!(uart->regs.ier & UART_IER_RDI))
  if(!(uart->regs.ier & UART_IER_RDI))
    return;
    return;
 
 
  if(uart->regs.iir != UART_IIR_RLSI) {
  if(uart->regs.iir != UART_IIR_RLSI) {
    TRACE("Raiseing receiver data interrupt\n");
    TRACE("Raiseing receiver data interrupt\n");
    uart_clear_int(uart, uart->regs.iir);
 
 
 
 
    if((uart->regs.iir != UART_IIR_RDI) && (uart->regs.iir != UART_IIR_NO_INT)) {
 
      uart_clear_int(uart, uart->regs.iir);
 
      uart->regs.iir = UART_IIR_RDI;
 
    } else {
    uart->regs.iir = UART_IIR_RDI;
    uart->regs.iir = UART_IIR_RDI;
    SCHED_ADD(uart_int_rdi, dat, UART_CLOCK_DIVIDER);
    SCHED_ADD(uart_int_rdi, dat, UART_CLOCK_DIVIDER);
    report_interrupt(uart->irq);
    report_interrupt(uart->irq);
  }
  }
}
}
 
}
 
 
static void uart_int_rlsi(void *dat)
static void uart_int_rlsi(void *dat)
{
{
  struct dev_16450 *uart = dat;
  struct dev_16450 *uart = dat;
 
 
  uart->istat.ints |= 1 << UART_IIR_RLSI;
  uart->istat.ints |= 1 << UART_IIR_RLSI;
 
 
  if(!(uart->regs.ier & UART_IER_RLSI))
  if(!(uart->regs.ier & UART_IER_RLSI))
    return;
    return;
 
 
  uart_clear_int(uart, uart->regs.iir);
 
 
 
  TRACE("Raiseing receiver line status interrupt\n");
  TRACE("Raiseing receiver line status interrupt\n");
 
 
  /* Highest priority interrupt */
  /* Highest priority interrupt */
 
  if((uart->regs.iir != UART_IIR_RLSI) && (uart->regs.iir != UART_IIR_NO_INT)) {
 
    uart_clear_int(uart, uart->regs.iir);
 
    uart->regs.iir = UART_IIR_RLSI;
 
  } else {
  uart->regs.iir = UART_IIR_RLSI;
  uart->regs.iir = UART_IIR_RLSI;
  SCHED_ADD(uart_int_rlsi, dat, UART_CLOCK_DIVIDER);
  SCHED_ADD(uart_int_rlsi, dat, UART_CLOCK_DIVIDER);
  report_interrupt(uart->irq);
  report_interrupt(uart->irq);
}
}
 
}
 
 
/* Checks to see if an RLSI interrupt is due and schedules one if need be */
/* Checks to see if an RLSI interrupt is due and schedules one if need be */
static void uart_check_rlsi(void *dat)
static void uart_check_rlsi(void *dat)
{
{
  struct dev_16450 *uart = dat;
  struct dev_16450 *uart = dat;
Line 197... Line 216...
/* Checks to see if an RDI interrupt is due and schedules one if need be */
/* Checks to see if an RDI interrupt is due and schedules one if need be */
static void uart_check_rdi(void *dat)
static void uart_check_rdi(void *dat)
{
{
  struct dev_16450 *uart = dat;
  struct dev_16450 *uart = dat;
 
 
  if(uart->istat.rxbuf_full >= UART_FIFO_TRIGGER(uart->regs.fcr >> 6))
  if(uart->istat.rxbuf_full >= UART_FIFO_TRIGGER(uart->regs.fcr >> 6)) {
 
    TRACE("FIFO trigger level reached %i\n",
 
          UART_FIFO_TRIGGER(uart->regs.fcr >> 6));
    uart_int_rdi(uart);
    uart_int_rdi(uart);
}
}
 
}
 
 
/* Raises the next highest priority interrupt */
/* Raises the next highest priority interrupt */
static void uart_next_int(void *dat)
static void uart_next_int(void *dat)
{
{
  struct dev_16450 *uart = dat;
  struct dev_16450 *uart = dat;
Line 231... Line 253...
/* Clears potentially pending interrupts */
/* Clears potentially pending interrupts */
static void uart_clear_int(struct dev_16450 *uart, int intr)
static void uart_clear_int(struct dev_16450 *uart, int intr)
{
{
  uart->istat.ints &= ~(1 << intr);
  uart->istat.ints &= ~(1 << intr);
 
 
 
  TRACE("Interrupt pending was %x\n", uart->regs.iir);
 
 
  /* Short-circuit most likely case */
  /* Short-circuit most likely case */
  if(uart->regs.iir == UART_IIR_NO_INT)
  if(uart->regs.iir == UART_IIR_NO_INT)
    return;
    return;
 
 
  if(intr != uart->regs.iir)
  if(intr != uart->regs.iir)
Line 580... Line 604...
    }
    }
  }
  }
 
 
  switch (addr) {
  switch (addr) {
    case UART_TXBUF:
    case UART_TXBUF:
      TRACE("Adding %"PRIx8" to TX FIFO\n", value);
      TRACE("Adding %"PRIx8" to TX FIFO (fill %i)\n", value,
 
            uart->istat.txbuf_full);
      uart->regs.lsr &= ~UART_LSR_TXBUFE;
      uart->regs.lsr &= ~UART_LSR_TXBUFE;
      if (uart->istat.txbuf_full < uart->fifo_len) {
      if (uart->istat.txbuf_full < uart->fifo_len) {
        uart->regs.txbuf[uart->istat.txbuf_head] = value;
        uart->regs.txbuf[uart->istat.txbuf_head] = value;
        uart->istat.txbuf_head = (uart->istat.txbuf_head + 1) % uart->fifo_len;
        uart->istat.txbuf_head = (uart->istat.txbuf_head + 1) % uart->fifo_len;
        if(!uart->istat.txbuf_full++ && (uart->regs.lsr & UART_LSR_TXSERE))
        if(!uart->istat.txbuf_full++ && (uart->regs.lsr & UART_LSR_TXSERE))

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.