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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_52/] [or1ksim/] [peripheral/] [16450.c] - Diff between revs 805 and 806

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

Rev 805 Rev 806
Line 46... Line 46...
/* 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)
{
{
  float bauds_per_char = 1.;
  float bauds_per_char = 1.;
  unsigned long char_clks = ((dlh << 8) + dll) * UART_CLOCK_DIVIDER;
  unsigned long char_clks = ((dlh << 8) + dll);
 
 
  if (lcr & UART_LCR_PARITY)
  if (lcr & UART_LCR_PARITY)
    bauds_per_char = bauds_per_char + 1.;
    bauds_per_char = bauds_per_char + 1.;
 
 
  /* stop bits 1 or two */
  /* stop bits 1 or two */
Line 330... Line 330...
  }
  }
  uarts[uart].regs.lsr |= UART_LSR_RDRDY;
  uarts[uart].regs.lsr |= UART_LSR_RDRDY;
  uarts[uart].istat.timeout_count = 0;
  uarts[uart].istat.timeout_count = 0;
}
}
 
 
/* Reset.  It initializes all registers of all UART devices to zero values,
 
   (re)opens all RX/TX file streams and places devices in memory address
 
   space.  */
 
void uart_reset()
 
{
 
  int i;
 
 
 
  if (config.sim.verbose && config.nuarts)
 
    printf("Resetting %u UART(s).\n", config.nuarts);
 
 
 
  memset(uarts, 0, sizeof(uarts));
 
 
 
  for(i = 0; i < config.nuarts; i++) {
 
    if (config.uarts[i].vapi_id) {
 
      if ((config.uarts[i].vapi_id & VAPI_DEVICE_ID) != i) {
 
        fprintf (stderr, "ERROR: Wrong vapi_id (0x%x) for uart %i, last byte is required to be %02x; ignoring.\n", config.uarts[i].vapi_id, i, i);
 
        config.uarts[i].vapi_id = 0;
 
        uarts[i].txfs = 0;
 
      } else {
 
        vapi_install_handler (config.uarts[i].vapi_id, uart_vapi_read);
 
        register_memoryarea(config.uarts[i].baseaddr, UART_ADDR_SPACE, 1, uart_read_byte, uart_write_byte);
 
      }
 
    } else if (config.uarts[i].txfile) { /* MM: Try to create stream.  */
 
      if (!(uarts[i].rxfs = fopen(config.uarts[i].rxfile, "r"))
 
        && !(uarts[i].rxfs = fopen(config.uarts[i].rxfile, "r+"))) {
 
        debug (0, "WARNING: UART%d has problems with RX file stream.\n", i);
 
        continue;
 
      }
 
      uarts[i].txfs = fopen(config.uarts[i].txfile, "a");
 
      if (uarts[i].rxfs && uarts[i].txfs && config.sim.verbose) {
 
        printf("UART%d at 0x%.8x uses ", i, config.uarts[i].baseaddr);
 
        printf("%s for RX and %s for TX.\n", config.uarts[i].rxfile, config.uarts[i].txfile);
 
      } else
 
        debug (1, "WARNING: UART%d has problems with TX file stream.\n", i);
 
      register_memoryarea(config.uarts[i].baseaddr, UART_ADDR_SPACE, 1, uart_read_byte, uart_write_byte);
 
    }
 
 
 
    if (config.uarts[i].uart16550)
 
      uarts[i].fifo_len = 16;
 
    else
 
      uarts[i].fifo_len = 1;
 
 
 
    uarts[i].istat.rxbuf_head = uarts[i].istat.rxbuf_tail = 0;
 
    uarts[i].istat.txbuf_head = uarts[i].istat.txbuf_tail = 0;
 
 
 
    uarts[i].istat.break_set = 0;
 
    uarts[i].istat.timeout_count = 0;
 
    uarts[i].istat.thre_int = 1; /* FIFO is empty at start */
 
    uarts[i].slowdown = UART_FGETC_SLOWDOWN;
 
 
 
    uarts[i].regs.lcr = UART_LCR_RESET;
 
    uarts[i].vapi.cur_break = uarts[i].vapi.cur_break_cnt = uarts[i].vapi.next_break = 0;
 
    uarts[i].vapi.next_break_cnt = -1;
 
  }
 
}
 
 
 
/* Simulation hook. Must be called every clock cycle to simulate all UART
/* Simulation hook. Must be called every clock cycle to simulate all UART
   devices. It does internal functional UART simulation. */
   devices. It does internal functional UART simulation. */
void uart_clock()
void uart_clock16(int i)
{
{
  int i, retval;
  int retval;
 
 
  for(i = 0; i < config.nuarts; i++) {
 
    /* If VAPI is not selected, UART communicates with two file streams;
    /* If VAPI is not selected, UART communicates with two file streams;
       if VAPI is selected, we use VAPI streams.  */
       if VAPI is selected, we use VAPI streams.  */
 
 
    /* if txfs is corrupted, skip this uart. */
    /* if txfs is corrupted, skip this uart. */
    if (!config.uarts[i].vapi_id && !uarts[i].txfs) continue;
  if (!config.uarts[i].vapi_id && !uarts[i].txfs) return;
 
 
    if (uarts[i].vapi.next_break_cnt >= 0)
    if (uarts[i].vapi.next_break_cnt >= 0)
      if (--uarts[i].vapi.next_break_cnt < 0) {
      if (--uarts[i].vapi.next_break_cnt < 0) {
        if (!(uarts[i].vapi.cur_break = uarts[i].vapi.next_break))
        if (!(uarts[i].vapi.cur_break = uarts[i].vapi.next_break))
          uarts[i].istat.break_set = 0;
          uarts[i].istat.break_set = 0;
Line 494... Line 436...
          } else uarts[i].slowdown = UART_FGETC_SLOWDOWN;
          } else uarts[i].slowdown = UART_FGETC_SLOWDOWN;
        }
        }
      } else { /* VAPI */
      } else { /* VAPI */
        int received = 0;
        int received = 0;
        /* do not handle commands while receiving */
        /* do not handle commands while receiving */
        if (uarts[i].istat.rxser_full)
      if (uarts[i].istat.rxser_full) return;
          break;
 
        while (!received) {
        while (!received) {
          if (uarts[i].vapi_buf_head_ptr != uarts[i].vapi_buf_tail_ptr) {
          if (uarts[i].vapi_buf_head_ptr != uarts[i].vapi_buf_tail_ptr) {
            unsigned long data = uarts[i].vapi_buf[uarts[i].vapi_buf_tail_ptr];
            unsigned long data = uarts[i].vapi_buf[uarts[i].vapi_buf_tail_ptr];
            debug(4, "Handling: %08x (%i,%i)\n", data, uarts[i].vapi_buf_head_ptr, uarts[i].vapi_buf_tail_ptr);
            debug(4, "Handling: %08x (%i,%i)\n", data, uarts[i].vapi_buf_head_ptr, uarts[i].vapi_buf_tail_ptr);
            uarts[i].vapi_buf_tail_ptr = (uarts[i].vapi_buf_tail_ptr + 1) % UART_VAPI_BUF_LEN;
            uarts[i].vapi_buf_tail_ptr = (uarts[i].vapi_buf_tail_ptr + 1) % UART_VAPI_BUF_LEN;
Line 601... Line 542...
    }
    }
    if (!(uarts[i].regs.iir & UART_IIR_NO_INT)) {
    if (!(uarts[i].regs.iir & UART_IIR_NO_INT)) {
      debug (4, "uarts[i].regs.iir = %i\t", uarts[i].regs.iir);
      debug (4, "uarts[i].regs.iir = %i\t", uarts[i].regs.iir);
      report_interrupt(config.uarts[i].irq);
      report_interrupt(config.uarts[i].irq);
    }
    }
 
  SCHED_ADD (uart_clock16, i, cycles + UART_CLOCK_DIVIDER);
 
}
 
 
 
/* Reset.  It initializes all registers of all UART devices to zero values,
 
   (re)opens all RX/TX file streams and places devices in memory address
 
   space.  */
 
void uart_reset()
 
{
 
  int i;
 
  if (config.sim.verbose && config.nuarts) printf("Resetting %u UART(s).\n", config.nuarts);
 
  memset(uarts, 0, sizeof(uarts));
 
 
 
  for(i = 0; i < config.nuarts; i++) {
 
    if (config.uarts[i].vapi_id) {
 
      if ((config.uarts[i].vapi_id & VAPI_DEVICE_ID) != i) {
 
        fprintf (stderr, "ERROR: Wrong vapi_id (0x%x) for uart %i, last byte is required to be %02x; ignoring.\n", config.uarts[i].vapi_id, i, i);
 
        config.uarts[i].vapi_id = 0;
 
        uarts[i].txfs = 0;
 
      } else {
 
        vapi_install_handler (config.uarts[i].vapi_id, uart_vapi_read);
 
        register_memoryarea(config.uarts[i].baseaddr, UART_ADDR_SPACE, 1, uart_read_byte, uart_write_byte);
 
      }
 
    } else if (config.uarts[i].txfile) { /* MM: Try to create stream.  */
 
      if (!(uarts[i].rxfs = fopen(config.uarts[i].rxfile, "r"))
 
        && !(uarts[i].rxfs = fopen(config.uarts[i].rxfile, "r+"))) {
 
        debug (0, "WARNING: UART%d has problems with RX file stream.\n", i);
 
        continue;
 
      }
 
      uarts[i].txfs = fopen(config.uarts[i].txfile, "a");
 
      if (uarts[i].rxfs && uarts[i].txfs && config.sim.verbose) {
 
        printf("UART%d at 0x%.8x uses ", i, config.uarts[i].baseaddr);
 
        printf("%s for RX and %s for TX.\n", config.uarts[i].rxfile, config.uarts[i].txfile);
 
      } else
 
        debug (1, "WARNING: UART%d has problems with TX file stream.\n", i);
 
      register_memoryarea(config.uarts[i].baseaddr, UART_ADDR_SPACE, 1, uart_read_byte, uart_write_byte);
 
    }
 
 
 
    if (config.uarts[i].uart16550)
 
      uarts[i].fifo_len = 16;
 
    else
 
      uarts[i].fifo_len = 1;
 
 
 
    uarts[i].istat.rxbuf_head = uarts[i].istat.rxbuf_tail = 0;
 
    uarts[i].istat.txbuf_head = uarts[i].istat.txbuf_tail = 0;
 
 
 
    uarts[i].istat.break_set = 0;
 
    uarts[i].istat.timeout_count = 0;
 
    uarts[i].istat.thre_int = 1; /* FIFO is empty at start */
 
    uarts[i].slowdown = UART_FGETC_SLOWDOWN;
 
 
 
    uarts[i].regs.lcr = UART_LCR_RESET;
 
    uarts[i].vapi.cur_break = uarts[i].vapi.cur_break_cnt = uarts[i].vapi.next_break = 0;
 
    uarts[i].vapi.next_break_cnt = -1;
 
    SCHED_ADD (uart_clock16, i, cycles + UART_CLOCK_DIVIDER);
  }
  }
}
}
 
 
/* Print register values on stdout. */
/* Print register values on stdout. */
void uart_status()
void uart_status()

powered by: WebSVN 2.1.0

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