RPi-WiringPi
view release on metacpan or search on metacpan
t/RPiTest.pm view on Meta::CPAN
}
# PWM -> ADS1115 feedback calibration, single-sourced here for both PWM
# feedback tests (t/109-pwm_hw_mods.t and t/140-pwm_spi_adc.t) so a hardware
# recalibration updates both in one place.
#
# %pwm_adc_windows holds the empirically calibrated ADC percent windows per
# PWM level at the default PWM range (1023), as historically carried by
# t/140. rpi_pwm_adc_window() returns the empirical window when one exists
# for the requested level/range; for any other level/range combination
# (e.g. t/109's range-2000 sweep) it falls back to the model: expected duty
# (pwm / range * 100) +/- RPI_PWM_TOLERANCE percentage points, clamped to
# 0..100. The tolerance is derived from the empirical windows, whose largest
# deviation from ideal duty is 3.35 points.
use constant RPI_PWM_TOLERANCE => 4;
my %pwm_adc_windows = (
100 => [8, 13],
200 => [18, 22],
300 => [27, 31],
400 => [36, 42],
500 => [46, 50],
600 => [58, 62],
700 => [67, 70],
800 => [75, 79],
900 => [86, 89],
1000 => [96, 100],
);
sub rpi_pwm_adc_window {
my ($pwm, $range) = @_;
if (! defined $pwm || $pwm !~ /^\d+$/){
croak "rpi_pwm_adc_window() requires the \$pwm param, and it must " .
"be an integer";
}
if (! defined $range || $range !~ /^\d+$/ || $range == 0){
croak "rpi_pwm_adc_window() requires the \$range param, and it " .
"must be a positive integer";
}
if ($range == 1023 && exists $pwm_adc_windows{$pwm}){
return @{ $pwm_adc_windows{$pwm} };
}
my $duty = $pwm / $range * 100;
my $min = $duty - RPI_PWM_TOLERANCE;
$min = 0 if $min < 0;
my $max = $duty + RPI_PWM_TOLERANCE;
$max = 100 if $max > 100;
return ($min, $max);
}
sub rpi_i2c_check {
# Gate tests that require a live I2C bus (e.g. the ADS1115 ADC). Without
# this, a test that unconditionally touches I2C dies mid-run when the bus
# is disabled, leaving stale metadata in shared memory that cascades into
# subsequent tests.
if (! $ENV{RPI_I2C}) {
plan skip_all => "RPI_I2C environment variable not set (these tests " .
"verify PWM via the I2C ADS1115; set RPI_I2C=1 when " .
"the I2C bus and ADS1115 are wired and powered)\n";
}
}
# fetch the current running test file number
sub rpi_running_test {
(my $test) = @_;
my $pi = RPi::WiringPi->new(label => 't/RPiTest.pm', shm_key => 'rpit');
$pi->meta_lock;
my $meta = $pi->meta_fetch;
if ($test =~ m|t/(\d+)-(.*)\.t|){
$meta->{testing}{test_num} = $1;
$meta->{testing}{test_name} = $2;
$pi->meta_store($meta);
$pi->meta_unlock;
$pi->cleanup;
return 0;
}
elsif ($test =~ /^-\d+/){
$meta->{testing}{test_num} = -1;
$meta->{testing}{test_name} = '';
$pi->meta_store($meta);
$pi->meta_unlock;
$pi->cleanup;
return 0;
}
croak
"rpi_running_test() couldn't translate '$test' to a usable shared format\n";
}
# get and set the availability of the OLED
sub rpi_oled_available {
my ($available) = @_;
if ($available) {
if (-e $oled_lock) {
unlink $oled_lock or die $!;
}
}
return -e $oled_lock ? 0 : 1;
}
sub rpi_oled_unavailable {
open my $wfh, '>', $oled_lock or die $!;
close $wfh;
return -e $oled_lock ? 1 : 0;
}
# test whether all pins have been reset to program start defaults
( run in 2.682 seconds using v1.01-cache-2.11-cpan-9581c071862 )