summaryrefslogtreecommitdiff
path: root/xpp/calibrate_slics
diff options
context:
space:
mode:
authortzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-09-04 23:53:30 +0000
committertzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-09-04 23:53:30 +0000
commitd1dca1a4fed07a51f4a2b013902eca069ae1734c (patch)
treedaeb458935244fae1a2293068a46140e694fafc0 /xpp/calibrate_slics
parentee5282ac097e112e9baf1c760211e6ee0f2a4fe8 (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-xxpp/calibrate_slics314
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";
+
+