Commit cdd68038 authored by Stefan Tauner's avatar Stefan Tauner
Browse files

fiji_scripts: make internal names of settings independent from strings in .ini file

Also,
 - no longer support FIU_CFG_BITS from .ini file,
 - rename injection to inject (about everywhere).
parent 59d0d843
## @file [FIJI.pm]
## @class [FIJI]
#
# Various constants used in the FIJI packages.
package FIJI;
# Architecture from http://www.perlmonks.org/?node_id=1072731
# Fields:
# name = key name in FIJI Settings file
# default = (optional) default value if not given in file and not determinable otherwise
my %constmap;
BEGIN {
%constmap = (
ID => {
name => "ID",
},
FIU_NUM => {
name => "FIU_NUM",
},
BAUDRATE => {
name => "BAUDRATE",
default => 115200,
},
FIU_CFG_BITS => {
name => "FIU_CFG_BITS",
default => 3,
},
TIMER_WIDTH => {
name => "TIMER_WIDTH",
default => 32,
},
ARM_DURATION_WIDTH => {
name => "ARM_DUR_WIDTH2",
},
INJECT_DURATION_WIDTH => {
name => "INJECT_DUR_WIDTH",
},
);
}
use constant \%constmap;
use constant CONSTS => \%constmap;
use base 'Exporter';
# our @EXPORT = ();
our @EXPORT = keys(%constmap);
our @EXPORT_OK = (keys(%constmap), 'CONSTS');
our %EXPORT_TAGS = (
all => \@EXPORT_OK,
default => \@EXPORT,
# log => [ grep /^LOG_/, @EXPORT_OK ], # all constants beginning with "LOG_"
);
1;
......@@ -119,7 +119,7 @@ sub reset_comm {
push(@bytes, 0x00);
# Everything else
for (my $i = 0; $i < $consts_ref->{'ARM_DURATION_WIDTH'} / 8 + $consts_ref->{'INJECTION_DURATION_WIDTH'} / 8 + 2; $i++) {
for (my $i = 0; $i < $consts_ref->{'ARM_DURATION_WIDTH'} / 8 + $consts_ref->{'INJECT_DURATION_WIDTH'} / 8 + 2; $i++) {
push(@bytes, 0x00);
}
if (_send_bitstream($port, \pack('C*', @bytes), 1000) != scalar(@bytes)) {
......@@ -141,7 +141,7 @@ sub reset_comm {
#
# \param config_ref a reference to a hash containing a FIJI configuration consisting of
# - payload: a byte array representing the FIU configuration
# - arm_duration and injection_duration (optional):
# - arm_duration and inject_duration (optional):
# initialization values for the arm and injection duration counters (minus one, actually).
# - consts: a reference to a hash representing FIJI constants (see \ref FIJI::Settings::_sanitize_consts).
# The following values are optional booleans and hence not checked:
......@@ -188,7 +188,7 @@ sub sanitize_config {
# }
# optional, positive values:
foreach my $k ('arm_duration', 'injection_duration') {
foreach my $k ('arm_duration', 'inject_duration') {
if (!exists($config_ref->{$k})) {
$logger->debug("$k not in configuration, using default 0.");
$config_ref->{$k} = 0;
......@@ -253,15 +253,15 @@ sub send_config {
push(@arm_duration_arr, ($arm_duration >> ($i * 8)) & 0xFF);
}
my $injection_duration = $config_ref->{'injection_duration'};
my $injection_duration_en = 0;
if ($injection_duration > 0) {
$injection_duration--;
$injection_duration_en = 1;
my $inject_duration = $config_ref->{'inject_duration'};
my $inject_duration_en = 0;
if ($inject_duration > 0) {
$inject_duration--;
$inject_duration_en = 1;
}
my @injection_duration_arr;
for (my $i = 0; $i < $consts_ref->{'INJECTION_DURATION_WIDTH'} / 8; $i++) {
push(@injection_duration_arr, ($injection_duration >> ($i * 8)) & 0xFF);
my @inject_duration_arr;
for (my $i = 0; $i < $consts_ref->{'INJECT_DURATION_WIDTH'} / 8; $i++) {
push(@inject_duration_arr, ($inject_duration >> ($i * 8)) & 0xFF);
}
......@@ -299,12 +299,12 @@ sub send_config {
$logger->debug("The resulting configuration payload: " . join(", ", unpack("H2" x scalar(@cfg), pack("C*",@cfg))));
my $config_byte = ($reset << 3) | ($injection_duration_en << 2) | ($arm_duration_en << 1) | ($trigger << 0);
my $config_byte = ($reset << 3) | ($inject_duration_en << 2) | ($arm_duration_en << 1) | ($trigger << 0);
my $bitstr = pack('C*', @cfg,
$id & 0xFF,
($id >> 8) & 0x7F,
@arm_duration_arr,
@injection_duration_arr,
@inject_duration_arr,
$config_byte
); # oh my.
......
......@@ -9,6 +9,8 @@ use Log::Log4perl qw(get_logger);
use Scalar::Util "looks_like_number";
use Config::Simple;
use FIJI qw(:all);
## @function read_configfile ($fiji_cfg_file)
# @brief Load the configuration file containing design constants.
#
......@@ -32,75 +34,121 @@ sub read_configfile {
return undef;
}
if (_sanitize_consts($fiji_consts) != 0) {
$fiji_consts = _sanitize_consts($fiji_consts);
if (!defined($fiji_consts)) {
$logger->error("Constants in fiji configuration invalid");
return undef;
}
return $fiji_consts;
}
## @function _sanitize_consts (%$consts_ref)
# @brief Do a sanity check on the fiji configuration hash.
# @brief Convert and sanity check FIJI Settings.
#
# This function takes a hash of FIJI Settings and converts it to the
# respective internal representation. This allows to use different
# names in the external file than within the implementation.
#
# First, this function sets some default values for missing constants if
# there is a default stored for the respective constant in FIJI.pm.
# If there is no default available it has to be a mandatory value and
# hence the function returns non-0 in that case.
#
# ARM_DURATION_WIDTH and INJECT_DURATION_WIDTH are handled different because
# they are no official FIJI Settings because there is only a single timer
# (yet). However, the Perl implementation supports independet timer widths
# named as above. If they are not given in consts_ref then the value of
# TIMER_WIDTH is used. If that is not given either the default value for
# TIMER_WIDTH is used.
#
# The second part of the function deals with sanity checks for the values
# themselves. It checks for the following conditions:
#
# \param consts_ref a reference to a hash containing following constants
# - FIU_NUM: > 0
# - FIU_CFG_BITS: > 0
# - ARM_DURATION_WIDTH, INJECTION_DURATION_WIDTH: > 0, multiple of 8
# - ARM_DURATION_WIDTH, INJECT_DURATION_WIDTH: > 0, multiple of 8
# - ID: > 0, < 2^15-1
# - BAUDRATE: > 0
#
# \returns 0 if all required constants exist and seem sane.
# \param consts_ref a reference to a hash containing some FIJI Settings
#
# \returns A new hash with all required constants in sanitized form,
# or undef on errors.
sub _sanitize_consts {
my $logger = get_logger();
my ($consts_ref) = @_;
if (ref($consts_ref) ne 'HASH') {
$logger->error("Parameter is not a reference to a hash (containing fiji constants).");
return 1;
$logger->error("Parameter is not a reference to a hash (containing FIJI constants).");
return undef;
}
# Special cases of defaults handled separately here.
# Set ARM_DURATION_WIDTH and INJECT_DURATION_WIDTH to TIMER_WIDTH (or its default)
foreach my $k ('ARM_DURATION_WIDTH', 'INJECT_DURATION_WIDTH') {
if (!exists($consts_ref->{CONSTS->{$k}->{name}})) {
if (exists($consts_ref->{'TIMER_WIDTH'})) {
$consts_ref->{CONSTS->{$k}->{name}} = $consts_ref->{'TIMER_WIDTH'};
$logger->trace(sprintf("Using TIMER_WIDTH value as default for %s (%s).", CONSTS->{$k}->{name}, $consts_ref->{'TIMER_WIDTH'}));
} else {
$consts_ref->{CONSTS->{$k}->{name}} = TIMER_WIDTH->{'default'};
$logger->trace(sprintf("Using TIMER_WIDTH default as default for %s (%s).", CONSTS->{$k}->{name}, TIMER_WIDTH->{default}));
}
}
}
foreach my $k ('FIU_NUM', 'FIU_CFG_BITS', 'ARM_DURATION_WIDTH', 'INJECTION_DURATION_WIDTH', 'ID', 'BAUDRATE') {
if (!exists($consts_ref->{$k})) {
$logger->error("$k is missing from fiji constants.");
return 1;
my $new_consts = {};
# Iterating over CONSTS hash from FIJI.pm and set defaults if need be
foreach my $k (keys(CONSTS)) {
my $ini_name = CONSTS->{$k}->{name};
if (exists($consts_ref->{$ini_name})) {
$new_consts->{$k} = $consts_ref->{$ini_name};
$logger->trace(sprintf("Copying setting %s (%s) = %s.", $k, $ini_name, $consts_ref->{$ini_name}));
} else {
if (defined(CONSTS->{$k}->{default})) {
$new_consts->{$k} = CONSTS->{$k}->{default};
$logger->trace(sprintf("Adding default constant: %s (%s) = %s.", $k, CONSTS->{$k}->{name}, CONSTS->{$k}->{default}));
} else {
$logger->error(sprintf("%s is missing from FIJI constants.", CONSTS->{$k}->{name}));
return undef;
}
}
# convert non-decimal (hexadecimal, binary, octal) values to decimal
my $orig = $consts_ref->{$k};
$consts_ref->{$k} = oct($orig) if $orig =~ /^0/;
$logger->trace("Converted value of $k (\"$orig\") to \"$consts_ref->{$k}\".") if ($orig ne $consts_ref->{$k});
if (!looks_like_number($consts_ref->{$k})) {
my $orig = $new_consts->{$k};
$new_consts->{$k} = oct($orig) if $orig =~ /^0/;
$logger->trace("Converted value of $k (\"$orig\") to \"$new_consts->{$k}\".") if ($orig ne $new_consts->{$k});
if (!looks_like_number($new_consts->{$k})) {
$logger->error("$orig does not look like a number.");
return 1;
return undef;
}
}
if (($consts_ref->{'FIU_NUM'} <= 0)) {
# check for sane values
if (($new_consts->{FIU_NUM} <= 0)) {
$logger->error("FIU_NUM is <= 0.");
return 1;
return undef;
}
if (($consts_ref->{'FIU_CFG_BITS'} <= 0)) {
if (($new_consts->{FIU_CFG_BITS} <= 0)) {
$logger->error("FIU_CFG_BITS is <= 0.");
return 1;
return undef;
}
if (($consts_ref->{'ARM_DURATION_WIDTH'} <= 0) || ($consts_ref->{'ARM_DURATION_WIDTH'} % 8 != 0)) {
$logger->error("ARM_DURATION_WIDTH is invalid ('$consts_ref->{'ARM_DURATION_WIDTH'}').");
return 1;
if (($new_consts->{ARM_DURATION_WIDTH} <= 0) || ($new_consts->{ARM_DURATION_WIDTH} % 8 != 0)) {
$logger->error("ARM_DURATION_WIDTH is invalid ($new_consts->{ARM_DURATION_WIDTH}).");
return undef;
}
if (($consts_ref->{'INJECTION_DURATION_WIDTH'} <= 0) || (($consts_ref->{'INJECTION_DURATION_WIDTH'} % 8) != 0)) {
$logger->error("INJECTION_DURATION_WIDTH is invalid ('$consts_ref->{'INJECTION_DURATION_WIDTH'}').");
return 1;
if (($new_consts->{INJECT_DURATION_WIDTH} <= 0) || (($new_consts->{INJECT_DURATION_WIDTH} % 8) != 0)) {
$logger->error("INJECT_DURATION_WIDTH is invalid ($new_consts->{INJECT_DURATION_WIDTH}).");
return undef;
}
if (($consts_ref->{'ID'} <= 0) || ($consts_ref->{'ID'} > (2**15 - 1))) {
$logger->error("ID is invalid ('$consts_ref->{'ID'}').");
return 1;
if (($new_consts->{ID} <= 0) || ($new_consts->{ID} > (2**15 - 1))) {
$logger->error("ID is invalid ($new_consts->{ID}).");
return undef;
}
if (($consts_ref->{'BAUDRATE'} <= 0)) {
if (($new_consts->{BAUDRATE} <= 0)) {
$logger->error("BAUDRATE missing is <= 0.");
return 1;
return undef;
}
return 0;
return $new_consts;
}
1;
[consts]
FIU_NUM=8
FIU_CFG_BITS=3
ARM_DURATION_WIDTH=32
INJECTION_DURATION_WIDTH=32
TIMER_WIDTH=32
ID=0x0123
BAUDRATE=115200
......@@ -9,14 +9,14 @@ use FIJI::Connection;
use FIJI::Settings;
sub test_fi_uart {
my ($port, $payload_ref, $arm_duration, $injection_duration, $trigger, $reset, $fiji_consts) = @_;
my ($port, $payload_ref, $arm_duration, $inject_duration, $trigger, $reset, $fiji_consts) = @_;
# 1.: reset FIJI HW FSM to a sane state (hopefully)
$port->reset_comm($fiji_consts);
# my @payload = map hex($_), $cfg_str =~ /(..)/g; # TODO: how to do this with unpack?
my %config = (
payload => $payload_ref,
arm_duration => $arm_duration,
injection_duration => $injection_duration,
inject_duration => $inject_duration,
trigger => $trigger,
reset => $reset,
consts => $fiji_consts,
......@@ -71,7 +71,7 @@ sub main {
# default arm duration to maximum/2
my $default_arm_dur = oct("0x" . ("FF" x ($fiji_consts->{'ARM_DURATION_WIDTH'}/8))) / 2;
printf("Enter the duration of the arm timer (default: 0x%x): ", $default_arm_dur);
printf("Enter the duration of the ARM timer (default: 0x%x): ", $default_arm_dur);
my $arm_duration = <STDIN>;
last unless defined $arm_duration;
$arm_duration =~ s/\R//g; # remove line breaks globally
......@@ -79,13 +79,13 @@ sub main {
$logger->debug("arm duration is $arm_duration.");
# default arm duration to maximum/2
my $default_inj_dur = oct("0x" . ("FF" x ($fiji_consts->{'INJECTION_DURATION_WIDTH'}/8))) / 2;
printf("Enter the duration of the injection timer (default: 0x%x): ", $default_inj_dur);
my $injection_duration = <STDIN>;
last unless defined $injection_duration;
$injection_duration =~ s/\R//g; # remove line breaks globally
$injection_duration = int((length($injection_duration) == 0) ? $default_inj_dur : oct($injection_duration));
$logger->debug("injection duration is $injection_duration.");
my $default_inj_dur = oct("0x" . ("FF" x ($fiji_consts->{'INJECT_DURATION_WIDTH'}/8))) / 2;
printf("Enter the duration of the INJECT timer (default: 0x%x): ", $default_inj_dur);
my $inject_duration = <STDIN>;
last unless defined $inject_duration;
$inject_duration =~ s/\R//g; # remove line breaks globally
$inject_duration = int((length($inject_duration) == 0) ? $default_inj_dur : oct($inject_duration));
$logger->debug("injection duration is $inject_duration.");
printf("Decide the external trigger enable (default: 0): ");
my $trigger = <STDIN>;
......@@ -101,7 +101,7 @@ sub main {
$reset = ($reset =~ /1|yes|y/i) ? 1 : 0;
$logger->debug(sprintf("reset is %sabled.", $reset == 0 ? "dis" : "en"));
if (test_fi_uart($port, \@payload, $arm_duration, $injection_duration, $trigger, $reset, $fiji_consts) != 0) {
if (test_fi_uart($port, \@payload, $arm_duration, $inject_duration, $trigger, $reset, $fiji_consts) != 0) {
$logger->error("UART transaction failed.");
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment