📄 uart_test_stim.pl
字号:
#!/usr/bin/perl
use strict;
# Create stimulus/test file for 16550/16750 compatible UART cores
#
# Author: Sebastian Witt
# Date: 06.02.2008
# Version: 1.4
# License: GPL
#
# History: 1.0 - Initial version
# 1.1 - Update
# 1.2 - FIFO test update
# 1.3 - Automatic flow control tests
# 1.4 - FIFO 64 tests
#
#
# Global control settings
#
use constant CYCLE => 30e-9; # Cycle time
#use constant CYCLE => 1e-9; # Cycle time
use constant LOCAL_LOOP => 1; # Use UART local loopback
use constant INITREGS => 1; # Initialize registers
use constant TEST_CONTROL => 1; # Test control lines
use constant TEST_INTERRUPT => 1; # Test interrupts
use constant TEST_DEFAULT => 1; # Test standard modes
use constant TEST_FIFO => 1; # Test 64 byte FIFO mode
use constant TEST_FIFO64 => 1; # Test 64 byte FIFO mode
use constant TEST_AFC => 1; # Test automatic flow control
use constant UART_ADDRESS => 0x3f8; # UART base address
# Prototypes
sub logmessage($); # Message
sub uart_write($$); # Address, Data
sub uart_read($$); # Address, Expected data
sub uart_setbaudrate($); # Baudrate
##################################################################
# Main process
##################################################################
# Register addresses
use constant {
RBR => 0x00,
DLL => 0x00,
THR => 0x00,
DLM => 0x01,
IER => 0x01,
IIR => 0x02,
FCR => 0x02,
LCR => 0x03,
MCR => 0x04,
LSR => 0x05,
MSR => 0x06,
SCR => 0x07,
};
# Register settings
use constant {
IER_ERBI => 0x01,
IER_ETBEI => 0x02,
IER_ELSI => 0x04,
IER_EDSSI => 0x08,
IIR_IP => 0x01,
IIR_NONE => 0x01,
IIR_RLSI => 0x06,
IIR_RDAI => 0x04,
IIR_CTOI => 0x0C,
IIR_THRI => 0x02,
IIR_MSRI => 0x00,
IIR_F64E => 0x20,
IIR_FE => 0xC0,
FCR_FE => 0x01,
FCR_RXFR => 0x02,
FCR_TXFR => 0x04,
FCR_DMS => 0x08,
FCR_F64E => 0x20,
FCR_RT1 => 0x00,
FCR_RT4 => 0x40,
FCR_RT8 => 0x80,
FCR_RT14 => 0xC0,
FCR_RT16 => 0x40,
FCR_RT32 => 0x80,
FCR_RT56 => 0xC0,
LCR_WLS5 => 0x00,
LCR_WLS6 => 0x01,
LCR_WLS7 => 0x02,
LCR_WLS8 => 0x03,
LCR_STB => 0x04,
LCR_PEN => 0x08,
LCR_EPS => 0x10,
LCR_SP => 0x20,
LCR_BC => 0x40,
LCR_DLAB => 0x80,
MCR_DTR => 0x01,
MCR_RTS => 0x02,
MCR_OUT1 => 0x04,
MCR_OUT2 => 0x08,
MCR_LOOP => 0x10,
MCR_AFE => 0x20,
LSR_DR => 0x01,
LSR_OE => 0x02,
LSR_PE => 0x04,
LSR_FE => 0x08,
LSR_BI => 0x10,
LSR_THRE => 0x20,
LSR_TEMT => 0x40,
LSR_RXFE => 0x80,
MSR_DCTS => 0x01,
MSR_DDSR => 0x02,
MSR_TERI => 0x04,
MSR_DDCD => 0x08,
MSR_CTS => 0x10,
MSR_DSR => 0x20,
MSR_RI => 0x40,
MSR_DCD => 0x80,
};
# Baudrate generator clock input period
use constant BAUDGENCLK => 1.8432e6;
# Current DLM/DLL register
my $divisor = 0x0000;
# Shadow registers with default values after reset
my $RBR = 0x00;
my $IER = 0x00;
my $IIR = IIR_IP;
my $FCR = 0x00;
my $LCR = 0x00;
my $MCR = 0x00;
my $LSR = LSR_THRE | LSR_TEMT;
#my $MSR = 0x00;
my $MSR = 0x0F;
my $SCR = 0x00;
# De-assert reset (if available)
waitcycle (10);
print ("#SET 0 1 1 1 1\n");
if (INITREGS) {
logmessage ("UART: Initializing...");
uart_write (IER, $IER);
uart_write (FCR, $FCR);
uart_write (LCR, $LCR);
uart_write (MCR, $MCR);
uart_write (SCR, $SCR);
}
logmessage ("UART: Checking registers after reset...");
uart_read (RBR, $RBR);
uart_read (RBR, $RBR);
uart_read (IER, $IER);
uart_read (IIR, $IIR);
uart_read (LCR, $LCR);
uart_read (MCR, $MCR);
uart_read (LSR, $LSR);
uart_read (MSR, $MSR);
uart_read (SCR, $SCR);
#logmessage ("UART: Checking SCR write/read...");
#for (my $i = 0; $i <= 0x10; $i++) {
# uart_write (SCR, $i);
# uart_read (SCR, $i);
#}
if (LOCAL_LOOP) {
logmessage ("UART: Enabling local LOOP mode...");
uart_write (MCR, MCR_LOOP);
uart_read (MCR, MCR_LOOP);
}
uart_setbaudrate (115200);
logmessage ("UART: Enabling interrupts...");
uart_write (IER, IER_ERBI | IER_ETBEI | IER_ELSI | IER_EDSSI);
uart_read (IER, IER_ERBI | IER_ETBEI | IER_ELSI | IER_EDSSI);
uart_read (IIR, IIR_THRI);
uart_read (IIR, IIR_NONE);
sub uart_check_control_lines ()
{
logmessage ("UART: Checking control lines...");
uart_write (MCR, $MCR | MCR_DTR);
uart_read (MCR, $MCR);
uart_read (IIR, IIR_MSRI);
uart_read (MSR, MSR_DSR | MSR_DDSR);
uart_read (MSR, MSR_DSR);
uart_read (IIR, IIR_NONE);
uart_write (MCR, $MCR | MCR_RTS);
uart_read (MCR, $MCR);
uart_read (IIR, IIR_MSRI);
uart_read (MSR, MSR_CTS | MSR_DSR | MSR_DCTS);
uart_read (MSR, MSR_CTS | MSR_DSR);
uart_read (IIR, IIR_NONE);
uart_write (MCR, $MCR | MCR_OUT1);
uart_read (MCR, $MCR);
uart_read (MSR, MSR_CTS | MSR_DSR | MSR_RI);
uart_read (IIR, IIR_NONE);
uart_write (MCR, $MCR & ~MCR_OUT1);
uart_read (MCR, $MCR);
uart_read (IIR, IIR_MSRI);
uart_read (MSR, MSR_CTS | MSR_DSR | MSR_TERI);
uart_read (IIR, IIR_NONE);
uart_read (MSR, MSR_CTS | MSR_DSR);
uart_write (MCR, $MCR | MCR_OUT2);
uart_read (MCR, $MCR);
uart_read (IIR, IIR_MSRI);
uart_read (MSR, MSR_CTS | MSR_DSR | MSR_DCD | MSR_DDCD);
uart_read (MSR, MSR_CTS | MSR_DSR | MSR_DCD);
uart_read (IIR, IIR_NONE);
uart_write (MCR, $MCR & ~(MCR_DTR | MCR_RTS | MCR_OUT1 | MCR_OUT2));
uart_read (MCR, $MCR);
uart_read (IIR, IIR_MSRI);
uart_read (MSR, MSR_DDSR | MSR_DCTS | MSR_DDCD);
uart_read (IIR, IIR_NONE);
}
sub uart_check_interrupt_control ()
{
logmessage ("UART: Checking interrupt priority control...");
uart_write (MCR, $MCR | MCR_DTR);
uart_write (MCR, $MCR & ~MCR_DTR);
uart_write (THR, 0x12);
uart_wait (1);
uart_write (LCR, $LCR | LCR_BC);
uart_wait (1);
uart_write (LCR, $LCR & ~LCR_BC);
uart_read (IIR, IIR_RLSI);
uart_read (LSR, LSR_DR | LSR_OE | LSR_BI | LSR_FE | LSR_THRE | LSR_TEMT);
uart_read (IIR, IIR_RDAI);
uart_read (IIR, IIR_RDAI);
uart_rrbr (0x00);
uart_write (THR, 0x34);
uart_wait (1);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_write (THR, 0x56);
uart_read (IIR, IIR_RDAI);
uart_wait (1);
uart_read (IIR, IIR_RLSI);
uart_read (LSR, LSR_DR | LSR_OE | LSR_THRE | LSR_TEMT);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_read (IIR, IIR_RDAI);
uart_rrbr (0x56);
uart_read (IIR, IIR_THRI);
uart_read (IIR, IIR_MSRI);
uart_read (IIR, IIR_MSRI);
uart_read (MSR, MSR_DDSR);
uart_read (IIR, IIR_NONE);
uart_write (THR, 0x78);
uart_wait (1);
uart_read (IIR, IIR_RDAI);
uart_rrbr (0x78);
uart_read (IIR, IIR_THRI);
uart_read (IIR, IIR_NONE);
}
sub uart_check_default ()
{
for (my $mode = 0; $mode < 0x40; $mode++) {
logmessage (sprintf ("UART: Setting LCR to 0x%02X", $mode));
uart_write (LCR, $mode);
logmessage ("UART: Transmission test single byte (FIFO disabled)");
uart_wait (1);
uart_write (THR, 0x55);
uart_wait (1);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_read (IIR, IIR_RDAI);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_rrbr (0x55);
uart_read (LSR, LSR_THRE | LSR_TEMT);
uart_read (IIR, IIR_THRI);
uart_read (IIR, IIR_NONE);
logmessage ("UART: Transmission test multiple bytes (FIFO disabled)");
for (my $i = 0; $i < 10; $i++) {
uart_read (IIR, IIR_NONE);
uart_write (THR, $i);
uart_wait (1);
uart_read (IIR, IIR_RDAI);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_rrbr ($i);
uart_read (IIR, IIR_THRI);
uart_read (LSR, LSR_THRE | LSR_TEMT);
}
#logmessage ("UART: Transmission test loop (FIFO disabled)");
#for (my $i = 0; $i < 1000; $i++) {
# if (!($i % 100)) {
# logmessage ("UART: Loop " . $i);
# }
# uart_write (THR, $i);
# uart_read (IIR, IIR_THRI);
# uart_wait (1);
# uart_read (IIR, IIR_RDAI);
# uart_rrbr ($i);
# uart_read (IIR, IIR_NONE);
#}
logmessage ("UART: Transmission test overflow (FIFO disabled)");
uart_write (THR, 0x55);
uart_wait (1);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_read (IIR, IIR_RDAI);
uart_write (THR, 0xAA);
uart_wait (1);
uart_read (IIR, IIR_RLSI);
uart_read (LSR, LSR_DR | LSR_OE | LSR_THRE | LSR_TEMT);
uart_read (IIR, IIR_RDAI);
uart_wait (1);
uart_read (IIR, IIR_RDAI);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_rrbr (0xAA);
uart_read (LSR, LSR_THRE | LSR_TEMT);
uart_read (IIR, IIR_THRI);
uart_read (IIR, IIR_NONE);
logmessage ("UART: Break control test");
uart_write (LCR, $LCR | LCR_BC);
uart_read (LCR, $LCR);
uart_wait (2);
uart_read (IIR, IIR_RLSI);
if (($LCR & LCR_PEN) && !($LCR & LCR_EPS)) {
uart_read (LSR, LSR_DR | LSR_PE | LSR_FE | LSR_BI | LSR_THRE | LSR_TEMT);
} else {
uart_read (LSR, LSR_DR | LSR_FE | LSR_BI | LSR_THRE | LSR_TEMT);
}
uart_read (IIR, IIR_RDAI);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_read (RBR, 0x00);
uart_read (IIR, IIR_NONE);
uart_read (LSR, LSR_THRE | LSR_TEMT);
uart_write (LCR, $LCR & ~LCR_BC);
uart_read (LCR, $LCR);
uart_wait (2);
uart_read (LSR, LSR_THRE | LSR_TEMT);
uart_read (IIR, IIR_NONE);
}
uart_write (LCR, 0x00);
}
sub uart_check_fifo ()
{
logmessage ("UART: Enabling FIFO...");
uart_write (FCR, FCR_FE);
uart_read (IIR, IIR_THRI | IIR_FE);
uart_read (IIR, IIR_NONE | IIR_FE);
logmessage ("UART: Testing FIFO trigger level 1 byte...");
uart_write (FCR, FCR_FE | FCR_RT1);
uart_send (1);
uart_wait (4);
uart_read (IIR, IIR_CTOI | IIR_FE);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_rrbr (0x00);
uart_read (IIR, IIR_THRI | IIR_FE);
uart_read (LSR, LSR_THRE | LSR_TEMT);
uart_read (IIR, IIR_NONE | IIR_FE);
logmessage ("UART: Testing FIFO trigger level 4 byte...");
uart_write (FCR, FCR_FE | FCR_RT4);
uart_send (3);
uart_wait (7);
uart_read (IIR, IIR_CTOI | IIR_FE);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_rrbr (0x00);
uart_send (2);
uart_wait (6);
uart_read (IIR, IIR_CTOI | IIR_FE);
uart_wait (2);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_rrbr (1);
uart_read (IIR, IIR_THRI | IIR_FE);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_read (IIR, IIR_NONE | IIR_FE);
uart_rrbr (2);
uart_rrbr (0);
uart_rrbr (1);
uart_read (LSR, LSR_THRE | LSR_TEMT);
uart_read (IIR, IIR_NONE | IIR_FE);
logmessage ("UART: Testing FIFO trigger level 8 byte...");
uart_write (FCR, FCR_FE | FCR_RT8);
uart_send (7);
uart_read (IIR, IIR_NONE | IIR_FE);
uart_wait (11);
uart_read (IIR, IIR_CTOI | IIR_FE);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_rrbr (0x00);
uart_read (IIR, IIR_THRI | IIR_FE);
uart_read (IIR, IIR_NONE | IIR_FE);
uart_send (2);
uart_wait (6);
uart_read (IIR, IIR_CTOI | IIR_FE);
uart_wait (2);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_rrbr (1);
uart_read (IIR, IIR_THRI | IIR_FE);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_read (IIR, IIR_NONE | IIR_FE);
uart_rrbr (2);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_rrbr (3);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_rrbr (4);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_rrbr (5);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_rrbr (6);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_rrbr (0);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_rrbr (1);
uart_read (LSR, LSR_THRE | LSR_TEMT);
uart_read (IIR, IIR_NONE | IIR_FE);
logmessage ("UART: Testing FIFO trigger level 14 byte...");
uart_write (FCR, FCR_FE | FCR_RT14);
uart_send (13);
uart_wait (17);
uart_read (IIR, IIR_CTOI | IIR_FE);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_rrbr (0x00);
uart_read (IIR, IIR_THRI | IIR_FE);
uart_read (IIR, IIR_NONE | IIR_FE);
uart_send (2);
uart_wait (6);
uart_read (IIR, IIR_CTOI | IIR_FE);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_rrbr (1);
uart_read (IIR, IIR_THRI | IIR_FE);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_read (IIR, IIR_NONE | IIR_FE);
uart_rrbr (2);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_rrbr (3);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_rrbr (4);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_rrbr (5);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_rrbr (6);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_rrbr (7);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_rrbr (8);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_rrbr (9);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_rrbr (10);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_rrbr (11);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_rrbr (12);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_rrbr (0);
uart_read (LSR, LSR_DR | LSR_THRE | LSR_TEMT);
uart_rrbr (1);
uart_read (LSR, LSR_THRE | LSR_TEMT);
uart_read (IIR, IIR_NONE | IIR_FE);
logmessage ("UART: Testing FIFO overrun...");
uart_write (FCR, FCR_FE | FCR_RT1);
uart_send (17);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -