diff options
author | tzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2006-09-04 23:53:30 +0000 |
---|---|---|
committer | tzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2006-09-04 23:53:30 +0000 |
commit | d1dca1a4fed07a51f4a2b013902eca069ae1734c (patch) | |
tree | daeb458935244fae1a2293068a46140e694fafc0 /xpp/calibrate_slics | |
parent | ee5282ac097e112e9baf1c760211e6ee0f2a4fe8 (diff) |
* Re-add calibrate_slics to the FXS initialization process
* xpp/utils: Build and install init_fxo_modes . Data is based on data from
wctdm.c . TODO: a separate daa.h?
* Fail the script if automatic calibration has failed.
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@1394 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'xpp/calibrate_slics')
-rwxr-xr-x | xpp/calibrate_slics | 314 |
1 files changed, 314 insertions, 0 deletions
diff --git a/xpp/calibrate_slics b/xpp/calibrate_slics new file mode 100755 index 0000000..f5b45f3 --- /dev/null +++ b/xpp/calibrate_slics @@ -0,0 +1,314 @@ +#!/usr/bin/perl -w + +# +# $Id:$ +# + +use strict; +use Time::HiRes qw (time alarm sleep); + +my $SlicsFile = "$ENV{XPP_BASE}/$ENV{XPD_BUS}/$ENV{XPD_NAME}/slics"; + +my @SlicNums = (0 .. 7); + +if ( ! -f $SlicsFile ) { + exit 1 +} + +sub logger($) { + print STDERR "LOG: @_\n"; + system("logger @_"); +} + +sub write_to_slic_file($) { + my $write_str = shift; + #print STDERR "[Writing string]\n".$write_str."[End String]\n"; + + open(SLICS,">$SlicsFile") or + die("Failed writing to slics file $SlicsFile"); + print SLICS $write_str; + close(SLICS); + sleep(0.001); + +} + +sub read_reg($$$) { + my $read_slic = shift; + my $read_reg = shift; + my $direct = shift; + + write_to_slic_file( + sprintf("%02x 00 00 00 R%s %02X", + 1<<$read_slic, $direct, $read_reg)); + sleep(0.001); + open(SLICS,$SlicsFile) or + die("Failed reading from slics file $SlicsFile"); + my @reply = (); + while(<SLICS>){ + #if (/^[^#]/) { + # print STDERR "answer line: $_"; + #} + if (/^SLIC_REPLY:\s+[DI]\s+reg_num=0x[[:xdigit:]]+,\s+dataH=0x([[:xdigit:]]+)\s+dataL=0x([[:xdigit:]]+)/){ + @reply = (hex($1), hex($2)); + #print STDERR "got [@reply]\n"; + last; + } + } + close(SLICS); + if ($direct eq 'I') { + return @reply; + } else { + return $reply[1]; + } +} + +# TODO: rearange arguments +sub write_reg{#($$$$$) { + my $read_slic = shift; + my $read_reg = shift; + my $direct = shift; + my $reg_val_low = shift; + my $reg_val_hi = shift; + + my $str = sprintf "%02x 00 00 00 W%s %02X %02X", + 1<<$read_slic, $direct, $read_reg, $reg_val_low; + if ($direct eq 'I') { + $str .= sprintf " %02X", $reg_val_hi; + } + #printf STDERR "Writing: $str\n"; + write_to_slic_file($str); +} + +# TODO: rearange arguments +sub write_reg_all_slics{#($$$$) { + my $read_reg = shift; + my $direct = shift; + my $reg_val_low = shift; + my $reg_val_hi = shift; + + my $str = sprintf "FF FF 00 00 W%s %02X %02X", + $direct, $read_reg, $reg_val_low; + if ($direct eq 'I') { + $str .= sprintf " %02X", $reg_val_hi; + } + printf STDERR "Writing: $str\n"; + write_to_slic_file($str); +} + +sub log_calib_params() { + for my $i (100 .. 107) { + my $line="Calib Reg $i: "; + for my $slic (@SlicNums) { + $line .= " ".read_reg($slic, $i, 'D'); + } + logger($line); + } +} + +sub init_indirect_registers() { + return write_to_slic_file("# +FF FF 00 00 WI 00 C2 55 +FF FF 00 00 WI 01 E6 51 +FF FF 00 00 WI 02 85 4B +FF FF 00 00 WI 03 37 49 + +FF FF 00 00 WI 04 33 33 +FF FF 00 00 WI 05 02 02 +FF FF 00 00 WI 06 02 02 +FF FF 00 00 WI 07 98 01 + +FF FF 00 00 WI 08 98 01 +FF FF 00 00 WI 09 11 06 +FF FF 00 00 WI 0A 02 02 +FF FF 00 00 WI 0B E5 00 + +FF FF 00 00 WI 0C 1C 0A +FF FF 00 00 WI 0D 30 7B +FF FF 00 00 WI 0E 63 00 +FF FF 00 00 WI 0F 00 00 + +FF FF 00 00 WI 10 70 78 +FF FF 00 00 WI 11 7D 00 +FF FF 00 00 WI 12 00 00 +FF FF 00 00 WI 13 00 00 + +FF FF 00 00 WI 14 F0 7E +FF FF 00 00 WI 15 60 01 +FF FF 00 00 WI 16 00 00 +FF FF 00 00 WI 17 00 20 + +FF FF 00 00 WI 18 00 20 +FF FF 00 00 WI 19 00 00 +FF FF 00 00 WI 1A 00 20 +FF FF 00 00 WI 1B 00 40 + +FF FF 00 00 WI 1C 00 10 +FF FF 00 00 WI 1D 00 36 +FF FF 00 00 WI 1E 00 10 +FF FF 00 00 WI 1F 00 02 + +FF FF 00 00 WI 20 C0 07 +FF FF 00 00 WI 21 00 26 +FF FF 00 00 WI 22 F4 0F +FF FF 00 00 WI 23 00 80 + +#FF FF 00 00 WI 24 20 03 +#FF FF 00 00 WI 25 8C 08 +#FF FF 00 00 WI 26 00 01 +#FF FF 00 00 WI 27 10 00 + +FF FF 00 00 WI 24 00 08 +FF FF 00 00 WI 25 00 08 +FF FF 00 00 WI 26 00 08 +FF FF 00 00 WI 27 00 08 + +FF FF 00 00 WI 28 00 0C +FF FF 00 00 WI 29 00 0C +FF FF 00 00 WI 2B 00 01 + +FF FF 00 00 WI 63 DA 00 +FF FF 00 00 WI 64 60 6B +FF FF 00 00 WI 65 74 00 +FF FF 00 00 WI 66 C0 79 + +FF FF 00 00 WI 67 20 11 +FF FF 00 00 WI 68 E0 3B +#"); +} + +sub init_early_direct_regs() { + return write_to_slic_file("# +FF FF 00 00 WD 08 00 +FF FF 00 00 WD 4A 34 +FF FF 00 00 WD 4B 10 +FF FF 00 00 WD 40 00 +#") +} + +my @FilterParams = (); + +sub save_indirect_filter_params() { + for my $slic (@SlicNums) { + for my $reg (35 .. 39) { + $FilterParams[$slic][$reg] = + [read_reg($slic, $reg, 'I')]; + write_reg($slic, $reg, 'I', 0, 0x80); + } + } + +} + +sub restore_indirect_filter_params() { + for my $slic (@SlicNums) { + for my $reg (35 .. 39) { + write_reg($slic, $reg, 'I', + @{$FilterParams[$slic][$reg]}); + } + } +} + +my $ManualCalibrationSleepTime = 0.04; # 40ms + +sub manual_calibrate_loop($$) { + my $write_reg = shift; + my $read_reg = shift; + + # counters to count down to (at most) 0 + my @slic_counters = (); + for my $i (0 .. $#SlicNums) { + $slic_counters[$i] = 0x1F; + } + + # start calibration: + my $calibration_in_progress = 1; + write_reg_all_slics($write_reg, 'D', 0x1F); + sleep $ManualCalibrationSleepTime; + + # wait until all slics have finished calibration, or for timeout + while ($calibration_in_progress) { + $calibration_in_progress = 0; # until proven otherwise + print STDERR "ManualCalib:: "; + for my $slic(@SlicNums) { + my $value = read_reg($slic, $read_reg, 'D'); + print STDERR " [$slic_counters[$slic]:$value]"; + if ($value != 0 && $slic_counters[$slic] >= 0) { + $calibration_in_progress = 1; + $slic_counters[$slic]--; + write_reg($slic,$write_reg,'D',$slic_counters[$slic]); + } + } + print STDERR "\n"; + # TODO: unnecessary sleep in the last round: + sleep $ManualCalibrationSleepTime; + } +} + +sub manual_calibrate() { + manual_calibrate_loop(98, 88); + manual_calibrate_loop(99, 89); +} + +sub auto_calibrate($$) { + my $calib_96 = shift; + my $calib_97 = shift; + + #log_calib_params(); + # start calibration: + write_to_slic_file( + sprintf + "FF FF 00 00 WD 61 %02X\n". + "FF FF 00 00 WD 60 %02X\n". + "", $calib_97, $calib_96 + + ); + # wait until all slics have finished calibration, or for timeout + my $end_time=time() + 2; + my $timeout=0; + CALIB_LOOP: for my $slic (@SlicNums) { + logger("checking slic $slic"); + while(1) { + my $reply; + if (($reply=read_reg($slic, 96, 'D')) == 0) { + # move to next register + logger("slic $slic calibrated"); + last; + } + print STDERR "reply: $reply\n"; + my $time=time(); + if ( $time > $end_time) { + $timeout=1; + logger("Exiting on timeout: $time is after timeout $end_time ."); + exit 1; + #last CALIB_LOOP; + } + logger("auto_calibrate not done yet: slic #$slic\n"); + sleep(0.1); + } + } + #log_calib_params(); +} + +########################################################### +# +# main +# + +# TODO: for all slics check the following reads to check communication +#read_reg($slic, 0x08, 'D'): 0x02 +#read_reg($slic, 0x0B, 'D'): 0x33 +#read_reg($slic, 0x40, 'D'): 0x00 (?) + +print STDERR "starting\n"; + +init_indirect_registers(); +print STDERR "after init_indirect_registers\n"; +init_early_direct_regs(); +print STDERR "after init_early_direct_regs\n"; +auto_calibrate(0x47, 0x1E); +print STDERR "after auto_calibrate\n"; +manual_calibrate(); +print STDERR "after manul_calibrate\n"; +auto_calibrate(0x40, 0x01); +print STDERR "after auto_calibrate 2\n"; + + |