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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_43/] [or1ksim/] [peripheral/] [16450.c] - Diff between revs 344 and 355

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

Rev 344 Rev 355
Line 40... Line 40...
static struct dev_16450 uarts[NR_UARTS];
static struct dev_16450 uarts[NR_UARTS];
static int thre_int;
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 void set_char_clks(int uartchip)
static unsigned long char_clks(int dll, int dlh, int lcr)
{
{
        int bauds_per_char = 0;
  float bauds_per_char = 0;
 
  unsigned long char_clks = (dlh << 8) + dll;
 
 
        uarts[uartchip].char_clks = (uarts[uartchip].regs.dlh << 8)
  if (lcr & UART_LCR_PARITY)
                                        + uarts[uartchip].regs.dll;
    bauds_per_char = bauds_per_char + 1.;
 
 
        if (uarts[uartchip].regs.lcr & UART_LCR_PARITY)
  /* stop bits 1 or two */
                bauds_per_char++;
  if (lcr & UART_LCR_STOP)
 
    bauds_per_char = bauds_per_char + 2.;
        if (uarts[uartchip].regs.lcr & UART_LCR_STOP)
  else
                bauds_per_char += 2;
    if ((lcr & 0x3) != 0)
 
      bauds_per_char = bauds_per_char + 1.;
        else
        else
                bauds_per_char++;
      bauds_per_char = bauds_per_char + 1.5;
 
 
        bauds_per_char += (5 + (uarts[uartchip].regs.lcr & 0x2));
  bauds_per_char = bauds_per_char + (5. + (lcr & 0x3));
 
 
        uarts[uartchip].char_clks *= bauds_per_char;
  return char_clks * bauds_per_char;
}
}
 
 
/* Set a specific UART register with value. */
/* Set a specific UART register with value. */
void uart_write_byte(unsigned long addr, unsigned long value)
void uart_write_byte(unsigned long addr, unsigned long value)
{
{
Line 76... Line 78...
 
 
        if (uarts[chipsel].regs.lcr & UART_LCR_DLAB) {
        if (uarts[chipsel].regs.lcr & UART_LCR_DLAB) {
                switch (addr % UART_ADDR_SPACE) {
                switch (addr % UART_ADDR_SPACE) {
                        case UART_DLL:
                        case UART_DLL:
                                uarts[chipsel].regs.dll = value;
                                uarts[chipsel].regs.dll = value;
                    set_char_clks(chipsel);
        uarts[chipsel].char_clks = char_clks(uarts[chipsel].regs.dll, uarts[chipsel].regs.dlh, uarts[chipsel].regs.lcr);
                return;
                return;
                        case UART_DLH:
                        case UART_DLH:
                                uarts[chipsel].regs.dlh = value;
                                uarts[chipsel].regs.dlh = value;
                                return;
                                return;
                }
                }
Line 284... Line 286...
                                uarts[i].regs.lsr &= ~UART_LSR_TXSERE;
                                uarts[i].regs.lsr &= ~UART_LSR_TXSERE;
                                uarts[i].istat.thre_int = 1;
                                uarts[i].istat.thre_int = 1;
                        } else
                        } else
                                uarts[i].regs.lsr |= UART_LSR_TXSERE;
                                uarts[i].regs.lsr |= UART_LSR_TXSERE;
                } else if (uarts[i].char_clks >= uarts[i].istat.txser_clks++) {
                } else if (uarts[i].char_clks >= uarts[i].istat.txser_clks++) {
                        debug(8, "TX \'%c\' via UART%d...\n", uarts[i].iregs.txser, i);
      debug(4, "TX \'%c\' via UART%d...\n", uarts[i].iregs.txser, i);
                        if (uarts[i].regs.mcr & UART_MCR_LOOP)
                        if (uarts[i].regs.mcr & UART_MCR_LOOP)
                                uarts[i].iregs.loopback = uarts[i].iregs.txser;
                                uarts[i].iregs.loopback = uarts[i].iregs.txser;
                        else {
                        else {
                          /* Send to either VAPI or to file */
                          /* Send to either VAPI or to file */
                          if (config.uarts[i].vapi_id) {
                          if (config.uarts[i].vapi_id) {
                            vapi_send (config.uarts[i].vapi_id, uarts[i].iregs.txser);
          int par, pe, fe, nbits = (uarts[i].regs.lcr & UART_LCR_WLEN8) + 5;
 
          int i, data;
 
          unsigned long packet = 0;
 
 
 
          /* Encode a packet */
 
          packet = uarts[i].regs.lcr & ((1 << nbits) - 1);
 
 
 
          /* Calculate parity */
 
          for (i = 0; i < nbits; i++)
 
            par ^= (packet >> i) & 1;
 
 
 
          if (uarts[i].regs.lcr & UART_LCR_PARITY) {
 
            if (uarts[i].regs.lcr & UART_LCR_SPAR) {
 
              packet |= 1 << nbits;
 
            } else {
 
              if (uarts[i].regs.lcr & UART_LCR_EPAR)
 
                packet |= par << nbits;
 
              else
 
                packet |= (par ^ 1) << nbits;
 
            }
 
            nbits++;
 
          }
 
          packet |= 1 << (nbits++);
 
          if (uarts[i].regs.lcr & UART_LCR_STOP)
 
            packet |= 1 << (nbits++);
 
 
 
          /* Decode a packet */
 
          nbits = (uarts[i].vapi.lcr & UART_LCR_WLEN8) + 5;
 
          data = packet & ((1 << nbits) - 1);
 
 
 
          /* Calculate parity, including parity bit */
 
          for (i = 0; i < nbits + 1; i++)
 
            par ^= (packet >> i) & 1;
 
 
 
          if (uarts[i].vapi.lcr & UART_LCR_PARITY) {
 
            if (uarts[i].vapi.lcr & UART_LCR_SPAR) {
 
              pe = !((packet >> nbits) & 1);
 
            } else {
 
              if (uarts[i].vapi.lcr & UART_LCR_EPAR)
 
                pe = par != 0;
 
              else
 
                pe = par != 1;
 
            }
 
            nbits++;
 
          } else
 
            pe = 0;
 
 
 
          fe |= ((packet >> (nbits++)) & 1) ^ 1;
 
          if (uarts[i].vapi.lcr & UART_LCR_STOP)
 
            fe |= ((packet >> (nbits++)) & 1) ^ 1;
 
 
 
          printf ("%08x %08x\n", config.uarts[i].vapi_id, data | (uarts[i].vapi.lcr << 8) | (pe << 16) | (fe << 17));
 
          vapi_send (config.uarts[i].vapi_id, data | (uarts[i].vapi.lcr << 8) | (pe << 16) | (fe << 17));
                          } else {
                          } else {
                                  fputc((int)(uarts[i].iregs.txser & 0xFF), uarts[i].txfs);
                                  fputc((int)(uarts[i].iregs.txser & 0xFF), uarts[i].txfs);
                                  fflush(uarts[i].txfs);
                                  fflush(uarts[i].txfs);
                                }
                                }
                        }
                        }
                        uarts[i].istat.txser_full = 1;
      uarts[i].istat.txser_full = 0;
                        uarts[i].istat.txser_clks = 0;
                        uarts[i].istat.txser_clks = 0;
                }
                }
 
 
                /* Receive */
                /* Receive */
                if (uarts[i].istat.rxser_full) {
                if (uarts[i].istat.rxser_full) {
                        if (uarts[i].char_clks >= uarts[i].istat.rxser_clks++) {
                        if (uarts[i].char_clks >= uarts[i].istat.rxser_clks++) {
                        debug(8, "Receiving via UART%d...\n", i);
        debug(4, "Receiving via UART%d...\n", i);
            uarts[i].istat.rxser_full = 0;
            uarts[i].istat.rxser_full = 0;
                        uarts[i].istat.rxser_clks = 0;
                        uarts[i].istat.rxser_clks = 0;
 
 
                        if (++uarts[i].istat.rxbuf_full > uarts[i].fifo_len)
                        if (++uarts[i].istat.rxbuf_full > uarts[i].fifo_len)
                                  uarts[i].regs.lsr |= UART_LSR_OVRRUN;
                                  uarts[i].regs.lsr |= UART_LSR_OVRRUN;
Line 328... Line 382...
            if (!config.uarts[i].vapi_id) {
            if (!config.uarts[i].vapi_id) {
                    if((retval = fgetc(uarts[i].rxfs)) != EOF)
                    if((retval = fgetc(uarts[i].rxfs)) != EOF)
                          uarts[i].iregs.rxser = (char)retval;
                          uarts[i].iregs.rxser = (char)retval;
                          uarts[i].istat.rxser_full = 1;
                          uarts[i].istat.rxser_full = 1;
          } else { /* VAPI */
          } else { /* VAPI */
 
        int received = 0;
 
        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) {
                                uarts[i].iregs.rxser = uarts[i].vapi_buf[uarts[i].vapi_buf_tail_ptr];
            unsigned long data = uarts[i].vapi_buf[uarts[i].vapi_buf_tail_ptr];
                                uarts[i].vapi_buf_tail_ptr = (uarts[i].vapi_buf_tail_ptr + 1) % uarts[i].fifo_len;
                                uarts[i].vapi_buf_tail_ptr = (uarts[i].vapi_buf_tail_ptr + 1) % uarts[i].fifo_len;
 
            switch (data >> 24) {
 
              case 0x00:
 
                uarts[i].vapi.lcr = (data >> 8) & 0xff;
 
                /* Put data into rx fifo */
 
                uarts[i].vapi.char_clks = char_clks (uarts[i].vapi.dll, uarts[i].vapi.dlh, uarts[i].vapi.lcr);
 
                if (uarts[i].vapi.lcr != uarts[i].regs.lcr || uarts[i].vapi.char_clks != uarts[i].char_clks
 
                 || uarts[i].vapi.skew < -MAX_SKEW || uarts[i].vapi.skew > MAX_SKEW) {
 
                  fprintf (stderr, "WARNING: unmatched VAPI and uart modes.\n");
 
                  /* Set error bits */
 
                  uarts[i].regs.lsr |= UART_LSR_PARITY | UART_LSR_FRAME;
 
                  break;
 
                } else {
 
                  uarts[i].iregs.rxser = data & 0xff;
                                uarts[i].istat.rxser_full = 1;
                                uarts[i].istat.rxser_full = 1;
                        }
                        }
 
                received = 1;
 
                break;
 
              case 0x01:
 
                uarts[i].vapi.dll = (data >> 0) & 0xff;
 
                uarts[i].vapi.dlh = (data >> 8) & 0xff;
 
                break;
 
              case 0x02:
 
                uarts[i].vapi.lcr = data & 0xff;
 
                break;
 
              case 0x03:
 
                uarts[i].vapi.skew = (signed short)(data & 0xffff);
 
                break;
 
              default:
 
                fprintf (stderr, "WARNING: Invalid vapi command %02x\n", data >> 24);
 
                break;
 
            }
 
          } else break;
 
        }
          }
          }
                }
                }
 
 
                /* Loopback */
                /* Loopback */
                if (uarts[i].regs.mcr & UART_MCR_LOOP) {
                if (uarts[i].regs.mcr & UART_MCR_LOOP) {

powered by: WebSVN 2.1.0

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