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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [or1ksim/] [testbench/] [acv_uart.c] - Rev 355

Go to most recent revision | Compare with Previous | Blame | View Log

/* UART test using ACV */
 
#include "spr_defs.h"
#include "support.h"
 
#define UART_ADDR   (0x9c000000)
#define UART_RBR    (UART_ADDR + 0)
#define UART_THR    (UART_ADDR + 0)
#define UART_IER    (UART_ADDR + 1)
#define UART_IIR    (UART_ADDR + 2)
#define UART_FCR    (UART_ADDR + 2)
#define UART_LCR    (UART_ADDR + 3)
#define UART_MCR    (UART_ADDR + 4)
#define UART_LSR    (UART_ADDR + 5)
#define UART_MSR    (UART_ADDR + 6)
 
#define UART_DLL    (UART_ADDR + 0)
#define UART_DLH    (UART_ADDR + 1)
 
#define LCR_DIVL    (0x80)
#define LCR_BREAK   (0x40)
#define LCR_STICK   (0x20)
#define LCR_EVENP   (0x10)
#define LCR_PAREN   (0x08)
#define LCR_NSTOP   (0x04)
#define LCR_NBITS   (0x03)
 
#define LSR_DR      (0x01)
#define LSR_OE      (0x02)
#define LSR_PE      (0x04)
#define LSR_FE      (0x08)
#define LSR_BREAK   (0x10)
#define LSR_TXFE    (0x20)
#define LSR_TXE     (0x40)
#define LSR_ERR     (0x80)
 
/* fails if x is false */
#define ASSERT(x) ((x)?1: fail (__FUNCTION__, __LINE__))
/* Waits a few cycles that uart can prepare its data */
#define WAIT() {asm ("l.nop");asm ("l.nop");asm ("l.nop");asm ("l.nop");}
/* fails if there is an error */
#define NO_ERROR() { unsigned x = getreg (UART_LSR); if ((x & (LSR_BREAK|LSR_FE|LSR_PE|LSR_OE)) && !(x & LSR_ERR)) \
printf ("LSR7 ERR\n"); ASSERT(!(x & LSR_ERR));}
 
#ifndef __LINE__
#define __LINE__  0
#endif
 
void fail (char *func, int line)
{
#ifndef __FUNCTION__
#define __FUNCTION__ "?"
#endif
  printf ("Test failed in %s:%i\n", func, line);
  exit (1);
}
 
inline void setreg (unsigned long addr, unsigned char value)
{
  *((volatile unsigned char *)addr) = value;
}
 
inline unsigned long getreg (unsigned long addr)
{
  return *((volatile unsigned char *)addr);
}
 
void interrupt_handler ()
{
  printf ("Int\n");
}
 
/* Test reset values and r/w properties of some registers */
 
void register_test ()
{
  printf ("register test\n");
  { /* test reset values */
    ASSERT(getreg (UART_RBR) == 0x00); //0
    ASSERT(getreg (UART_IER) == 0x00); //1
    ASSERT(getreg (UART_IIR) == 0xc1); //2
    ASSERT(getreg (UART_LCR) == 0x03); //3
    ASSERT(getreg (UART_MCR) == 0x00); //4
    ASSERT(getreg (UART_LSR) == 0x60); //5
    ASSERT(getreg (UART_MSR) == 0x00); //6
 
    setreg(UART_LCR, LCR_DIVL); //enable latches
    ASSERT(getreg (UART_DLL) == 0x00); //0
    ASSERT(getreg (UART_DLH) == 0x00); //1
    setreg(UART_LCR, 0x00); //disable latches
  }
 
  { /* test if status registers are read only */
    unsigned long tmp;
    int i;
    tmp = getreg (UART_LSR);
    setreg (UART_LSR, ~tmp);
    ASSERT(getreg (UART_LSR) == tmp);
 
    for (i = 0; i < 9; i++) {
      setreg (UART_LSR, 1 < i);
      ASSERT(getreg (UART_LSR) == tmp);
    }
 
    tmp = getreg (UART_MSR);
    setreg (UART_MSR, ~tmp);
    ASSERT(getreg (UART_MSR) == tmp);
 
    for (i = 0; i < 9; i++) {
      setreg (UART_MSR, 1 < i);
      ASSERT(getreg (UART_MSR) == tmp);
    }
  }
  ASSERT (!(getreg (UART_LSR) & 0x1f));
  { /* test whether MCR is write only, be careful not to set the loopback bit */
    ASSERT(getreg (UART_MCR) == 0x00);
    setreg (UART_MCR, 0x45);
    ASSERT(getreg (UART_MCR) == 0x00);
    setreg (UART_MCR, 0xaa);
    ASSERT(getreg (UART_MCR) == 0x00);
  }
  ASSERT (!(getreg (UART_LSR) & 0x1f));
  { /* Test if Divisor latch byte holds the data */
    int i;
    setreg(UART_LCR, LCR_DIVL); //enable latches
    ASSERT(getreg (UART_LCR) == LCR_DIVL);
    for (i = 0; i < 16; i++) {
      unsigned short tmp = 0xdead << i;
      setreg (UART_DLH, tmp >> 8);
      setreg (UART_DLL, tmp & 0xff);
      ASSERT(getreg (UART_DLL) == (tmp & 0xff)); //0
      ASSERT(getreg (UART_DLH) == (tmp >> 8)); //1
    }
    ASSERT (!(getreg (UART_LSR) & 0x1f));
    for (i = 0; i < 16; i++) {
      unsigned short tmp = 0xdead << i;
      setreg (UART_DLL, tmp >> 8);
      setreg (UART_DLH, tmp & 0xff);
      ASSERT(getreg (UART_DLL) == (tmp >> 8)); //1
      ASSERT(getreg (UART_DLH) == (tmp & 0xff)); //0
    }
    setreg(UART_LCR, 0x00); //disable latches
    ASSERT(getreg (UART_LCR) == 0x00);
    ASSERT (!(getreg (UART_LSR) & 0x1f));
  }
  { /* Test LCR, if it holds our data */
    int i;
    for (i = 0; i < 6; i++) {
      unsigned short tmp = (0xde << i) & 0x3f;
      setreg (UART_LCR, tmp);
      ASSERT(getreg (UART_LCR) == tmp);
    }
    ASSERT (!(getreg (UART_LSR) & 0x1f));
  }
  /* Other registers will be tested later, if they function correctly,
     since we cannot test them now, without destroying anything.  */
}
 
/* Initializes uart and sends a few bytes to VAPI. It is then activated and send something back. */
 
void send_recv_test ()
{
  char *s;
  printf ("send_recv_test: ");
  /* Init */
  setreg (UART_IER, 0x00); /* disable interrupts */
  WAIT();
  ASSERT(getreg (UART_IIR) == 0xc1); /* nothing should be happening */
  setreg (UART_FCR, 0x06);      /* clear RX and TX FIFOs */
  setreg (UART_LCR, LCR_DIVL);
  setreg (UART_DLH, 10 >> 8);
  setreg (UART_DLL, 10 & 0xff);
  setreg (UART_LCR, 0x03);    /* 8N1 @ 10 => 160 instructions for one cycle */
  ASSERT(getreg (UART_LCR) == 0x03);
 
  //printf ("basic\n");
  ASSERT (!(getreg (UART_LSR) & LSR_DR));
 
  /* Send a string */
  s = "send_";
  while (*s) {
    /* Wait for tx fifo to be empty */
    while (!(getreg (UART_LSR) & LSR_TXFE));
    NO_ERROR();
    setreg (UART_THR, *s); /* send character */
    NO_ERROR();
    s++;
  }
  ASSERT (!(getreg (UART_LSR) & LSR_DR));
  s = "test_";
  while (*s) {
    /* Wait for tx fifo and tx to be empty */
    while (!(getreg (UART_LSR) & LSR_TXE));
    NO_ERROR();
    setreg (UART_THR, *s); /* send character */
    NO_ERROR();
    s++;
  }
  ASSERT (!(getreg (UART_LSR) & LSR_DR));
 
  /* Send characters with delay inbetween */
  s = "is_running";
  while (*s) {
    int i;
    /* Wait for tx fifo and tx to be empty */
    while (!(getreg (UART_LSR) & LSR_TXE));
    NO_ERROR();
    setreg (UART_THR, *s); /* send character */
    NO_ERROR();
    for (i = 0; i < 1600; i++) /* wait at least ten chars before sending next one */
      asm volatile ("l.nop");
    s++;
  }
 
  while (!(getreg (UART_LSR) & LSR_TXE));
  NO_ERROR();
  setreg (UART_THR, 0); /* send terminate character */
  NO_ERROR();
 
  /* Receives and compares the string */
  s = "recv_test";
  while (*s) {
    /* Wait for rx fifo to be  */
    while (!(getreg (UART_LSR) & LSR_DR));
    NO_ERROR();
    ASSERT (getreg (UART_RBR) == *s); /* compare character */
    NO_ERROR();
    s++;
  }
  printf ("OK\n");
}
 
/* sends break in both directions */
 
void break_test ()
{
  char *s;
  printf ("break_test: ");
 
  /* Send and receive break */
  NO_ERROR();
  setreg (UART_LCR, LCR_BREAK);
  while (!(getreg (UART_LSR) & LSR_BREAK));
  setreg (UART_THR, '*');
  while (getreg (UART_LSR) & LSR_BREAK);
  NO_ERROR(); /* BREAK bit should be cleared */
 
  /* Break while sending characters */
  s = "no_star";
  while (*s) {
    /* Wait for tx fifo to be empty */
    while (!(getreg (UART_LSR) & LSR_TXFE));
    NO_ERROR();
    setreg (UART_THR, *s); /* send character */
    NO_ERROR();
    s++;
  }
  ASSERT (!(getreg (UART_LSR) & LSR_DR));
  setreg (UART_THR, '*');
  /* this should break the current char, so no * should be received */
  setreg (UART_LCR, LCR_BREAK);
  /* uart should hold line long enough even if we drop it immediately */
  setreg (UART_LCR, 0);
  NO_ERROR();
 
  /* Receives and compares the string */
  s = "no_star";
  while (*s) {
    /* Wait for rx fifo to be nonempty */
    while (!(getreg (UART_LSR) & LSR_DR));
    NO_ERROR();
    ASSERT (getreg (UART_RBR) == *s); /* compare character */
    s++;
  }
  /* right now we should receive break */
  while (!(getreg (UART_LSR) & LSR_BREAK));
  setreg (UART_THR, '*');
  while (getreg (UART_LSR) & LSR_BREAK);
  NO_ERROR(); /* BREAK bit should be cleared */  
  /* we should not receive incoming characters */
  ASSERT (!(getreg (UART_LSR) & LSR_DR));
  printf ("OK\n");
}
 
void loopback_test ()
{
  printf ("loopback test\n");
  setreg (UART_MCR, 0);
}
 
int main ()
{
  /* Use our low priority interrupt handler */
  excpt_lpint = (unsigned long)interrupt_handler;
 
  /* Enable interrupts */
  mtspr (SPR_SR, mfspr(SPR_SR) | SPR_SR_EXR);
 
  register_test ();
  send_recv_test ();
  break_test ();
  /*different_modes_test ();
  loopback_send_rcv_test ();
  interrupt_test ();
  fifo_test ();
  loopback_test ();
  modem_test ();
  line_error_test ();
  speed_error_test ();
  frame_error_test ();
  modem_error_test ();*/
  printf ("ALL TESTS PASSED\n");
  return 0;
}
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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