From 82e6b0217e63d5a77e7f673bc2a7c3712c84b7e6 Mon Sep 17 00:00:00 2001 From: tzafrir Date: Wed, 3 Oct 2007 16:46:13 +0000 Subject: New xpp release: r4786: * New firmware protocol version: 2.9 . * fpga_load: initial clean-ups before interface split. * genzaptelconf: Don't leave an empty directory behind (4784) * Increase xpp poll_timeout to 1000ms - useful for CentOS 4 (r4781). * Fix initialization anoyance: if AB don't answer to polls, don't waitfor_xpds, and show no waiting XPDs (r4725). * Disable dtmf_detect by default once again (r4712). * Don't check twice for asterisk to stop. The second test was done while Asterisk was still stopping (r4708). * Support building the kernel with M= instead of with SUBDIRS= , as used in some newer build systems (r4677). git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@3105 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- xpp/init_card_7_29 | 434 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 434 insertions(+) create mode 100755 xpp/init_card_7_29 (limited to 'xpp/init_card_7_29') diff --git a/xpp/init_card_7_29 b/xpp/init_card_7_29 new file mode 100755 index 0000000..255d50e --- /dev/null +++ b/xpp/init_card_7_29 @@ -0,0 +1,434 @@ +#! /usr/bin/perl -w +use strict; + +# +# $Id$ +# + +# +# Written by Oron Peled +# Copyright (C) 2006, Xorcom +# +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# See the file LICENSE in the top level of this tarball. +# + +# This script is run from the xpp kernel module upon detection +# of a new XPD. +# +# Expects the following environment variables to be set: +# XPD_BUS - bus name +# XPD_NAME - xpd name +# XPD_UNIT - xpd unit number +# XPD_SUBUNIT - xpd subunit number +# XPD_TYPE - xpd type number (from protocol reply): +# 3 - FXS +# 4 - FXO +# 6 - BRI_TE +# 7 - BRI_NT +# XPD_REVISION - xpd revision number +# +# Output data format: +# - An optional comment start with ';' or '#' until the end of line +# - Optional Blank lines are ignored +# - Fields are whitespace separated (spaces or tabs) +# +# The fields are (in command line order): +# 1. CHIP select in decimal (ignored, taken from 3 LSB's of subunit number) +# 2. Command word: +# - RD Read Direct register. +# - RS Read Sub-register. +# - WD Write Direct register. +# - WS Write Sub-register. +# 3. Register number in hexadecimal. +# 4. Subregister number in hexadecimal. (for RS and WS commands). +# 5. Data byte in hexadecimal. (for WD and WS commands only). +# + +package main; +use File::Basename; + +my $program = basename("$0"); +my $init_dir = dirname("$0"); +my $unit_id; + +sub logit { + print STDERR "$unit_id: @_\n"; +} + +# Arrange for error logging +if (-t STDERR) { + $unit_id = 'Interactive'; + logit "Interactive startup\n"; +} else { + $unit_id = "$ENV{XPD_BUS}/$ENV{XPD_NAME}"; + open (STDERR, "| logger -t $program -p kern.info") || die; + logit "Non Interactive startup\n"; +} + +package BRI; + +sub gen { + my $fmt = shift; + $| = 1; + printf "$fmt\n", @_; +} + +package BRI::Port; + +sub new { + my $pack = shift; + my $port = { @_ }; + bless $port, $pack; +} + +# zap_xhfc_su.c:995 +sub init_su { + my $port = shift; + my $portnum = $port->{PORT_NUM}; + my $port_mode_up = $port->{PORT_MODE_UP}; + my $port_mode_exch = $port->{PORT_MODE_EXCH}; + my $bri_nt = $port->{BRI_NT}; + #logit "init_su(portnum=$portnum, port_mode_up=$port_mode_up, bri_nt=$bri_nt)"; + + # Setting PLL + # R_PLL_CTRL = 0 (V_PLL_M = 0, Reset PLL, Disable PLL_ + # R_CLK_CFG = 05 (PLL clock as system clock, output it to CLK_OUT pin) + # R_PLL_P = 1 + # R_PLL_N = 6 + # R_PLL_S = 1 + # R_PLL_CTRL = 1 (V_PLL_M) + + BRI::gen "#--------------------------- init_su($portnum, $bri_nt, $port_mode_up, $port_mode_exch)"; + BRI::gen "0 WD 02 04"; + BRI::gen "0 WD 50 00"; # disable PLL + BRI::gen "0 WD 51 02"; + BRI::gen "0 WD 52 06"; + BRI::gen "0 WD 53 04"; + BRI::gen "0 WD 50 01"; # Enable PLL + BRI::gen "0 WD 02 05"; # Enable PLL + + su_sel($portnum); # select port + if ("$port_mode_up" == 1) { + $port->{CTRL3} = 0x01; # A_ST_CTRL3: V_ST_SEL = 1 + $port->{CTRL0} = 0x10; # A_SU_CTRL0: V_ST_SQ_EN = 1 + BRI::gen "0 WD 34 0F"; # A_MS_TX: + # (multiframe/superframe transmit register) + } else { + $port->{CTRL3} = 0x00; # A_ST_CTRL3: V_ST_SEL = 0 + $port->{CTRL0} = 0x00; # A_SU_CTRL0: V_ST_SQ_EN = 0 + } + if ("$bri_nt" == 1) { + $port->{CTRL0} |= 0x04; # V_SU_MD + } + # ((V_SU_EXCH)?0x80:00) (change polarity) + if($port_mode_exch) { + $port->{CTRL2} = 0x80; + } else { + $port->{CTRL2} = 0x00; + } + BRI::gen "0 WD 35 %02X", $port->{CTRL3}; # A_ST_CTRL3 + BRI::gen "0 WD 31 %02X", $port->{CTRL0}; # A_SU_CTRL0 + BRI::gen "0 WD 35 F8"; # A_ST_CTRL3 = set end of pulse control to 0xF8 + BRI::gen "0 WD 32 08"; # A_SU_CTRL1 = Ignore E-channel data + BRI::gen "0 WD 33 %02X", $port->{CTRL2}; # A_SU_CTRL2 + + # zap_xhfc_su.c:1030 in init_su() + # A_SU_CLK_DLY + my $clk_dly; + if ("$bri_nt" == 1) { + $clk_dly = 0x6C; + } else { + $clk_dly = 0x0E; + } + #logit "clk_dly=$clk_dly"; + BRI::gen "0 WD 37 %02X", "$clk_dly"; +} + +sub su_sel { + if (@_ != 1 ) { + main::logit "ERROR: su_sel() called with " . scalar(@_) . " parameters"; + exit 1; + } + my $portnum = shift; + BRI::gen "0 WD 16 %02X", $portnum; # R_SU_SEL +} + +# zap_xhfc_su.c:281 +sub xhfc_selfifo { + if (@_ != 1 ) { + main::logit "ERROR: xhfc_selfifo() called with " . scalar(@_) . " parameters"; + exit 1; + } + my $fifonum = shift; + #logit "xhfc_selfifo($fifonum)"; + BRI::gen "0 WD 0F %02X", $fifonum; + # --> WAIT UNTIL (R_STATUS & M_BUSY) == 0 +} + +# zap_xhfc_su.c:295 +sub xhfc_resetfifo() { + #logit "xhfc_resetfifo()"; + # A_INC_RES_FIFO = M_RES_FIFO | M_RES_FIFO_ERR + BRI::gen "0 WD 0E 0A"; + # --> WAIT UNTIL (R_STATUS & M_BUSY) == 0 +} + +# zap_xhfc_su.c:1040 +# Initialize fifo (called for each portnum, channel, direction) +sub setup_fifo { + my $port = shift; + my $chan = shift; + my $direction = shift; + my $conhdlc = shift; + my $subcfg = shift; + my $fifoctrl = shift; + + my $portnum = $port->{PORT_NUM}; + my $port_mode_up = $port->{PORT_MODE_UP}; + my $port_mode_exch = $port->{PORT_MODE_EXCH}; + my $bri_nt = $port->{BRI_NT}; + + BRI::gen "#--------------------------- setup_fifo($portnum, $chan, $direction)"; + # my $fifonum = 0x80 | ($portnum << 3) | ($chan << 1) | ($direction); # # MSB first + my $fifonum = ($portnum << 3) | ($chan << 1) | ($direction); # # MSB first + my $r_slot = ($portnum << 3) | ($chan << 1) | ($direction); + + # channel order workaround, swap odd and even portnums in $r_slot for PCM (chan 0, 1) only + if ("$chan" == 0 || "$chan" == 1) { + $r_slot = $r_slot ^ 0x08; + } + + my $short_portnum = $portnum & 0x03; + my $a_sl_cfg = (0x80 | ($short_portnum << 3) | ($chan << 1) | ($direction)); # receive data from STIO2, transmit to STIO1 + + #logit "setup_fifo($fifonum)"; + xhfc_selfifo $fifonum; + # A_CON_HDLC: transparent mode selection + BRI::gen "0 WD FA %02X", $conhdlc; + # A_SUBCH_CFG: subchnl params + BRI::gen "0 WD FB %02X", $subcfg; + # A_FIFO_CTRL: FIFO Control Register + BRI::gen "0 WD FF %02X", $fifoctrl; + xhfc_resetfifo; + xhfc_selfifo $fifonum; # wait for busy is builtin in this command + BRI::gen "0 WD 10 %02X", $r_slot; # R_SLOT + BRI::gen "0 WD D0 %02X", $a_sl_cfg; # A_SL_CFG + + #system("/bin/echo \"----=====NT\" \"short_portnum=\"$short_portnum \"portnum=\" $portnum \"chan=\" $chan\"======----\n\" >>/root/xortel/test_init"); +} + +# zap_xhfc_su.c:1071 +sub setup_su { + my $port = shift; + my $bchan = shift; + my $portnum = $port->{PORT_NUM}; + my $port_mode_exch = $port->{PORT_MODE_EXCH}; + my $bri_nt = $port->{BRI_NT}; + + BRI::gen "#--------------------------- setup_su($portnum, $bchan)"; + #logit "setup_su(portnum=$portnum, bchan=$bchan, port_mode_exch=$port_mode_exch, bri_nt=$bri_nt)"; + $port->{CTRL0} |= (1 << $bchan) | $bri_nt; + $port->{CTRL2} |= ($port_mode_exch << 7) | (1 << $bchan); + su_sel($portnum); # Select port + BRI::gen "0 WD 31 %02X", $port->{CTRL0}; # A_SU_CTRL0: V_B1_TX_EN | V_SU_MD | (NT/TE) + BRI::gen "0 WD 33 %02X", $port->{CTRL2}; # A_SU_CTRL2: V_B1_RX_EN +} + +sub xhfc_ph_command { + my $port = shift; + my $cmd = shift; + my $portnum = $port->{PORT_NUM}; + #logit "xhfc_ph_command(portnum=$portnum)"; + if ("$cmd" eq "HFC_L1_ACTIVATE_TE") { + su_sel($portnum); # Select port + BRI::gen "0 WD 30 60"; # A_SU_WR_STA = (M_SU_ACT & 0x03) + # (set activation) + } elsif ("$cmd" eq "HFC_L1_FORCE_DEACTIVATE_TE") { + su_sel($portnum); # Select port + BRI::gen "0 WD 30 40"; # A_SU_WR_STA = (M_SU_ACT & 0x02) + # (set deactivation) + } elsif ("$cmd" eq "HFC_L1_ACTIVATE_NT") { + su_sel($portnum); # Select port + BRI::gen "0 WD 30 E0"; # A_SU_WR_STA = (M_SU_ACT & 0x03) | 0x80 + # (set activation + NT) + } elsif ("$cmd" eq "HFC_L1_DEACTIVATE_NT") { + su_sel($portnum); # Select port + BRI::gen "0 WD 30 40"; # A_SU_WR_STA = (M_SU_ACT & 0x02) + # (set deactivation) + } +} + + +sub zthfc_startup { + my $port = shift; + my $portnum = $port->{PORT_NUM}; + my $port_mode_exch = $port->{PORT_MODE_EXCH}; + my $bri_nt = $port->{BRI_NT}; + #logit "zthfc_startup(portnum=$portnum, port_mode_exch=$port_mode_exch, bri_nt=$bri_nt)"; + + # PCM <-> ST/Up Configuration + foreach my $chan ( 0, 1 ) { + $port->setup_fifo($chan, 0, 0xFE, 0, 0);# Transparent mode, FIFO EN, ST->PCM + $port->setup_fifo($chan, 1, 0xFE, 0, 0);# Transparent mode, FIFO EN, ST->PCM + $port->setup_su($chan); # zap_xhfc_su.c:194 + } + + # Zaptel chan 2 used as HDLC D-Channel + $port->setup_fifo(2, 0, 0x05, 2, 0); # D-TX: zap_xhfc_su.c:205 + $port->setup_fifo(2, 1, 0x05, 2, 0); # D-RX: zap_xhfc_su.c:206 + # E-chan, Echo channel is ignored + + + # enable this port's state machine + su_sel($portnum); # Select port + # A_SU_WR_STA: reset port state machine + BRI::gen "0 WD 30 00"; + if ("$bri_nt" == 0) { + $port->xhfc_ph_command("HFC_L1_ACTIVATE_TE"); + } else { + $port->xhfc_ph_command("HFC_L1_ACTIVATE_NT"); + } +} + + +package main; +use Getopt::Std; + +my %opts; +getopts('o:', \%opts); + +$ENV{XPP_BASE} = '/proc/xpp'; +my $cmd = "$ENV{XPP_BASE}/$ENV{XPD_BUS}/command"; +my $output; +if ($opts{o}) { + $output = $opts{o}; +} else { + $ENV{XPD_BUS} || die "Missing XPD_BUS environment variable\n"; + $ENV{XPD_NAME} || die "Missing XPD_NAME environment variable\n"; + $ENV{XPD_TYPE} || die "Missing XPD_TYPE environment variable\n"; + $ENV{XPD_REVISION} || die "Missing XPD_REVISION environment variable\n"; + $output = "$ENV{XPP_BASE}/$ENV{XPD_BUS}/$ENV{XPD_NAME}/slics"; +} + +open(REG, ">$output") || die "Failed to open '$output': $!\n"; +select REG; + +logit "Starting '$0'"; + +#------------------------------------------- Instance detection + +# zap_xhfc_su.c:895 +sub init_xhfc() { + #logit "init_xhfc()"; + BRI::gen "#--------------------------- init_xhfc"; + BRI::gen "0 WD 0D 00"; # r_FIFO_MD: 16 fifos, + # 64 bytes for TX and RX each (FIFO mode config) + + # software reset to enable R_FIFO_MD setting + BRI::gen "0 WD 00 08"; # R_CIRM = M_SRES (soft reset) + # --> WAIT 5u + BRI::gen "0 WD 00 00"; # R_CIRM = 0 (zero it to deactivate reset) + + # amplitude + BRI::gen "0 WD 46 80"; # R_PWM_MD: (PWM output mode register) + # PWM push to zero only + BRI::gen "0 WD 39 18"; # R_PWM1: (modulator register for PWM1) + # set duty cycle + + BRI::gen "0 WD 0C 11"; # R_FIFO_THRES: (FIFO fill lvl control register) + # RX/TX threshold = 16 bytes + + # --> Wait until (R_STATUS & (M_BUSY | M_PCM_INIT)) + # M_BUSY status will be checked after fifo selection + BRI::gen "0 WD 0F 80"; + # set PCM !master mode + BRI::gen "0 WD 14 08"; # R_PCM_MD0 = PCM slave mode, F0IO duration is 2 HFC_PCLK's + + # (C4IO, F0IO are inputs) + + # set pll adjust + # WD 14 90 # R_PCM_MD0: Index value to select + # the register at address 15 + # WD 15 2C # R_PCM_MD1: V_PLL_ADJ (DPLL adjust speed), C4IO is 16.384MHz(128 time slots) + # in the last slot of PCM frame + BRI::gen "0 WS 14 98 20"; # R_PCM_MD1: V_PLL_ADJ + # (DPLL adjust speed) in the + # last slot of PCM frame + + BRI::gen "0 WD 4C 03"; # GPIOGPIO function (not PWM) on GPIO0 and GPIO1 pins + BRI::gen "0 WD 4A 03"; # Output enable for GPIO0 and GPIO1 pins +} + +my %port_type = ( + 6 => { 'BRI_NT' => 0 }, + 7 => { 'BRI_NT' => 1 } + ); + +# zap_xhfc_su.c:175 +sub main() { + #logit "main(): XPD_TYPE=$ENV{XPD_TYPE}"; + + $ENV{XPD_TYPE} || die "Missing XPD_TYPE environment variable\n"; + my $type = $port_type{$ENV{XPD_TYPE}}; + die "Bad XPD_TYPE=$ENV{XPD_TYPE}\n" unless $type; + die "Missing XPD_SUBUNIT information\n" unless defined($ENV{XPD_SUBUNIT}); + + # We must first turn off packet reception. + # + # Otherwise we mess with registers while the FPGA firmware tries to + # send us packets. + BRI::gen "0 Wm"; + + # Common initialization + if(($ENV{XPD_SUBUNIT} % 4) eq '0') { + # Turn off multi-byte packet reception before initialization started + my $chipnum = ($ENV{XPD_SUBUNIT} & 0x04) << 3; # Max 2 XHFC chips + for my $subunit (0 .. 3) { # 4 subunits per XHFC chip + my $addr = $chipnum | ($subunit << 3); + my $str = sprintf("0A 00 0F %02X C0 00 00 00 00 00\n", $addr); + open(CMD, ">$cmd") || die "Failed to open '$cmd': $!\n"; + print CMD $str; + close CMD; + } + init_xhfc; # zap_xhfc_su.c:1173 in setup_instance() + } + + # Port initialization + my $p = BRI::Port->new( + 'PORT_NUM' => $ENV{XPD_SUBUNIT}, + 'BRI_NT' => $type->{BRI_NT}, + 'PORT_MODE_UP' => 0, + 'PORT_MODE_EXCH' => 0 + ); + # zap_XHfc_su.c:1186 in setup_instance() + $p->init_su; + + $p->zthfc_startup; + + if(($ENV{XPD_SUBUNIT} % 4) eq 3) { + # Turn on multi-byte packet reception when ports initialization finished + my $chipnum = ($ENV{XPD_SUBUNIT} & 0x04) << 3; # Max 2 XHFC chips + for my $subunit (0 .. 3) { # 4 subunits per XHFC chip + my $addr = $chipnum | ($subunit << 3); + my $str = sprintf("0A 00 0F %02X 80 00 00 00 00 00\n", $addr); + open(CMD, ">$cmd") || die "Failed to open '$cmd': $!\n"; + print CMD $str; + close CMD; + } + } +} + +main; + +logit "Ending '$0'"; + +close REG; +close STDERR; +exit 0; -- cgit v1.2.3