Commit 89b863b9 authored by Christian Fibich's avatar Christian Fibich Committed by Stefan Tauner
Browse files

Added 'auto' mode for fiji_download.pl

Extended test description file format (see fiji_test.cfg)
parent 65f84051
......@@ -258,52 +258,60 @@ use constant FIUMAP => \%fiumap;
my %testconstmap;
BEGIN {
%testconstmap = (
FIJI_CFG => {
ini_name => "FIJI_CFG",
default => "fiji.cfg"
},
UART => {
ini_name => "UART",
default => "/dev/ttyUSB0"
},
NUM_TESTS => {
ini_name => "NUM_TESTS",
type => 'natural',
phases_opt => [qw(download)],
phases_opt => [qw(manual)],
},
REPEAT => {
ini_name => "REPEAT",
default => 0,
type => 'boolean',
phases_opt => [qw(download)],
phases_opt => [qw(manual)],
},
REPEAT_OFFSET => {
ini_name => "REPEAT_OFFSET",
default => 0,
type => 'natural',
phases_opt => [qw(download)],
phases_opt => [qw(manual)],
},
HALT_ON_FAULT_DETECT => {
ini_name => "HALT_ON_FAULT_DETECT",
default => 1,
type => 'boolean',
phases_opt => [qw(download)],
phases_opt => [qw(manual)],
},
HALT_ON_UART_ERROR => {
ini_name => "HALT_ON_UART_ERROR",
default => 1,
type => 'boolean',
phases_opt => [qw(download)],
phases_opt => [qw(manual)],
},
HALT_ON_CRC_ERROR => {
ini_name => "HALT_ON_CRC_ERROR",
default => 1,
type => 'boolean',
phases_opt => [qw(download)],
phases_opt => [qw(manual)],
},
HALT_ON_ID_ERROR => {
ini_name => "HALT_ON_ID_ERROR",
default => 1,
type => 'boolean',
phases_opt => [qw(download)],
phases_opt => [qw(manual)],
},
HALT_ON_UNDERRUN => {
ini_name => "HALT_ON_UNDERRUN",
default => 1,
type => 'boolean',
phases_opt => [qw(download)],
phases_opt => [qw(manual)],
},
);
}
......@@ -314,27 +322,15 @@ use constant TESTCONSTMAP => \%testconstmap;
my %testpatmap;
BEGIN {
%testpatmap = (
TIMER_VALUE_1 => {
ini_name => "TIMER_VALUE_1",
type => 'natural',
phases_opt => [qw(download)], # defaults to undef
},
TIMER_VALUE_2 => {
ini_name => "TIMER_VALUE_2",
type => 'natural',
phases_opt => [qw(download)],
},
TRIGGER => {
ini_name => "TRIGGER",
default => "NONE",
values => [qw(INT EXT NONE)],
phases_opt => [qw(setup)],
values => [qw(INT EXT NONE)]
},
RESET_DUT_AFTER_CONFIG => {
ini_name => "RESET_DUT_AFTER_CONFIG",
type => 'boolean',
default => 0,
phases_opt => [qw(setup)],
default => 0
},
);
}
......@@ -342,6 +338,22 @@ BEGIN {
use constant \%testpatmap;
use constant TESTPATMAP => \%testpatmap;
my %fiuenum;
BEGIN {
%fiuenum = (
NONE => 0x0,
STUCK_AT_0 => 0x1,
STUCK_AT_1 => 0x2,
DELAY => 0x3,
SEU => 0x4,
STUCK_OPEN => 0x5
);
}
use constant \%fiuenum;
use constant FIUENUM => \%fiuenum;
## @function ini2constkey ($ini_name, %$map_ref)
#
# Allows to retrieve the reversal of the mapping established by the
......@@ -360,8 +372,8 @@ sub ini2constkey {
use base 'Exporter';
our @EXPORT = (keys(%designmap), keys(%fiumap), keys(%testpatmap), keys(%testconstmap));
our @EXPORT_OK = (keys(%designmap), 'DESIGNMAP', keys(%fiumap), 'FIUMAP', keys(%testpatmap), 'TESTPATMAP', keys(%testconstmap), 'TESTCONSTMAP');
our @EXPORT = (keys(%designmap), keys(%fiumap), keys(%testpatmap), keys(%testconstmap), keys(%fiuenum));
our @EXPORT_OK = (keys(%designmap), 'DESIGNMAP', keys(%fiumap), 'FIUMAP', keys(%testpatmap), 'TESTPATMAP', keys(%testconstmap), 'TESTCONSTMAP', keys(%fiuenum), 'FIUENUM');
## @var @EXPORT_TAGS Export Tags
#
......
This diff is collapsed.
......@@ -21,5 +21,5 @@ TIMER_WIDTH=4
BAUDRATE=115200
FIU_CFG_BITS=3
RESET_EXT_EN=0
ID=0x0123
......@@ -7,126 +7,345 @@ use Log::Log4perl qw(get_logger);
use FIJI::Connection;
use FIJI::Settings;
use FIJI::Tests;
use Data::Dumper;
use FIJI qw(:all);
my $USAGE = <<END_USAGE;
Usage: perl $0 MODE CFG
MODE manual
auto
CFG FIJI::Tests file
END_USAGE
sub test_fi_uart {
my ($port, $payload_ref, $t1_duration, $t2_duration, $trigger_en, $trigger_ext, $reset, $fiji_consts) = @_;
# my @payload = map hex($_), $cfg_str =~ /(..)/g; # TODO: how to do this with unpack?
my %config = (
payload => $payload_ref,
t1_duration => $t1_duration,
t2_duration => $t2_duration,
trigger_en => $trigger_en,
trigger_ext => $trigger_ext,
reset => $reset,
consts => $fiji_consts,
);
$port->send_config(\%config, 1000, 0, 1);
}
my (
$port, $payload_ref, $t1_duration, $t2_duration,
$trigger_en, $trigger_ext, $reset, $fiji_consts
) = @_;
# my @payload = map hex($_), $cfg_str =~ /(..)/g; # TODO: how to do this with unpack?
my %config = (
payload => $payload_ref,
t1_duration => $t1_duration,
t2_duration => $t2_duration,
trigger_en => $trigger_en,
trigger_ext => $trigger_ext,
reset => $reset,
consts => $fiji_consts,
);
$port->send_config( \%config, 1000, 0, 1 );
}
sub main {
my $logger = get_logger();
my $name = $0;
$name =~ s/\.p[lm]//;
my $cfgname = $name . ".cfg";
$logger->debug("=== Starting new execution of $name ===");
$logger->debug(sprintf("%d argument(s)%s", scalar(@_), scalar(@_) > 0 ? ": @_" : ""));
my %cfg;
if (!Config::Simple->import_from($cfgname, \%cfg)) {
$logger->fatal("Could not read config file \"$cfgname\": " . Config::Simple->error());
return 1;
}
my $fiji_settings = FIJI::Settings->new('download', $cfg{"cli.fiji_cfg"});
if (!ref($fiji_settings)) {
printf($fiji_settings . " Aborting.\n");
return 1;
}
my $fiji_consts = $fiji_settings->{'design'};
# use Data::Dumper;
# print Dumper(\%{cfg});
# print Dumper($fiji_consts);
my $portname = shift || $cfg{"cli.uart"} || "/dev/ttyUSB1";
my $port = FIJI::Connection->init($portname, $fiji_consts->{'BAUDRATE'}) or $logger->fatal("Could not init UART.") and return 1;
my $cfg_mask = 2 ** $fiji_consts->{'FIU_CFG_BITS'} - 1;
while (1) {
my $default_cfg = $cfg_mask;
my @payload;
for (my $i = 0; $i < $fiji_consts->{'FIU_NUM'}; $i++) {
for (my $t = 1; $t <= $fiji_consts->{'CFGS_PER_MSG'}; $t++) {
printf("Enter configuration for FIU #%d in t%d (default: 0x%x): ", $i, $t, $default_cfg);
my $cfg_str = <STDIN>;
last unless defined $cfg_str;
$cfg_str =~ s/\R//g; # remove line breaks globally
# $cfg_str =~ s/^0x//i; # remove optional 0x prefix
# if ($cfg_str !~ m/^[0-9A-F]+$|^$/i) {
# printf("This is not hexadecimal.\n");
# next;
# }
my $cur_cfg = (length($cfg_str) == 0) ? $default_cfg : $cfg_str;
$cur_cfg = oct($cur_cfg) if $cur_cfg =~ /^0/;
$logger->debug(sprintf("Configuration of FIU #%d in t%d is 0x%x.", $i, $t, $cur_cfg));
push(@payload, $cur_cfg);
}
my $logger = get_logger();
my $name = $0;
$name =~ s/\.p[lm]//;
my $mode = $_[0];
my $cfgname = $_[1];
my $rv;
$logger->debug("=== Starting new execution of $name ===");
$logger->debug(
sprintf( "%d argument(s)%s", scalar(@_), scalar(@_) > 0 ? ": @_" : "" )
);
if ( !defined $mode || !defined $cfgname ) {
print $USAGE;
return -1;
}
my $fiji_tests = FIJI::Tests->new( $mode, $cfgname );
if ( !ref($fiji_tests) ) {
printf( $fiji_tests . " Aborting.\n" );
return 1;
}
my $portname = $fiji_tests->{'design'}->{'UART'} || "/dev/ttyUSB1";
my $port =
FIJI::Connection->init( $portname, $fiji_tests->{'ext'}->{'global_settings'}->{'design'}->{'BAUDRATE'} )
or $logger->fatal("Could not init UART.")
and return 1;
if ( $mode eq "auto" ) {
$rv = _auto($fiji_tests,$port);
}
elsif ( $mode eq "manual" ) {
$rv = _manual($fiji_tests->{'ext'}->{'global_settings'}->{'design'},$port);
}
$logger->error($rv) if ( defined $rv );
printf "\n";
$logger->trace("=== Stopping execution ===");
return 0;
}
sub _auto {
my $msg;
my $logger = get_logger();
my ($fiji_tests,$port) = @_;
my $fiji_design_consts =
$fiji_tests->{'ext'}->{'global_settings'}->{'design'};
my $toff = 0;
$logger->info("Downloading in auto mode.");
while(1) {
for (my $ti = $toff; $ti < @{$fiji_tests->{'tests'} }; $ti++) {
$logger->info("Downloading test $ti.");
my $test = @{ $fiji_tests->{'tests'} }[$ti];
my @payload;
for (
my $i = 0 ;
$i <
$fiji_tests->{'ext'}->{'global_settings'}->{'design'}->{'FIU_NUM'} ;
$i++
)
{
for (
my $t = 1 ;
$t <= $fiji_tests->{'ext'}->{'global_settings'}->{'design'}
->{'CFGS_PER_MSG'} ;
$t++
)
{
my $k = "FIU_${i}_PATTERN_${t}";
my $cur_cfg = FIUENUM->{ $test->{$k} };
$cur_cfg = oct($cur_cfg) if $cur_cfg =~ /^0/;
$logger->debug(
sprintf(
"Configuration of FIU #%d in t%d is 0x%x.",
$i, $t, $cur_cfg
)
);
push( @payload, $cur_cfg );
}
}
my $t1_duration = $test->{'TIMER_VALUE_1'};
$t1_duration = oct($t1_duration) if $t1_duration =~ /^0/;
$logger->debug(
sprintf( "t1 duration is %d (0x%x).", $t1_duration, $t1_duration )
);
my $t2_duration = $test->{'TIMER_VALUE_2'};
$t2_duration = oct($t1_duration) if $t2_duration =~ /^0/;
$logger->debug(
sprintf( "t2 duration is %d (0x%x).", $t2_duration, $t2_duration )
);
my $trigger_en = ( $test->{'TRIGGER'} ne "NONE" ) ? 1 : 0;
my $trigger_ext = ( $test->{'TRIGGER'} eq "EXT" ) ? 1 : 0;
my $reset = $test->{'RESET_DUT_AFTER_CONFIG'};
$logger->debug(
sprintf( "trigger is %sabled.", $trigger_en == 0 ? "dis" : "en" ) );
if ( $trigger_en == 1 ) {
$logger->debug(
sprintf(
"External trigger is %sabled, internal trigger is %sabled.",
$trigger_ext == 0 ? "dis" : "en",
$trigger_ext != 0 ? "dis" : "en"
)
);
}
$logger->debug(
sprintf( "reset is %sabled.", $reset == 0 ? "dis" : "en" ) );
if (
test_fi_uart(
$port, \@payload, $t1_duration,
$t2_duration, $trigger_en, $trigger_ext,
$reset, $fiji_design_consts
) != 0
)
{
$msg = "UART transaction failed.";
# last;
}
#TODO: get return message
my $type = "READY";
my $u = 0;
my $i = 0;
my $c = 0;
my @e = ( 0, 0 );
my $halt = 0;
if ( $type eq "UNDERRUN" ) {
$logger->info( "UNDERRUN message received. HALT_ON_UNDERRUN = "
. $fiji_tests->{'design'}->{'HALT_ON_UNDERRUN'}
. "." );
$halt |= $fiji_tests->{'design'}->{'HALT_ON_UNDERRUN'};
}
if ( $u == 1 ) {
$logger->info( "UART error. HALT_ON_UART_ERROR = "
. $fiji_tests->{'design'}->{'HALT_ON_UART_ERROR'}
. "." );
$halt |= $fiji_tests->{'design'}->{'HALT_ON_UART_ERROR'};
}
if ( $i == 1 ) {
$logger->info( "ID error. HALT_ON_ID_ERROR = "
. $fiji_tests->{'design'}->{'HALT_ON_ID_ERROR'}
. "." );
$halt |= $fiji_tests->{'design'}->{'HALT_ON_ID_ERROR'};
}
if ( $c == 1 ) {
$logger->info( "CRC error. HALT_ON_ID_ERROR = "
. $fiji_tests->{'design'}->{'HALT_ON_CRC_ERROR'}
. "." );
$halt |= $fiji_tests->{'design'}->{'HALT_ON_CRC_ERROR'};
}
for my $ei ( 0 .. $#e ) {
if ( $e[$ei] == 1 ) {
$logger->info(
"FAULT detected (Bit $ei). HALT_ON_FAULT_DETECT = "
. $fiji_tests->{'design'}->{'HALT_ON_FAULT_DETECT'}
. "." );
$halt |= $fiji_tests->{'design'}->{'HALT_ON_FAULT_DETECT'};
}
}
if ( $halt == 1 ) {
$msg = "Halt because of HALT_ON_xxx. Failed test: $ti.";
last;
}
}
# default t1 is maximum/2
my $default_t1_dur = oct("0x" . ("FF" x ($fiji_consts->{'TIMER_WIDTH'}/8))) / 2;
printf("Enter duration t1 (default: 0x%x): ", $default_t1_dur);
my $t1_duration = <STDIN>;
last unless defined $t1_duration;
$t1_duration =~ s/\R//g; # remove line breaks globally
$t1_duration = int((length($t1_duration) == 0) ? $default_t1_dur : $t1_duration);
$t1_duration = oct($t1_duration) if $t1_duration =~ /^0/;
$logger->debug(sprintf("t1 duration is %d (0x%x).", $t1_duration, $t1_duration));
# default t2 duration to maximum/2
my $default_t2_dur = oct("0x" . ("FF" x ($fiji_consts->{'TIMER_WIDTH'}/8))) / 2;
printf("Enter duration t2 (default: 0x%x): ", $default_t2_dur);
my $t2_duration = <STDIN>;
last unless defined $t2_duration;
$t2_duration =~ s/\R//g; # remove line breaks globally
$t2_duration = int((length($t2_duration) == 0) ? $default_t2_dur : $t2_duration);
$t2_duration = oct($t2_duration) if $t2_duration =~ /^0/;
$logger->debug(sprintf("t2 duration is %d (0x%x).", $t2_duration, $t2_duration));
printf("Enable trigger (default: 0)? ");
my $trigger_en = <STDIN>;
last unless defined $trigger_en;
$trigger_en =~ s/\R//g; # remove line breaks globally
$trigger_en = ($trigger_en =~ /1|yes|y/i) ? 1 : 0;
$logger->debug(sprintf("trigger is %sabled.", $trigger_en == 0 ? "dis" : "en"));
my $trigger_ext = 0;
if ($trigger_en) {
printf("Use external/not internal trigger (default: 0)? ");
$trigger_ext = <STDIN>;
last unless defined $trigger_ext;
$trigger_ext =~ s/\R//g; # remove line breaks globally
$trigger_ext = ($trigger_ext =~ /1|yes|y/i) ? 1 : 0;
$logger->debug(sprintf("External trigger is %sabled, internal trigger is %sabled.", $trigger_ext == 0 ? "dis" : "en", $trigger_ext != 0 ? "dis" : "en"));
if($fiji_tests->{'design'}->{'REPEAT'} == 0) {
last;
} else {
$toff = $fiji_tests->{'design'}->{'REPEAT_OFFSET'};
$logger->info("Repeat tests beginning with $toff.");
}
}
return $msg;
}
sub _manual {
my $msg;
my $logger = get_logger();
my ($fiji_design_consts,$port) = @_;
$logger->info("Downloading in manual mode.");
while (1) {
my $cfg_mask = 2**$fiji_design_consts->{'FIU_CFG_BITS'} - 1;
my $default_cfg = $cfg_mask;
my @payload;
for ( my $i = 0 ; $i < $fiji_design_consts->{'FIU_NUM'} ; $i++ ) {
for ( my $t = 1 ; $t <= $fiji_design_consts->{'CFGS_PER_MSG'} ; $t++ ) {
printf(
"Enter configuration for FIU #%d in t%d (default: 0x%x): ",
$i, $t, $default_cfg );
my $cfg_str = <STDIN>;
last unless defined $cfg_str;
$cfg_str =~ s/\R//g; # remove line breaks globally
# $cfg_str =~ s/^0x//i; # remove optional 0x prefix
# if ($cfg_str !~ m/^[0-9A-F]+$|^$/i) {
# printf("This is not hexadecimal.\n");
# next;
# }
my $cur_cfg =
( length($cfg_str) == 0 ) ? $default_cfg : $cfg_str;
$cur_cfg = oct($cur_cfg) if $cur_cfg =~ /^0/;
$logger->debug(
sprintf(
"Configuration of FIU #%d in t%d is 0x%x.",
$i, $t, $cur_cfg
)
);
push( @payload, $cur_cfg );
}
}
# default t1 is maximum/2
my $default_t1_dur =
oct( "0x" . ( "FF" x ( $fiji_design_consts->{'TIMER_WIDTH'} / 8 ) ) ) / 2;
printf( "Enter duration t1 (default: 0x%x): ", $default_t1_dur );
my $t1_duration = <STDIN>;
last unless defined $t1_duration;
$t1_duration =~ s/\R//g; # remove line breaks globally
$t1_duration =
int( ( length($t1_duration) == 0 ) ? $default_t1_dur : $t1_duration );
$t1_duration = oct($t1_duration) if $t1_duration =~ /^0/;
$logger->debug(
sprintf( "t1 duration is %d (0x%x).", $t1_duration, $t1_duration )
);
# default t2 duration to maximum/2
my $default_t2_dur =
oct( "0x" . ( "FF" x ( $fiji_design_consts->{'TIMER_WIDTH'} / 8 ) ) ) / 2;
printf( "Enter duration t2 (default: 0x%x): ", $default_t2_dur );
my $t2_duration = <STDIN>;
last unless defined $t2_duration;
$t2_duration =~ s/\R//g; # remove line breaks globally
$t2_duration =
int( ( length($t2_duration) == 0 ) ? $default_t2_dur : $t2_duration );
$t2_duration = oct($t2_duration) if $t2_duration =~ /^0/;
$logger->debug(
sprintf( "t2 duration is %d (0x%x).", $t2_duration, $t2_duration )
);
printf("Enable trigger (default: 0)? ");
my $trigger_en = <STDIN>;
last unless defined $trigger_en;
$trigger_en =~ s/\R//g; # remove line breaks globally
$trigger_en = ( $trigger_en =~ /1|yes|y/i ) ? 1 : 0;
$logger->debug(
sprintf( "trigger is %sabled.", $trigger_en == 0 ? "dis" : "en" ) );
my $trigger_ext = 0;
if ($trigger_en) {
printf("Use external/not internal trigger (default: 0)? ");
$trigger_ext = <STDIN>;
last unless defined $trigger_ext;
$trigger_ext =~ s/\R//g; # remove line breaks globally
$trigger_ext = ( $trigger_ext =~ /1|yes|y/i ) ? 1 : 0;
$logger->debug(
sprintf(
"External trigger is %sabled, internal trigger is %sabled.",
$trigger_ext == 0 ? "dis" : "en",
$trigger_ext != 0 ? "dis" : "en"
)
);
}
printf("Enable reset (default: 0)? ");
my $reset = <STDIN>;
last unless defined $reset;
$reset =~ s/\R//g; # remove line breaks globally
$reset = ($reset =~ /1|yes|y/i) ? 1 : 0;
$logger->debug(sprintf("reset is %sabled.", $reset == 0 ? "dis" : "en"));
printf("Enable reset (default: 0)? ");
my $reset = <STDIN>;
last unless defined $reset;
$reset =~ s/\R//g; # remove line breaks globally
$reset = ( $reset =~ /1|yes|y/i ) ? 1 : 0;
$logger->debug(
sprintf( "reset is %sabled.", $reset == 0 ? "dis" : "en" ) );
if (test_fi_uart($port, \@payload, $t1_duration, $t2_duration, $trigger_en, $trigger_ext, $reset, $fiji_consts) != 0) {
$logger->error("UART transaction failed.");
if (
test_fi_uart(
$port, \@payload, $t1_duration, $t2_duration,
$trigger_en, $trigger_ext, $reset, $fiji_design_consts
) != 0
)
{
$msg = "UART transaction failed.";
last;
}
}
}
printf "\n";
$logger->trace("=== Stopping execution ===");
return 0;
return $msg;
}
Log::Log4perl::init_and_watch('logger.conf', 'HUP');
Log::Log4perl::init_and_watch( 'logger.conf', 'HUP' );
exit main(@ARGV);
; Config::Simple 4.58
; Thu Jun 11 14:56:45 2015
[TEST2]
TIMER_VALUE_1=0
FIU_0_PATTERN_1=NONE
RESET_DUT_AFTER_CONFIG=0
TIMER_VALUE_2=0
TRIGGER=NONE
FIU_0_PATTERN_2=NONE
[TEST0]
TIMER_VALUE_2=0
RESET_DUT_AFTER_CONFIG=1
FIU_0_PATTERN_1=NONE
TIMER_VALUE_1=0
FIU_0_PATTERN_2=NONE
TRIGGER=NONE
[CONSTS]
HALT_ON_UNDERRUN=1
REPEAT=1