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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_66/] [or1ksim/] [peripheral/] [16450.c] - Diff between revs 185 and 221

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

Rev 185 Rev 221
Line 28... Line 28...
*/
*/
 
 
#include <stdlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string.h>
#include <sys/types.h>  /* CZ 250801 */
 
#include <sys/stat.h>   /* CZ 250801 */
 
#include <fcntl.h>      /* CZ 250801 */ 
 
#include <sys/poll.h>   /* CZ 250801 */
 
#include <sys/time.h>   /* CZ 250801 */ 
 
#include <unistd.h>     /* CZ 250801 */ 
 
#include <errno.h>      /* CZ 250801 */ 
 
 
 
#include "16450.h"
#include "16450.h"
#include "sim-config.h"
#include "sim-config.h"
#include "pic.h"
#include "pic.h"
 
 
static struct dev_16450 uarts[NR_UARTS];
static struct dev_16450 uarts[NR_UARTS];
 
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 void set_char_clks(int uartchip)
{
{
Line 64... Line 58...
        bauds_per_char += (5 + (uarts[uartchip].regs.lcr & 0x2));
        bauds_per_char += (5 + (uarts[uartchip].regs.lcr & 0x2));
 
 
        uarts[uartchip].char_clks *= bauds_per_char;
        uarts[uartchip].char_clks *= bauds_per_char;
}
}
 
 
/* CZ 260801 --- The simulator expects to access only 32
 
   bit words. Since we only have an 8 bit data space, simply
 
   ignore the bottom 24 bits. */
 
/* Set a specific UART register with value. */
/* Set a specific UART register with value. */
void uart_write(unsigned long addr, unsigned int arg_value)
void uart_write(unsigned long addr, unsigned long value)
{
{
        int chipsel;
        int chipsel;
        unsigned char value = arg_value >> 24;
 
 
 
        debug("uart_write(%x,%x)\n", addr, value);
        debug("uart_write(%x,%x)\n", addr, (value >> 24));
 
 
        for(chipsel = 0; chipsel < NR_UARTS; chipsel++)
        for(chipsel = 0; chipsel < NR_UARTS; chipsel++)
                if ((addr & ~(UART_ADDR_SPACE-1)) == uarts[chipsel].baseaddr)
                if ((addr & ~(UART_ADDR_SPACE-1)) == uarts[chipsel].baseaddr)
                        break;
                        break;
                else if (chipsel == NR_UARTS)
                else if (chipsel == NR_UARTS)
                        return;
                        return;
 
 
        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 >> 24);
                set_char_clks(chipsel);
                                break;
                return;
 
              case UART_DLH:
              case UART_DLH:
                uarts[chipsel].regs.dlh = value;
                                uarts[chipsel].regs.dlh = (value >> 24);
                set_char_clks(chipsel);
                                break;
                return;
                        case UART_LCR:
              default: /* Fall through to normal processing */
                                uarts[chipsel].regs.lcr = (value >> 24) & UART_VALID_LCR;
                break;
                break;
 
                        default:
 
                                debug("write out of range (addr %x, DLAB=1)\n", addr);
              }
              }
 
                set_char_clks(chipsel);
 
                return;
          }
          }
 
 
        switch (addr % UART_ADDR_SPACE) {
        switch (addr % UART_ADDR_SPACE) {
                case UART_TXBUF:
                case UART_TXBUF:
                        uarts[chipsel].regs.txbuf = value;
                        uarts[chipsel].regs.txbuf = (value >> 24);
                        uarts[chipsel].istat.txbuf = FULL;
                        uarts[chipsel].istat.txbuf = FULL;
                        uarts[chipsel].regs.lsr &= ~UART_LSR_TXBUFE;
                        uarts[chipsel].regs.lsr &= ~UART_LSR_TXBUFE;
                        uarts[chipsel].regs.lsr &= ~UART_LSR_TXSERE;
                        uarts[chipsel].regs.lsr &= ~UART_LSR_TXSERE;
 
                        uarts[chipsel].istat.thre_int = 0;
                        break;
                        break;
                case UART_IER:
                case UART_IER:
                        uarts[chipsel].regs.ier = value & UART_VALID_IER;
                        uarts[chipsel].regs.ier = (value >> 24) & UART_VALID_IER;
                        break;
                        break;
                case UART_LCR:
                case UART_LCR:
                        uarts[chipsel].regs.lcr = value & UART_VALID_LCR;
                        uarts[chipsel].regs.lcr = (value >> 24) & UART_VALID_LCR;
                        break;
                        break;
                case UART_MCR:
                case UART_MCR:
                        uarts[chipsel].regs.mcr = value & UART_VALID_MCR;
                        uarts[chipsel].regs.mcr = (value >> 24) & UART_VALID_MCR;
                        break;
                        break;
                case UART_SCR:
                case UART_SCR:
                        uarts[chipsel].regs.scr = value;
                        uarts[chipsel].regs.scr = (value >> 24);
                        break;
                        break;
                default:
                default:
                        debug("write out of range (addr %x)\n", addr);
                        debug("write out of range (addr %x)\n", addr);
        }
        }
        set_char_clks(chipsel);
        set_char_clks(chipsel);
        return;
        return;
}
}
 
 
/* CZ 260801 --- The simulator expects to access only 32
 
   bit words. Since we only have an 8 bit data space, simply
 
   fill in the bottom 24 bits with zero */
 
/* Read a specific UART register. */
/* Read a specific UART register. */
unsigned int uart_read(unsigned long addr)
unsigned long uart_read(unsigned long addr)
{
{
        unsigned char value = 0;
        unsigned char value = 0;
        int chipsel;
        int chipsel;
 
 
        debug("uart_read(%x)\n", addr);
        debug("uart_read(%x)\n", addr);
Line 141... Line 130...
                if ((addr & ~(UART_ADDR_SPACE-1)) == uarts[chipsel].baseaddr)
                if ((addr & ~(UART_ADDR_SPACE-1)) == uarts[chipsel].baseaddr)
                        break;
                        break;
                else if (chipsel == NR_UARTS)
                else if (chipsel == NR_UARTS)
                        return 0;
                        return 0;
 
 
        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:
                return uarts[chipsel].regs.dll << 24;
                                value = uarts[chipsel].regs.dll;
 
                                break;
              case UART_DLH:
              case UART_DLH:
                return uarts[chipsel].regs.dlh << 24;
                                value = uarts[chipsel].regs.dlh;
              default: /* Fall through to normal processing */
 
                break;
                break;
 
                        default:
 
                                debug("read out of range (addr %x, DLAB=1)\n", addr);
              }
              }
 
                return (value << 24);
          }
          }
 
 
        switch (addr % UART_ADDR_SPACE) {
        switch (addr % UART_ADDR_SPACE) {
                case UART_RXBUF:
                case UART_RXBUF:
                        value = uarts[chipsel].regs.rxbuf;
                        value = uarts[chipsel].regs.rxbuf;
Line 165... Line 155...
                case UART_IER:
                case UART_IER:
                        value = uarts[chipsel].regs.ier & UART_VALID_IER;
                        value = uarts[chipsel].regs.ier & UART_VALID_IER;
                        break;
                        break;
                case UART_IIR:
                case UART_IIR:
                        value = uarts[chipsel].regs.iir & UART_VALID_IIR;
                        value = uarts[chipsel].regs.iir & UART_VALID_IIR;
 
                        uarts[chipsel].istat.thre_int = 0;
                        break;
                        break;
                case UART_LCR:
                case UART_LCR:
                        value = uarts[chipsel].regs.lcr & UART_VALID_LCR;
                        value = uarts[chipsel].regs.lcr & UART_VALID_LCR;
                        break;
                        break;
                case UART_MCR:
                case UART_MCR:
Line 188... Line 179...
                        value = uarts[chipsel].regs.scr;
                        value = uarts[chipsel].regs.scr;
                        break;
                        break;
                default:
                default:
                        debug("read out of range (addr %x)\n", addr);
                        debug("read out of range (addr %x)\n", addr);
        }
        }
        return value << 24;
        return (value << 24);
}
}
 
 
 
 
/* Reset. It initializes all registers of all UART devices to zero values,
/* 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
   (re)opens all RX/TX file streams and places devices in memory address
   space. */
   space. */
void uart_reset()
void uart_reset()
{
{
  int i;
  int i;
  static int initialized = 0; /* If we're not initialized, don't close it */
 
  int saved_tx_fds[NR_UARTS];
 
  int saved_rx_fds[NR_UARTS];
 
 
 
  if(initialized)
 
    {
 
      for(i = 0; i < NR_UARTS; i++)
 
        {
 
          struct stat buf;
 
 
 
          if(uarts[i].txfd >= 0)
 
            {
 
              if(fstat(uarts[i].txfd,&buf) ||
 
                 (!S_ISFIFO(buf.st_mode) &&
 
                  !S_ISSOCK(buf.st_mode)))
 
                {
 
                  close(uarts[i].txfd);
 
                  saved_tx_fds[i] = -1;
 
                }
 
              else
 
                saved_tx_fds[i] = uarts[i].txfd;
 
            }
 
          else
 
            saved_tx_fds[i] = -1;
 
 
 
          if(uarts[i].rxfd >= 0)
 
            {
 
              if(fstat(uarts[i].rxfd,&buf) ||
 
                 (!S_ISFIFO(buf.st_mode) &&
 
                  !S_ISSOCK(buf.st_mode)))
 
                {
 
                  close(uarts[i].rxfd);
 
                  saved_rx_fds[i] = -1;
 
                }
 
              else
 
                saved_rx_fds[i] = uarts[i].txfd;
 
            }
 
          else
 
            saved_rx_fds[i] = -1;
 
        }
 
    }
 
  else
 
    {
 
      for(i=0;i<NR_UARTS;i++)
 
        saved_tx_fds[i] = saved_rx_fds[i] = -1;
 
      initialized = 1;
 
    }
 
 
 
  printf("Resetting %u UART(s).\n", NR_UARTS);
  printf("Resetting %u UART(s).\n", NR_UARTS);
  memset(uarts, 0, sizeof(uarts));
  memset(uarts, 0, sizeof(uarts));
  for(i=0;i<NR_UARTS;i++)
 
    {
 
      uarts[i].txfd = saved_tx_fds[i];
 
      uarts[i].rxfd = saved_rx_fds[i];
 
    }
 
 
 
  for(i = 0; i < NR_UARTS; i++)
  for(i = 0; i < NR_UARTS; i++)
    if (config.uarts[i].txfile) { /* MM: Try to create stream.  */
    if (config.uarts[i].txfile) { /* MM: Try to create stream.  */
      /* CZ changed this to use descriptors and non blocking I/O */
      if (!(uarts[i].rxfs = fopen(config.uarts[i].rxfile, "r"))
      if ((uarts[i].rxfd = open(config.uarts[i].rxfile,
          && !(uarts[i].rxfs = fopen(config.uarts[i].rxfile, "r+"))) {
                                O_RDONLY | O_NONBLOCK)) < 0)
        printf("UART%d has problems with RX file stream.\n", i);
        {
 
          char sTemp[256];
 
 
 
          sprintf(sTemp,"UART%d RX - \"%s\"",i,config.uarts[i].rxfile);
 
          perror(sTemp);
 
          continue;
 
        }
 
      if((uarts[i].txfd = open(config.uarts[i].txfile,
 
                                O_WRONLY | O_NONBLOCK)) < 0)
 
        {
 
          char sTemp[256];
 
 
 
          if(errno == ENXIO)
 
            {
 
              /* In this case, we're a pipe, and the user has
 
                 forgotten to start the read process first. Help
 
                 him out by writing an error message and exiting */
 
 
 
              fprintf(stderr,"Please start the serial port reader "
 
                      "before starting the simulator.\nIf you wish "
 
                      "to continue without this, please remove the "
 
                      "file \"%s\" and restart.\n",config.uarts[i].txfile);
 
              fflush(stderr);
 
              exit(1);
 
            }
 
          sprintf(sTemp,"UART%d TX - \"%s\"",i,config.uarts[i].txfile);
 
          perror(sTemp);
 
          close(uarts[i].rxfd);
 
          uarts[i].rxfd = -1;
 
          continue;
          continue;
        }
        }
 
      uarts[i].txfs = fopen(config.uarts[i].txfile, "a");
      uarts[i].baseaddr = config.uarts[i].baseaddr;
      uarts[i].baseaddr = config.uarts[i].baseaddr;
 
      if (uarts[i].txfs && uarts[i].txfs) {
      printf("UART%d at 0x%.8x uses ", i, uarts[i].baseaddr);
      printf("UART%d at 0x%.8x uses ", i, uarts[i].baseaddr);
      printf("%s for RX and %s for TX.\n", config.uarts[i].rxfile,
        printf("%s for RX and %s for TX.\n", config.uarts[i].rxfile, config.uarts[i].txfile);
             config.uarts[i].txfile);
      } else
      register_memoryarea(uarts[i].baseaddr, UART_ADDR_SPACE,
        printf("UART%d has problems with TX file stream.\n", i);
                          uart_read, uart_write);
      register_memoryarea(uarts[i].baseaddr, UART_ADDR_SPACE, uart_read, uart_write);
    }
    }
}
}
 
 
/* 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_clock()
{
{
        int i;
        int i, retval;
 
 
        for(i = 0; i < NR_UARTS; i++) {
        for(i = 0; i < NR_UARTS; i++) {
 
                if (!uarts[i].txfs) {
          if(uarts[i].txfd < 0)
 
            continue;
            continue;
 
                }
 
 
          /* Transmit */
          /* Transmit */
          if (uarts[i].istat.txser == EMPTY)
                if (uarts[i].istat.txser == EMPTY) {
            {
 
              uarts[i].regs.lsr |= UART_LSR_TXBUFE;
              uarts[i].regs.lsr |= UART_LSR_TXBUFE;
              if (uarts[i].istat.txbuf == FULL)
                        if (uarts[i].istat.txbuf == FULL) {
                {
 
                  uarts[i].iregs.txser = uarts[i].regs.txbuf;
                  uarts[i].iregs.txser = uarts[i].regs.txbuf;
                  uarts[i].istat.txser = FULL;
                  uarts[i].istat.txser = FULL;
                  uarts[i].istat.txbuf = EMPTY;
                  uarts[i].istat.txbuf = EMPTY;
                  uarts[i].regs.lsr &= ~UART_LSR_TXSERE;
                  uarts[i].regs.lsr &= ~UART_LSR_TXSERE;
                }
                                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("TX \'%c\' via UART%d...\n", uarts[i].iregs.txser, i);
              debug("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 {
                switch(send_byte(uarts[i].txfd,config.uarts[i].jitter,
                                fputc((int)uarts[i].iregs.txser, uarts[i].txfs);
                               i,(int)uarts[i].iregs.txser))
                                fflush(uarts[i].txfs);
                  {
                        }
                  case -1: /* An error occurred */
 
                    close(uarts[i].txfd);
 
                    close(uarts[i].rxfd);
 
                    uarts[i].txfd = uarts[i].rxfd = -1;
 
                    continue;
 
                  case 0:  /* The device wasn't ready */
 
                    uarts[i].istat.txser_clks = 0; /* Try again later */
 
                    break;
 
                  case 1:  /* OK...it got sent */
 
                    uarts[i].istat.txser = EMPTY;
                    uarts[i].istat.txser = EMPTY;
                    uarts[i].istat.txser_clks = 0;
                    uarts[i].istat.txser_clks = 0;
                    break;
 
                  }
 
            }
            }
 
 
          /* Receive */
          /* Receive */
          if (uarts[i].istat.rxser == EMPTY)
          if (uarts[i].istat.rxser == EMPTY)
            uarts[i].istat.rxser = FULL;
            uarts[i].istat.rxser = FULL;
          else if (uarts[i].char_clks == uarts[i].istat.rxser_clks++)
                else if (uarts[i].char_clks == uarts[i].istat.rxser_clks++) {
            {
 
              debug("Receiving via UART%d...\n", i);
              debug("Receiving via UART%d...\n", i);
              if (uarts[i].regs.mcr & UART_MCR_LOOP)
              if (uarts[i].regs.mcr & UART_MCR_LOOP)
                uarts[i].iregs.rxser = uarts[i].iregs.loopback;
                uarts[i].iregs.rxser = uarts[i].iregs.loopback;
              else
                        else if((retval = fgetc(uarts[i].rxfs)) != EOF) {
                switch(receive_byte(uarts[i].rxfd,config.uarts[i].jitter,
                                uarts[i].iregs.rxser = (char)retval;
                                    i,&uarts[i].iregs.rxser))
 
                  {
 
                  case -1: /* An error occurred */
 
                    close(uarts[i].txfd);
 
                    close(uarts[i].rxfd);
 
                    uarts[i].txfd = uarts[i].rxfd = -1;
 
                    continue;
 
                  case 0:
 
                    uarts[i].istat.rxser_clks = 0;
 
                    break;
 
                  case 1:
 
                    uarts[i].istat.rxser = EMPTY;
 
                    uarts[i].istat.rxser_clks = 0;
 
                    if (uarts[i].istat.rxbuf == FULL)
                    if (uarts[i].istat.rxbuf == FULL)
                      uarts[i].regs.lsr |= UART_LSR_OVRRUN;
                      uarts[i].regs.lsr |= UART_LSR_OVRRUN;
                    uarts[i].regs.lsr |= UART_LSR_RDRDY;
                    uarts[i].regs.lsr |= UART_LSR_RDRDY;
                    uarts[i].regs.rxbuf = uarts[i].iregs.rxser;
                    uarts[i].regs.rxbuf = uarts[i].iregs.rxser;
                    uarts[i].istat.rxbuf = FULL;
                    uarts[i].istat.rxbuf = FULL;
                    break;
 
                  }
                  }
 
                        uarts[i].istat.rxser = EMPTY;
 
                        uarts[i].istat.rxser_clks = 0;
            }
            }
 
 
          /* Loopback */
          /* Loopback */
          if (uarts[i].regs.mcr & UART_MCR_LOOP)
                if (uarts[i].regs.mcr & UART_MCR_LOOP) {
            {
 
              debug("uart_clock: Loopback\n");
              debug("uart_clock: Loopback\n");
              if ((uarts[i].regs.mcr & UART_MCR_AUX2) !=
              if ((uarts[i].regs.mcr & UART_MCR_AUX2) !=
                  ((uarts[i].regs.msr & UART_MSR_DCD) >> 4))
                  ((uarts[i].regs.msr & UART_MSR_DCD) >> 4))
                uarts[i].regs.msr |= UART_MSR_DDCD;
                uarts[i].regs.msr |= UART_MSR_DDCD;
              if ((uarts[i].regs.mcr & UART_MCR_AUX1) <
              if ((uarts[i].regs.mcr & UART_MCR_AUX1) <
Line 408... Line 290...
 
 
          /* Interrupt detection in proper priority order. */
          /* Interrupt detection in proper priority order. */
          uarts[i].regs.iir = UART_IIR_NO_INT;
          uarts[i].regs.iir = UART_IIR_NO_INT;
          if (uarts[i].regs.ier & UART_IER_RLSI &&
          if (uarts[i].regs.ier & UART_IER_RLSI &&
              uarts[i].regs.lsr & (UART_LSR_OVRRUN | UART_LSR_PARITY
              uarts[i].regs.lsr & (UART_LSR_OVRRUN | UART_LSR_PARITY
                                   | UART_LSR_FRAME | UART_LSR_BREAK))
                                        | UART_LSR_FRAME | UART_LSR_BREAK)) {
            {
 
              uarts[i].regs.iir = UART_IIR_RLSI;
              uarts[i].regs.iir = UART_IIR_RLSI;
            }
            }
          else if (uarts[i].regs.ier & UART_IER_RDI &&
          else if (uarts[i].regs.ier & UART_IER_RDI &&
                   uarts[i].regs.lsr & UART_LSR_RDRDY)
                    uarts[i].regs.lsr & UART_LSR_RDRDY) {
            {
 
              uarts[i].regs.iir = UART_IIR_RDI;
              uarts[i].regs.iir = UART_IIR_RDI;
            }
            }
          else if (uarts[i].regs.ier & UART_IER_THRI &&
          else if (uarts[i].regs.ier & UART_IER_THRI &&
                   uarts[i].regs.lsr & UART_LSR_TXBUFE)
                    uarts[i].regs.lsr & UART_LSR_TXBUFE &&
            {
                    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 &&
          else if (uarts[i].regs.ier & UART_IER_MSI &&
                   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)) {
            {
 
              uarts[i].regs.iir = UART_IIR_MSI;
              uarts[i].regs.iir = UART_IIR_MSI;
            }
            }
          if (!(uarts[i].regs.iir & UART_IIR_NO_INT))
          if (!(uarts[i].regs.iir & UART_IIR_NO_INT))
            report_interrupt(INT_UART);
            report_interrupt(INT_UART);
        }
        }
Line 439... Line 318...
void uart_status()
void uart_status()
{
{
  int i;
  int i;
 
 
  for(i = 0; i < NR_UARTS; i++) {
  for(i = 0; i < NR_UARTS; i++) {
    if (uarts[i].txfd < 0)
/*              if (!uarts[i].txfs)
      continue;
                        continue;
 
*/
    printf("\nUART%d visible registers at 0x%.8x:\n", i, uarts[i].baseaddr);
    printf("\nUART%d visible registers at 0x%.8x:\n", i, uarts[i].baseaddr);
    printf("RXBUF: %.2x  TXBUF: %.2x\n", uarts[i].regs.rxbuf, uarts[i].regs.txbuf);
    printf("RXBUF: %.2x  TXBUF: %.2x\n", uarts[i].regs.rxbuf, uarts[i].regs.txbuf);
    printf("DLL  : %.2x  DLH  : %.2x\n", uarts[i].regs.dll, uarts[i].regs.dlh);
    printf("DLL  : %.2x  DLH  : %.2x\n", uarts[i].regs.dll, uarts[i].regs.dlh);
    printf("IER  : %.2x  IIR  : %.2x\n", uarts[i].regs.ier, uarts[i].regs.iir);
    printf("IER  : %.2x  IIR  : %.2x\n", uarts[i].regs.ier, uarts[i].regs.iir);
    printf("LCR  : %.2x  MCR  : %.2x\n", uarts[i].regs.lcr, uarts[i].regs.mcr);
    printf("LCR  : %.2x  MCR  : %.2x\n", uarts[i].regs.lcr, uarts[i].regs.mcr);
Line 459... Line 338...
    printf("char_clks: %d\n", uarts[i].char_clks);
    printf("char_clks: %d\n", uarts[i].char_clks);
    printf("rxser_clks: %d  txser_clks: %d\n", uarts[i].istat.rxser_clks, uarts[i].istat.txser_clks);
    printf("rxser_clks: %d  txser_clks: %d\n", uarts[i].istat.rxser_clks, uarts[i].istat.txser_clks);
    printf("rxser: %d  txser: %d\n", uarts[i].istat.rxser, uarts[i].istat.txser);
    printf("rxser: %d  txser: %d\n", uarts[i].istat.rxser, uarts[i].istat.txser);
    printf("rxbuf: %d  txbuf: %d\n", uarts[i].istat.rxbuf, uarts[i].istat.txbuf);
    printf("rxbuf: %d  txbuf: %d\n", uarts[i].istat.rxbuf, uarts[i].istat.txbuf);
 
 
    printf("RX fd: %d  TX fd: %d\n\n", uarts[i].rxfd, uarts[i].txfd);
                printf("RX fs: %p  TX fs: %p\n\n", uarts[i].rxfs, uarts[i].txfs);
  }
 
}
 
 
 
/* Send a byte. Return 1 for OK. 0 for timeout. -1 if a
 
   system error occurred. Asynchronous port is implied by
 
   passing a negative number to the timeout field. In this
 
   case, the function will return without generating an
 
   error message if it can not send. This simulates
 
   congestion control from the external source. */
 
int send_byte(int fd,int timeout,int uart_id,int byte)
 
{
 
  struct timeval now;
 
  struct timeval until;
 
  struct pollfd set;
 
  int msecs = 0;
 
  unsigned char ch = byte;
 
 
 
  if(gettimeofday(&now,NULL) < 0)
 
    {
 
      now.tv_sec = time(NULL);
 
      now.tv_usec = 0;
 
    }
 
 
 
  until.tv_sec = now.tv_sec;
 
  if(timeout > 0)
 
    until.tv_usec = now.tv_usec + timeout*1000;
 
  else
 
    until.tv_usec = now.tv_usec;
 
 
 
  if(until.tv_usec > 999999)
 
    {
 
      until.tv_sec++;
 
      until.tv_usec -= 1000000;
 
    }
 
 
 
  msecs = timeout > 0 ? timeout : 0;
 
  set.fd = fd;
 
  set.events = POLLOUT;
 
  set.revents = 0;
 
 
 
  while(msecs >= 0)
 
    {
 
      char sTemp[256];
 
 
 
      switch(poll(&set,1,msecs))
 
        {
 
        case 1: /* We're good, or we got an error */
 
          switch(write(fd,&ch,1))
 
            {
 
            case -1:
 
              sprintf(sTemp,"UART %d TX - write",uart_id);
 
              perror(sTemp);
 
              fflush(stderr);
 
              return -1;
 
            case 0:
 
              fprintf(stderr,"UART %d TX EOF detected. Shutting down"
 
                      " to prevent endless loop.\n",uart_id);
 
              fflush(stderr);
 
              if(uarts[uart_id].txfd >= 0)
 
                close(uarts[uart_id].txfd);
 
              if(uarts[uart_id].rxfd >= 0)
 
                close(uarts[uart_id].rxfd);
 
              uarts[uart_id].txfd = uarts[uart_id].rxfd = -1;
 
              return 0;
 
            case 1:
 
              return 1;
 
            }
 
        case 0: /* We timed out. Stop the loop. */
 
          msecs = -1;
 
          break;
 
        case -1:
 
          if(errno == EINTR)
 
            {
 
              if(gettimeofday(&now,NULL) < 0)
 
                {
 
                  now.tv_sec = time(NULL);
 
                  now.tv_usec = 0;
 
                }
 
              msecs = (until.tv_sec - now.tv_sec)*1000 +
 
                until.tv_usec - now.tv_usec;
 
              continue;
 
            }
 
          else
 
            {
 
              char sTemp[256];
 
 
 
              sprintf(sTemp,"UART %d TX - poll",uart_id);
 
              perror(sTemp);
 
              fflush(stderr);
 
              return -1;
 
            }
 
        }
 
    }
    }
 
 
  if(timeout >= 0)
 
    {
 
      fprintf(stderr,"Transmit timeout occurred on UART %d. Data "
 
              "may be corrupt.\n",uart_id);
 
      fflush(stderr);
 
    }
 
  return 0;
 
}
 
 
 
/* Receive a byte. Return 1 for OK. 0 for timeout. -1 if a
 
   system error occurred. Asynchronous port is implied by
 
   passing a negative number to the timeout field. In this
 
   case, the function will return without generating an
 
   error message. */
 
int receive_byte(int fd,int timeout,int uart_id,unsigned char* byte)
 
{
 
  struct timeval now;
 
  struct timeval until;
 
  struct pollfd set;
 
  int msecs = 0;
 
 
 
  if(gettimeofday(&now,NULL) < 0)
 
    {
 
      now.tv_sec = time(NULL);
 
      now.tv_usec = 0;
 
    }
 
 
 
  until.tv_sec = now.tv_sec;
 
  if(timeout > 0)
 
    until.tv_usec = now.tv_usec + timeout*1000;
 
  else
 
    until.tv_usec = now.tv_usec;
 
 
 
  if(until.tv_usec > 999999)
 
    {
 
      until.tv_sec++;
 
      until.tv_usec -= 1000000;
 
    }
 
 
 
  msecs = timeout > 0 ? timeout : 0;
 
  set.fd = fd;
 
  set.events = POLLIN;
 
  set.revents = 0;
 
 
 
  while(msecs >= 0)
 
    {
 
      char sTemp[256];
 
 
 
      switch(poll(&set,1,msecs))
 
        {
 
        case 1: /* We're good, or we got an error */
 
          switch(read(fd,byte,1))
 
            {
 
            case -1:
 
              sprintf(sTemp,"UART %d RX - read",uart_id);
 
              perror(sTemp);
 
              fflush(stderr);
 
              return -1;
 
            case 0:
 
              fprintf(stderr,"UART %d RX EOF detected. Shutting down"
 
                      " to prevent endless loop.\n",uart_id);
 
              fflush(stderr);
 
              if(uarts[uart_id].txfd >= 0)
 
                close(uarts[uart_id].txfd);
 
              if(uarts[uart_id].rxfd >= 0)
 
                close(uarts[uart_id].rxfd);
 
              uarts[uart_id].txfd = uarts[uart_id].rxfd = -1;
 
              return 0;
 
            case 1:
 
              return 1;
 
            }
 
        case 0: /* We timed out. Stop the loop. */
 
          *byte = 0xFF;
 
          msecs = -1;
 
          break;
 
        case -1:
 
          if(errno == EINTR)
 
            {
 
              if(gettimeofday(&now,NULL) < 0)
 
                {
 
                  now.tv_sec = time(NULL);
 
                  now.tv_usec = 0;
 
                }
 
              msecs = (until.tv_sec - now.tv_sec)*1000 +
 
                until.tv_usec - now.tv_usec;
 
              continue;
 
            }
 
          else
 
            {
 
              char sTemp[256];
 
 
 
              sprintf(sTemp,"UART %d RX - poll",uart_id);
 
              perror(sTemp);
 
              fflush(stderr);
 
              return -1;
 
            }
 
        }
 
    }
 
 
 
  if(timeout >= 0)
 
    {
 
      fprintf(stderr,"Receive timeout occurred on UART %d. Data "
 
              "may be corrupt.\n",uart_id);
 
      fflush(stderr);
 
    }
 
  return 0;
 
}
}
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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