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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_65/] [or1ksim/] [peripheral/] [16450.c] - Diff between revs 1116 and 1143

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

Rev 1116 Rev 1143
Line 41... Line 41...
 
 
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MIN(a,b) ((a) < (b) ? (a) : (b))
 
 
static struct dev_16450 uarts[MAX_UARTS];                       /* simulation info */
static struct dev_16450 uarts[MAX_UARTS];                       /* simulation info */
static struct channel * channels[MAX_UARTS] = { NULL, };        /* emulation info */
static struct channel * channels[MAX_UARTS] = { NULL, };        /* emulation info */
static int thre_int;
 
 
 
/* Number of clock cycles (one clock cycle is one call to the uart_clock())
/* Number of clock cycles (one clock cycle is one call to the uart_clock())
   before a single character is transmitted or received. */
   before a single character is transmitted or received. */
static unsigned long char_clks(int dll, int dlh, int lcr)
static unsigned long char_clks(int dll, int dlh, int lcr)
{
{
Line 113... Line 112...
      uarts[chipsel].fifo_len = (value & UART_FCR_FIE) ? 16 : 1;
      uarts[chipsel].fifo_len = (value & UART_FCR_FIE) ? 16 : 1;
      if (value & UART_FCR_RTXFI) {
      if (value & UART_FCR_RTXFI) {
        uarts[chipsel].istat.txbuf_head = uarts[chipsel].istat.txbuf_tail = 0;
        uarts[chipsel].istat.txbuf_head = uarts[chipsel].istat.txbuf_tail = 0;
        uarts[chipsel].istat.txbuf_full = 0;
        uarts[chipsel].istat.txbuf_full = 0;
        uarts[chipsel].regs.lsr &= ~UART_LSR_TXBUFE;
        uarts[chipsel].regs.lsr &= ~UART_LSR_TXBUFE;
 
        uarts[chipsel].istat.thre_int = 0;
      }
      }
      if (value & UART_FCR_RRXFI) {
      if (value & UART_FCR_RRXFI) {
        uarts[chipsel].istat.rxbuf_head = uarts[chipsel].istat.rxbuf_tail = 0;
        uarts[chipsel].istat.rxbuf_head = uarts[chipsel].istat.rxbuf_tail = 0;
        uarts[chipsel].istat.rxbuf_full = 0;
        uarts[chipsel].istat.rxbuf_full = 0;
        uarts[chipsel].regs.lsr &= ~UART_LSR_RDRDY;
        uarts[chipsel].regs.lsr &= ~UART_LSR_RDRDY;
      }
      }
      break;
      break;
    case UART_IER:
    case UART_IER:
      uarts[chipsel].regs.ier = value & UART_VALID_IER;
      uarts[chipsel].regs.ier = value & UART_VALID_IER;
#if 0
 
      if (uarts[chipsel].regs.ier & UART_IER_THRI)
 
        uarts[chipsel].istat.thre_int = 1;
 
#endif
 
      break;
      break;
    case UART_LCR:
    case UART_LCR:
      uarts[chipsel].regs.lcr = value & UART_VALID_LCR;
      uarts[chipsel].regs.lcr = value & UART_VALID_LCR;
      uarts[chipsel].char_clks = char_clks(uarts[chipsel].regs.dll, uarts[chipsel].regs.dlh, uarts[chipsel].regs.lcr);
      uarts[chipsel].char_clks = char_clks(uarts[chipsel].regs.dll, uarts[chipsel].regs.dlh, uarts[chipsel].regs.lcr);
      break;
      break;
Line 361... Line 357...
      uarts[i].iregs.txser = uarts[i].regs.txbuf[uarts[i].istat.txbuf_tail];
      uarts[i].iregs.txser = uarts[i].regs.txbuf[uarts[i].istat.txbuf_tail];
      uarts[i].istat.txbuf_tail = (uarts[i].istat.txbuf_tail + 1) % uarts[i].fifo_len;
      uarts[i].istat.txbuf_tail = (uarts[i].istat.txbuf_tail + 1) % uarts[i].fifo_len;
      uarts[i].istat.txser_full = 1;
      uarts[i].istat.txser_full = 1;
      uarts[i].istat.txbuf_full--;
      uarts[i].istat.txbuf_full--;
      uarts[i].regs.lsr &= ~UART_LSR_TXSERE;
      uarts[i].regs.lsr &= ~UART_LSR_TXSERE;
 
 
 
      // When UART is in either character mode, i.e. 16450 emulation mode, or FIFO mode,
 
      // the THRE interrupt is raised when THR transitions from full to empty.
 
      if (!uarts[i].istat.txbuf_full) {
      uarts[i].istat.thre_int = 1;
      uarts[i].istat.thre_int = 1;
 
        uarts[i].regs.lsr |= UART_LSR_TXBUFE;
 
      }
    } else {
    } else {
      uarts[i].regs.lsr |= UART_LSR_TXSERE;
      uarts[i].regs.lsr |= UART_LSR_TXSERE;
      uarts[i].regs.lsr |= UART_LSR_TXBUFE;
 
    }
    }
  } else if (uarts[i].char_clks <= uarts[i].istat.txser_clks++) {
  } else if (uarts[i].char_clks <= uarts[i].istat.txser_clks++) {
    send_char(i, (uarts[i].regs.lcr & UART_LCR_WLEN8) + 5); /* We've sent all bits */
    send_char(i, (uarts[i].regs.lcr & UART_LCR_WLEN8) + 5); /* We've sent all bits */
  } else {
  } else {
    /* We are still sending char here*/
    /* We are still sending char here*/
Line 388... Line 389...
      /* mark as character was sent */
      /* mark as character was sent */
      uarts[i].istat.txser_full = 0;
      uarts[i].istat.txser_full = 0;
      uarts[i].istat.txser_clks = 0;
      uarts[i].istat.txser_clks = 0;
    } else
    } else
      uarts[i].vapi.break_sent = 0;
      uarts[i].vapi.break_sent = 0;
 
 
 
  }
 
 
 
  // For FIFO-mode only, THRE interrupt is set when THR and FIFO are empty
 
  if (!uarts[i].istat.txbuf_full && (uarts[i].fifo_len == 16)) {
 
    uarts[i].regs.lsr |= UART_LSR_TXBUFE;
 
    uarts[i].istat.thre_int = 1;
  }
  }
 
 
  /***************** Receive *****************/
  /***************** Receive *****************/
 
 
  /* Is there a break? */
  /* Is there a break? */
Line 542... Line 550...
    uarts[i].regs.iir = UART_IIR_RDI;
    uarts[i].regs.iir = UART_IIR_RDI;
  } else if ((uarts[i].regs.ier & UART_IER_RDI)               /* timeout */
  } else if ((uarts[i].regs.ier & UART_IER_RDI)               /* timeout */
      && (uarts[i].istat.timeout_count >= UART_CHAR_TIMEOUT * uarts[i].char_clks)) {
      && (uarts[i].istat.timeout_count >= UART_CHAR_TIMEOUT * uarts[i].char_clks)) {
    uarts[i].regs.iir = UART_IIR_CTI;
    uarts[i].regs.iir = UART_IIR_CTI;
  } else if (uarts[i].regs.ier & UART_IER_THRI &&             /* Transm. empty */
  } else if (uarts[i].regs.ier & UART_IER_THRI &&             /* Transm. empty */
      uarts[i].regs.lsr & UART_LSR_TXBUFE &&
 
      uarts[i].istat.thre_int == 1) {
      uarts[i].istat.thre_int == 1) {
    uarts[i].regs.iir = UART_IIR_THRI;
    uarts[i].regs.iir = UART_IIR_THRI;
  } else if (uarts[i].regs.ier & UART_IER_MSI &&              /* Modem status */
  } else if (uarts[i].regs.ier & UART_IER_MSI &&              /* Modem status */
      uarts[i].regs.msr & (UART_MSR_DCTS | UART_MSR_DDSR
      uarts[i].regs.msr & (UART_MSR_DCTS | UART_MSR_DDSR
        | UART_MSR_TERI | UART_MSR_DDCD)) {
        | UART_MSR_TERI | UART_MSR_DDCD)) {

powered by: WebSVN 2.1.0

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