[zaptel-commits] trunk - commit revision 834

zaptel-commits at lists.digium.com zaptel-commits at lists.digium.com
Mon Nov 28 17:42:01 CST 2005


Author: markster
Date: Mon Nov 28 17:42:01 2005
New Revision: 834

URL: http://svn.digium.com/view/zaptel?rev=834&view=rev
Log:
Add support for next generation VPM400M


Modified:
    trunk/wct4xxp.c

Modified: trunk/wct4xxp.c
URL: http://svn.digium.com/view/zaptel/trunk/wct4xxp.c?rev=834&r1=833&r2=834&view=diff
==============================================================================
--- trunk/wct4xxp.c (original)
+++ trunk/wct4xxp.c Mon Nov 28 17:42:01 2005
@@ -207,6 +207,7 @@
 
 #define FLAG_2NDGEN  (1 << 3)
 #define FLAG_2PORT   (1 << 4)
+#define FLAG_VPM2GEN (1 << 5)
 
 #define CANARY 0xc0de
 
@@ -545,7 +546,7 @@
 	unsigned int digit, regval = 0;
 	unsigned int regbyte;
 	int x, i;
-	short energy;
+	short energy=0;
 	static unsigned int lastio = 0;
 	struct t4_span *ts;
 
@@ -575,10 +576,12 @@
 					base -= 4;
 				regbyte = __t4_vpm_in(wc, x, 0xa8 + i);
 				digit = vpm_digits[regbyte];
-				energy = __t4_vpm_in(wc, x, 0x58 + channel);
-				energy = ZT_XLAW(energy, ts->chans);
+				if (!(wc->tspans[0]->spanflags & FLAG_VPM2GEN)) {
+					energy = __t4_vpm_in(wc, x, 0x58 + channel);
+					energy = ZT_XLAW(energy, ts->chans);
+					ts->dtmfenergy[base] = energy;
+				}
 				ts->dtmfactive |= (1 << base);
-				ts->dtmfenergy[base] = energy;
 				if (ts->dtmfdigit[base]) {
 					if (ts->dtmfmask & (1 << base))
 						zt_qevent_lock(&ts->span.chans[base], (ZT_EVENT_DTMFUP | ts->dtmfdigit[base]));
@@ -604,6 +607,38 @@
 			}
 			regval = regval >> 1;
 		}
+		if (!(wc->tspans[0]->spanflags & FLAG_VPM2GEN))
+			continue;
+
+		/* Start of DTMF off detection process */	
+		regbyte = __t4_vpm_in(wc, x, 0xbc);
+		__t4_vpm_out(wc, x, 0xbc, regbyte); /* Write 1 to clear */
+		regval = regbyte << 8;
+		regbyte = __t4_vpm_in(wc, x, 0xbd);
+		__t4_vpm_out(wc, x, 0xbd, regbyte);
+		regval |= regbyte;
+
+		for(i = 0; (i < MAX_DTMF_DET) && regval; i++) {
+			if(regval & 0x0001) {
+				int channel = (i << 1) + (x >> 2);
+				int base = channel - 1;
+
+				if (!wc->t1e1)
+					base -= 4;
+				ts->dtmfactive &= ~(1 << base);
+				if (ts->dtmfdigit[base]) {
+					if (ts->dtmfmask & (1 << base))
+						zt_qevent_lock(&ts->span.chans[base], (ZT_EVENT_DTMFUP | ts->dtmfdigit[base]));
+				}
+				digit = ts->dtmfdigit[base];
+				ts->dtmfdigit[base] = 0;
+				if (debug)
+					printk("Digit Gone: %d, Span: %d, channel: %d, energy: %02x, 'channel %d' chip %d\n", digit, x % 4, base + 1, energy, channel, x);
+				
+			}
+			regval = regval >> 1;
+		}
+
 	}
 }
 #endif
@@ -2231,41 +2266,39 @@
 	}
 #ifdef VPM_SUPPORT
 	if (wc->vpm) {
-		if (!(wc->intcount % 16)) {
+		if (!(wc->intcount % 16) && !(wc->tspans[0]->spanflags & FLAG_VPM2GEN)) {
 			/* Check DTMF events */
-			if (wc->vpm) {
-				int span = (wc->intcount >> 4) & 0x3;
-				int y;
-				short energy;
-				int offset = 1;
-				int chip;
-				int channel;
-				struct t4_span *ts = wc->tspans[span];
-				if (!wc->t1e1)
-					offset = 5;
-				if (ts->dtmfactive) {
-					for (y = 0; y < ts->span.channels; y++) {
-						if (ts->dtmfactive & (1 << y)) {
-							channel = y + offset;
-							chip = span + ((channel & 0x1) << 2);
-							/* Have an active channel, check its energy! */
-							energy = __t4_vpm_in(wc, chip, 0x58 + channel);
-							energy = ZT_XLAW(energy, ts->span.chans);
-							if (energy < (ts->dtmfenergy[y])) {
-								if (debug & DEBUG_DTMF)
-									printk("Finished digit on span %d, channel %d (energy = %02x < %02x) 'channel' %d, chip %d!\n", span, y + 1, energy, ts->dtmfenergy[y], channel, chip);
-								if (debug & DEBUG_DTMF)	
-									printk("Finished digit '%c' on channel %d of span %d\n", ts->dtmfdigit[y], y + 1, span);
-								if (ts->dtmfmask & (1 << y))
-									zt_qevent_lock(&ts->span.chans[y], (ZT_EVENT_DTMFUP | ts->dtmfdigit[y]));
-								ts->dtmfenergy[y] = 0;
-								ts->dtmfdigit[y] = 0;
-								ts->dtmfactive &= ~(1 << y);
-							} else if (energy > (ts->dtmfenergy[y])) {
-								if (debug & DEBUG_DTMF)
-									printk("Increasing digit energy on span %d, channel %d (energy = %02x > %02x)!\n", span, y + 1, energy, ts->dtmfenergy[y]);
-								ts->dtmfenergy[y] = energy;
-							}
+			int span = (wc->intcount >> 4) & 0x3;
+			int y;
+			short energy;
+			int offset = 1;
+			int chip;
+			int channel;
+			struct t4_span *ts = wc->tspans[span];
+			if (!wc->t1e1)
+				offset = 5;
+			if (ts->dtmfactive) {
+				for (y = 0; y < ts->span.channels; y++) {
+					if (ts->dtmfactive & (1 << y)) {
+						channel = y + offset;
+						chip = span + ((channel & 0x1) << 2);
+						/* Have an active channel, check its energy! */
+						energy = __t4_vpm_in(wc, chip, 0x58 + channel);
+						energy = ZT_XLAW(energy, ts->span.chans);
+						if (energy < (ts->dtmfenergy[y])) {
+							if (debug & DEBUG_DTMF)
+								printk("Finished digit on span %d, channel %d (energy = %02x < %02x) 'channel' %d, chip %d!\n", span, y + 1, energy, ts->dtmfenergy[y], channel, chip);
+							if (debug & DEBUG_DTMF)	
+								printk("Finished digit '%c' on channel %d of span %d\n", ts->dtmfdigit[y], y + 1, span);
+							if (ts->dtmfmask & (1 << y))
+								zt_qevent_lock(&ts->span.chans[y], (ZT_EVENT_DTMFUP | ts->dtmfdigit[y]));
+							ts->dtmfenergy[y] = 0;
+							ts->dtmfdigit[y] = 0;
+							ts->dtmfactive &= ~(1 << y);
+						} else if (energy > (ts->dtmfenergy[y])) {
+							if (debug & DEBUG_DTMF)
+								printk("Increasing digit energy on span %d, channel %d (energy = %02x > %02x)!\n", span, y + 1, energy, ts->dtmfenergy[y]);
+							ts->dtmfenergy[y] = energy;
 						}
 					}
 				}
@@ -2382,7 +2415,7 @@
 	unsigned char reg;
 	unsigned int mask;
 	unsigned int ver;
-	unsigned int i, x, y;
+	unsigned int i, x, y, gen2vpm=0;
 
 	if (!vpmsupport) {
 		printk("VPM: Support Disabled\n");
@@ -2405,10 +2438,22 @@
 		int echotail = t4_vpm_echotail();
 
 		ver = t4_vpm_in(wc, x, 0x1a0); /* revision */
-		if (ver != 0x26) {
+		if ((ver != 0x26) && (ver != 0x33)) {
 			printk("VPM: %s\n", x ? "Inoperable" : "Not Present");
 			return;
-		}	
+		}
+		if (ver == 0x33) {
+			if (x && !gen2vpm) {
+				printk("VPM: Inconsistent\n");
+				return;
+			}
+			ts->spanflags |= FLAG_VPM2GEN;
+			gen2vpm++;
+		} else if (gen2vpm) {
+			printk("VPM: Inconsistent\n");
+			return;
+		}
+
 
 		/* Setup GPIO's */
 		for (y=0;y<4;y++) {
@@ -2475,13 +2520,29 @@
 		for (i = 0; i < MAX_DTMF_DET; i++) {
 			t4_vpm_out(wc, x, 0x98 + i, 0x40 | (i * 2) | ((x < 4) ? 0 : 1));
 		}
+		for (i = 0x34; i < 0x38; i++)
+			t4_vpm_out(wc, x, i, 0x00);
+		for (i = 0x3C; i < 0x40; i++)
+			t4_vpm_out(wc, x, i, 0x00);
+
+		for (i = 0x48; i < 0x4B; i++)
+			t4_vpm_out(wc, x, i, 0x00);
+		for (i = 0x50; i < 0x53; i++)
+			t4_vpm_out(wc, x, i, 0x00);
 		for (i = 0xB8; i < 0xBE; i++)
 			t4_vpm_out(wc, x, i, 0xFF);
+		if (gen2vpm) {
+			for (i = 0xBE; i < 0xC0; i++)
+				t4_vpm_out(wc, x, i, 0xFF);
+		} else {
+			for (i = 0xBE; i < 0xC0; i++)
+				t4_vpm_out(wc, x, i, 0x00);
+		}
 		for (i = 0xC0; i < 0xC4; i++)
 			t4_vpm_out(wc, x, i, (x < 4) ? 0x55 : 0xAA);
 
 	} 
-	printk("VPM: Present and operational servicing %d span(s)\n", vpmspans);
+	printk("VPM%s: Present and operational servicing %d span(s)\n", (gen2vpm ? "(2nd Gen)" : ""), vpmspans);
 	wc->vpm = T4_VPM_PRESENT;
 }
 



More information about the zaptel-commits mailing list