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

Subversion Repositories or1k

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 410 to Rev 411
    Reverse comparison

Rev 410 → Rev 411

/trunk/or1ksim/testbench/acv_uart.c
19,6 → 19,7
#define UART_MCR (UART_ADDR + 4)
#define UART_LSR (UART_ADDR + 5)
#define UART_MSR (UART_ADDR + 6)
#define UART_SCR (UART_ADDR + 7)
 
#define UART_DLL (UART_ADDR + 0)
#define UART_DLH (UART_ADDR + 1)
48,7 → 49,7
#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 (0x%02x) ERR @ %i\n", x, __LINE__); ASSERT(!(x & LSR_ERR));}
printf ("LSR7 (0x%02x) ERR @ %i\n", x, __LINE__); ASSERT(!(x & LSR_ERR) && ((x & 0x60) != 0x40));}
#define MARK() printf ("Passed line %i\n", __LINE__)
 
#ifndef __LINE__
169,6 → 170,7
ASSERT(getreg (UART_LSR) == 0x60); //5
ASSERT(getreg (UART_MSR) == 0x00); //6
#endif
ASSERT(getreg (UART_SCR) == 0x00); //7
 
setreg(UART_LCR, LCR_DIVL); //enable latches
ASSERT(getreg (UART_DLL) == 0x00); //0
246,6 → 248,20
}
ASSERT (!(getreg (UART_LSR) & 0x1f));
}
MARK ();
 
{ /* SCR Test :))) */
int i;
setreg (UART_SCR, 0);
ASSERT (getreg (UART_SCR) == 0);
setreg (UART_SCR, 0xff);
ASSERT (getreg (UART_SCR) == 0xff);
for (i = 0; i < 16; i++) {
unsigned char tmp = 0xdead << i;
setreg (UART_SCR, tmp);
ASSERT (getreg (UART_SCR) == tmp);
}
}
MARK();
/* Other registers will be tested later, if they function correctly,
since we cannot test them now, without destroying anything. */
256,7 → 272,7
void send_recv_test ()
{
char *s;
printf ("send_recv_test: ");
printf ("send_recv_test\n");
/* Init */
MARK();
312,7 → 328,7
{
unsigned x;
char *s;
printf ("break_test: ");
printf ("break_test\n");
MARK();
/* Send a break */
401,7 → 417,7
void different_modes_test ()
{
int speed, parity, length;
printf ("different modes test");
printf ("different modes test\n");
init_8n1();
/* Init */
443,11 → 459,17
MARK();
/* Restore normal mode */
send_char ('T');
while (getreg (UART_LSR) != 0x60); /* Wait for THR to be empty */
setreg (UART_LCR, LCR_DIVL);
setreg (UART_DLH, 2 >> 8);
setreg (UART_DLL, 2 & 0xff);
setreg (UART_LCR, 0x03); /* 8N1 @ 2 */
MARK();
send_char ('T');
while (getreg (UART_LSR) != 0x60); /* Wait for THR to be empty */
MARK();
printf ("OK\n");
}
 
456,13 → 478,13
void interrupt_test ()
{
int i;
printf ("interrupt_test");
printf ("interrupt_test\n");
/* Configure UART for interrupt mode */
ASSERT(getreg (UART_IIR) == 0xc1); /* nothing should be happening */
setreg (UART_LCR, LCR_DIVL);
setreg (UART_DLH, 6 >> 8); /* Set relatively slow speed, so we can hanlde interrupts properly */
setreg (UART_DLL, 6 & 0xff);
setreg (UART_LCR, 0x03); /* 8N1 @ 2 */
setreg (UART_LCR, 0x03); /* 8N1 @ 6 */
 
setreg (UART_IER, 0x07); /* Enable interrupts: line status, THR empty, data ready */
setreg (UART_FCR, 0x01); /* Set trigger level = 1 char, fifo should not be reset */
587,6 → 609,7
ASSERT (int_iir == 0xc6);
ASSERT (int_lsr == 0xf9); /* BE flag should be set */
ASSERT (getreg (UART_LSR) == 0x61); /* BE flag should be cleared by previous read */
MARK();
recv_char (0);
MARK();
598,9 → 621,9
MARK();
/* Wait for acknowledge */
int_rbr = '$';
while (!int_cnt); /* Wait for DR */
while (!int_cnt); /* Wait for timeout */
ASSERT (--int_cnt == 0);
ASSERT (int_iir == 0xc4);
ASSERT (int_iir == 0xcc);
ASSERT (int_lsr == 0x61);
MARK();
624,15 → 647,115
MARK();
 
send_char ('T');
while (!int_cnt); /* Wait for THR to be empty */
ASSERT (--int_cnt == 0);
ASSERT (int_iir == 0xc2);
ASSERT ((int_lsr & 0xbe) == 0x20);
MARK();
 
setreg (UART_IER, 0x00); /* Disable interrupts */
ASSERT (int_cnt == 0); /* no interrupts should be pending */
NO_ERROR ();
/* TODO: check if trigger is set up on full fifo */
while (getreg (UART_LSR) != 0x60); /* wait till we sent everynthing and then change mode */
setreg (UART_LCR, LCR_DIVL);
setreg (UART_DLH, 2 >> 8); /* Set relatively slow speed, so we can hanlde interrupts properly */
setreg (UART_DLL, 2 & 0xff);
setreg (UART_LCR, 0x03); /* 8N1 @ 2 */
send_char ('T');
MARK ();
printf ("OK\n");
}
 
/* Test if all control bits are set correctly. Lot of this was already tested
elsewhere and tests are not duplicated. */
 
void control_register_test ()
{
/* RBR already tested in send_recv_test() */
/* THR already tested in send_recv_test() */
/* IER already tested in interrupt_test() */
/* IIR already tested in interrupt_test() */
/* FCR0 - uart 16450 specific, not tested */
/* FCR1 - reset rx FIFO */
send_char ('*');
NO_ERROR ();
while (!(getreg (UART_LSR) & 0x01)); /* Wait for data ready */
setreg (UART_FCR, 2); /* Clears rx fifo */
ASSERT (getreg (UART_LSR) == 0x60); /* nothing happening */
send_char ('!');
recv_char ('!');
MARK ();
/* FCR2 - reset tx FIFO */
send_char ('1');
send_char ('2');
setreg (UART_FCR, 4); /* Should clear '2' from fifo, but '1' should be sent OK */
ASSERT (getreg (UART_LSR) == 0x00); /* we should still be sending '1' */
NO_ERROR();
send_char ('*');
recv_char ('*');
MARK ();
/* LCR already tested in different_modes_test () */
/* TODO: MSR */
/* LSR already tested in different_modes_test () and interrupt_test() */
/* SCR already tested in register_test () */
MARK ();
printf ("OK\n");
}
 
/* Tests parity error and frane error behaviour */
 
void line_error_test ()
{
printf ("line_error_test\n");
/* Test framing error if we change speed */
setreg (UART_LCR, LCR_DIVL);
setreg (UART_DLH, 2 >> 8);
setreg (UART_DLL, 2 & 0xff);
setreg (UART_LCR, 0x03); /* 8N1 @ 2 */
MARK();
send_char ('c');
ASSERT (int_cnt == 0);
setreg (UART_IER, 0x04); /* Enable interrupts: line status */
while (!int_cnt); /* Wait for THR to be empty */
ASSERT (--int_cnt == 0);
ASSERT (int_iir == 0xc6);
ASSERT (int_lsr == 0xe9); /* Framing error and FIFO error */
getreg (UART_RBR); /* Ignore the data */
MARK ();
recv_char ('b');
MARK ();
 
#if COMPLETE
/* Test framing error if we change stop bits */
send_char ('*');
while (getreg (UART_LSR)); /* wait till we sent everynthing and then change mode */
setreg (UART_LCR, 0x07); /* 8N2 */
send_char ('*');
MARK ();
 
ASSERT (int_cnt == 0);
setreg (UART_IER, 0x04); /* Enable interrupts: line status */
while (!int_cnt); /* Wait for THR to be empty */
ASSERT (--int_cnt == 0);
ASSERT (int_iir == 0xc6);
ASSERT (int_lsr == 0xe9); /* Framing error and FIFO error */
getreg (UART_RBR); /* Ignore the data */
recv_char ('b');
MARK();
#endif
 
MARK ();
printf ("OK\n");
}
 
int main ()
{
/* Use our low priority interrupt handler */
640,23 → 763,21
/* Enable interrupts */
mtspr (SPR_SR, mfspr(SPR_SR) | SPR_SR_EXR | SPR_SR_EIR);
mtspr(SPR_PICMR, mfspr(SPR_PICMR) | (0x00000001L << UART_INT_LINE));
mtspr (SPR_PICMR, mfspr(SPR_PICMR) | (0x00000001L << UART_INT_LINE));
 
// register_test ();
register_test ();
init_8n1 ();
// send_recv_test ();
// break_test ();
// different_modes_test ();
interrupt_test ();
/*control_register_test ();
loopback_send_rcv_test ();
fifo_test ();
loopback_test ();
// interrupt_test ();
// control_register_test ();
line_error_test ();
 
/* loopback_test ();
modem_test ();
line_error_test ();
speed_error_test ();
frame_error_test ();
modem_error_test ();*/
recv_char ('@');
printf ("ALL TESTS PASSED\n");
return 0;
}
/trunk/or1ksim/peripheral/16450.c
99,11 → 99,7
} else
uarts[chipsel].regs.txbuf[uarts[chipsel].istat.txbuf_head] = value;
 
if (uarts[chipsel].istat.txbuf_full < uarts[chipsel].fifo_len)
uarts[chipsel].regs.lsr &= ~UART_LSR_TXBUFE;
else
uarts[chipsel].regs.lsr |= UART_LSR_TXBUFE;
uarts[chipsel].regs.lsr &= ~UART_LSR_TXSERE;
uarts[chipsel].regs.lsr &= ~(UART_LSR_TXSERE | UART_LSR_TXBUFE);
 
uarts[chipsel].istat.thre_int = 0;
break;
116,10 → 112,12
if (value & UART_FCR_RTXFI) {
uarts[chipsel].istat.txbuf_head = uarts[chipsel].istat.txbuf_tail = 0;
uarts[chipsel].istat.txbuf_full = 0;
uarts[chipsel].regs.lsr &= ~UART_LSR_TXBUFE;
}
if (value & UART_FCR_RRXFI) {
uarts[chipsel].istat.rxbuf_head = uarts[chipsel].istat.rxbuf_tail = 0;
uarts[chipsel].istat.rxbuf_full = 0;
uarts[chipsel].regs.lsr &= ~UART_LSR_RDRDY;
}
break;
case UART_IER:
314,6 → 312,22
uarts[uart].istat.txser_clks = 0;
}
 
/* Adds a character to the FIFO */
 
void uart_add_char (int uart, int ch)
{
if (uarts[uart].istat.rxbuf_full + 1 > uarts[uart].fifo_len)
uarts[uart].regs.lsr |= UART_LSR_OVRRUN | UART_LSR_RXERR;
else {
debug(4, "add %02x\n", ch);
uarts[uart].regs.rxbuf[uarts[uart].istat.rxbuf_head] = ch;
uarts[uart].istat.rxbuf_head = (uarts[uart].istat.rxbuf_head + 1) % uarts[uart].fifo_len;
uarts[uart].istat.rxbuf_full++;
}
uarts[uart].regs.lsr |= UART_LSR_RDRDY;
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. */
387,7 → 401,6
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))
uarts[i].regs.lsr &= ~UART_LSR_BREAK;
uarts[i].istat.break_set = 0;
}
434,23 → 447,14
uarts[i].vapi.cur_break_cnt++;
if (uarts[i].vapi.cur_break_cnt > UART_BREAK_COUNT * uarts[i].vapi.char_clks) {
if (!uarts[i].istat.break_set) {
unsigned lsr;
uarts[i].istat.break_set = 1;
uarts[i].regs.lsr |= UART_LSR_BREAK | UART_LSR_FRAME | UART_LSR_RXERR | UART_LSR_RDRDY;
if (uarts[i].regs.lcr & UART_LCR_PARITY) uarts[i].regs.lsr |= UART_LSR_PARITY;
lsr = UART_LSR_BREAK | UART_LSR_FRAME | UART_LSR_RXERR | UART_LSR_RDRDY;
if (uarts[i].regs.lcr & UART_LCR_PARITY) lsr |= UART_LSR_PARITY;
printf ("[%x]\n", uarts[i].regs.lsr);
uarts[i].istat.rxser_full = 0;
uarts[i].istat.rxser_clks = 0;
if (uarts[i].istat.rxbuf_full + 1 > uarts[i].fifo_len)
uarts[i].regs.lsr |= UART_LSR_OVRRUN | UART_LSR_RXERR;
else {
uarts[i].regs.rxbuf[uarts[i].istat.rxbuf_head] = 0;
debug(4, "add %02x\n", 0);
uarts[i].istat.rxbuf_head = (uarts[i].istat.rxbuf_head + 1) % uarts[i].fifo_len;
uarts[i].istat.rxbuf_full++;
}
uarts[i].regs.lsr |= UART_LSR_RDRDY;
uarts[i].istat.timeout_count = 0;
uart_add_char (i, lsr << 8);
} else
uarts[i].vapi.cur_break_cnt = 0;
}
461,21 → 465,12
} else {
if (uarts[i].istat.rxser_full) {
if (uarts[i].char_clks <= uarts[i].istat.rxser_clks++) {
uarts[i].iregs.rxser &= ((1 << ((uarts[i].regs.lcr & 3) + 5)) - 1);
/* Set unused character bits to zero and allow lsr register in fifo */
uarts[i].iregs.rxser &= ((1 << ((uarts[i].regs.lcr & 3) + 5)) - 1) | 0xff00;
debug(4, "Receiving 0x%02x'%c' via UART%d...\n", uarts[i].iregs.rxser, uarts[i].iregs.rxser, i);
uarts[i].istat.rxser_full = 0;
uarts[i].istat.rxser_clks = 0;
 
if (uarts[i].istat.rxbuf_full + 1 > uarts[i].fifo_len)
uarts[i].regs.lsr |= UART_LSR_OVRRUN | UART_LSR_RXERR;
else {
debug(4, "add %02x\n", uarts[i].iregs.rxser);
uarts[i].regs.rxbuf[uarts[i].istat.rxbuf_head] = uarts[i].iregs.rxser;
uarts[i].istat.rxbuf_head = (uarts[i].istat.rxbuf_head + 1) % uarts[i].fifo_len;
uarts[i].istat.rxbuf_full++;
}
uarts[i].regs.lsr |= UART_LSR_RDRDY;
uarts[i].istat.timeout_count = 0;
uart_add_char (i, uarts[i].iregs.rxser);
}
}
}
503,6 → 498,7
case 0x00:
uarts[i].vapi.lcr = (data >> 8) & 0xff;
/* Put data into rx fifo */
uarts[i].iregs.rxser = data & 0xff;
uarts[i].vapi.char_clks = char_clks (uarts[i].vapi.dll, uarts[i].vapi.dlh, uarts[i].vapi.lcr);
if ((uarts[i].vapi.lcr & ~UART_LCR_SBC) != (uarts[i].regs.lcr & ~UART_LCR_SBC)
|| uarts[i].vapi.char_clks != uarts[i].char_clks
510,10 → 506,9
debug (3, "WARNING: unmatched VAPI (%02x) and uart (%02x) modes.\n",
uarts[i].vapi.lcr & ~UART_LCR_SBC, uarts[i].regs.lcr & ~UART_LCR_SBC);
/* Set error bits */
uarts[i].regs.lsr |= UART_LSR_FRAME | UART_LSR_RXERR;
if (uarts[i].regs.lcr & UART_LCR_PARITY) uarts[i].regs.lsr |= UART_LSR_PARITY;
uarts[i].iregs.rxser |= (UART_LSR_FRAME | UART_LSR_RXERR) << 8;
if (uarts[i].regs.lcr & UART_LCR_PARITY) uarts[i].iregs.rxser |= UART_LSR_PARITY << 8;
}
uarts[i].iregs.rxser = data & 0xff;
uarts[i].istat.rxser_full = 1;
received = 1;
break;
565,6 → 560,13
if (uarts[i].regs.lsr & UART_LSR_RDRDY)
uarts[i].istat.timeout_count++;
/* Update LSR error bits from the ones from rx FIFO */
if (uarts[i].istat.rxbuf_full) {
uarts[i].regs.lsr |= uarts[i].regs.rxbuf[uarts[i].istat.rxbuf_tail] >> 8;
/* we must delete the lsr status, so that we can clear it from lsr */
uarts[i].regs.rxbuf[uarts[i].istat.rxbuf_tail] &= 0xff;
}
/* Interrupt detection in proper priority order. */
uarts[i].regs.iir = UART_IIR_NO_INT;
/trunk/or1ksim/peripheral/16450.h
33,8 → 33,8
 
struct dev_16450 {
struct {
unsigned char txbuf[UART_MAX_FIFO_LEN];
unsigned char rxbuf[UART_MAX_FIFO_LEN];
unsigned txbuf[UART_MAX_FIFO_LEN];
unsigned rxbuf[UART_MAX_FIFO_LEN];
unsigned char dll;
unsigned char dlh;
unsigned char ier;
171,7 → 171,7
*/
#define UART_FCR_FIE 0x01 /* FIFO enable */
#define UART_FCR_RRXFI 0x02 /* Reset rx FIFO */
#define UART_FCR_RTXFI 0x02 /* Reset tx FIFO */
#define UART_FCR_RTXFI 0x04 /* Reset tx FIFO */
#define UART_FIFO_TRIGGER(x) /* Trigger values for indexes 0..3 */\
((x)==0?1\
:(x)==1?4\

powered by: WebSVN 2.1.0

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