summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2002-08-17 00:28:51 +0000
committermarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2002-08-17 00:28:51 +0000
commit9ba4e07b16bf5efa450f9ab3b9f1eaa937d54a82 (patch)
tree82eaee499b6fddeb273ac4614748ec2148d27fd5
parentcae7000b30d70bede209225c841cf2702c84fb0f (diff)
Version 0.3.0 from FTP
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@98 5390a7c7-147a-4af0-8ec9-7488f05a26cb
-rwxr-xr-xtor2.c26
-rwxr-xr-xtorisa.c31
2 files changed, 48 insertions, 9 deletions
diff --git a/tor2.c b/tor2.c
index fbe7c37..8e1879a 100755
--- a/tor2.c
+++ b/tor2.c
@@ -103,6 +103,8 @@ struct tor2 {
int spansstarted; /* number of spans started */
spinlock_t lock; /* lock context */
unsigned char leds; /* copy of LED register */
+ unsigned char ec_chunk1[4][32][ZT_CHUNKSIZE]; /* first EC chunk buffer */
+ unsigned char ec_chunk2[4][32][ZT_CHUNKSIZE]; /* second EC chunk buffer */
#ifdef ENABLE_TASKLETS
int taskletrun;
int taskletsched;
@@ -707,11 +709,18 @@ static int tor2_startup(struct zt_span *span)
return -1;
}
-
spin_lock_irqsave(&p->tor->lock, flags);
alreadyrunning = span->flags & ZT_FLAG_RUNNING;
+ /* initialize the start value for the entire chunk of last ec buffer */
+ for(i = 0; i < span->channels; i++)
+ {
+ memset(p->tor->ec_chunk1[p->span][i],
+ ZT_LIN2X(0,&span->chans[i]),ZT_CHUNKSIZE);
+ memset(p->tor->ec_chunk2[p->span][i],
+ ZT_LIN2X(0,&span->chans[i]),ZT_CHUNKSIZE);
+ }
if (p->tor->cardtype == TYPE_E1) { /* if this is an E1 card */
unsigned char tcr1,ccr1;
if (!alreadyrunning) {
@@ -937,11 +946,18 @@ static inline void tor2_run(struct tor2 *tor)
int x,y;
for (x=0;x<4;x++) {
if (tor->spans[x].flags & ZT_FLAG_RUNNING) {
+ /* since the Tormenta 2 PCI is double-buffered, you
+ need to delay the transmit data 2 entire chunks so
+ that the transmit will be in sync with the receive */
for (y=0;y<tor->spans[x].channels;y++) {
- /* XXX Technically, we're wasting 8 taps of echo canceller
- because we're cancelling against something that won't be sent
- until the next chunk XXX */
- zt_ec_chunk(&tor->spans[x].chans[y], tor->spans[x].chans[y].readchunk, tor->spans[x].chans[y].writechunk);
+ zt_ec_chunk(&tor->spans[x].chans[y],
+ tor->spans[x].chans[y].readchunk,
+ tor->ec_chunk2[x][y]);
+ memcpy(tor->ec_chunk2[x][y],tor->ec_chunk1[x][y],
+ ZT_CHUNKSIZE);
+ memcpy(tor->ec_chunk1[x][y],
+ tor->spans[x].chans[y].writechunk,
+ ZT_CHUNKSIZE);
}
zt_receive(&tor->spans[x]);
}
diff --git a/torisa.c b/torisa.c
index 19a81a3..b7c67a8 100755
--- a/torisa.c
+++ b/torisa.c
@@ -132,6 +132,7 @@ static rwlock_t torisa;
static u_char readdata[2][64][ZT_MAX_CHUNKSIZE];
static u_char writedata[2][64][ZT_MAX_CHUNKSIZE];
+static u_char last_ecwrite[2][32];
static int curread;
static unsigned long base;
@@ -441,6 +442,11 @@ static int torisa_startup(struct zt_span *span)
alreadyrunning = span->flags & ZT_FLAG_RUNNING;
+ /* initialize the start value for the last ec buffer */
+ for(i = 0; i < span->channels; i++)
+ {
+ last_ecwrite[tspan - 1][i] = ZT_LIN2X(0,&span->chans[i]);
+ }
crcing = "";
if (card_type == TYPE_T1) { /* if its a T1 card */
if (!alreadyrunning) {
@@ -669,8 +675,8 @@ static struct tasklet_struct torisa_tlet;
static void torisa_tasklet(unsigned long data)
{
- int x;
-
+ int x,y;
+ u_char mychunk[2][ZT_CHUNKSIZE];
taskletrun++;
if (taskletpending) {
taskletexec++;
@@ -679,13 +685,30 @@ static void torisa_tasklet(unsigned long data)
if (spans[1].flags & ZT_FLAG_RUNNING) {
/* Perform echo cancellation */
for (x=0;x<channels_per_span;x++)
- zt_ec_chunk(&spans[1].chans[x], spans[1].chans[x].readchunk, writedata[1-curread][x + channels_per_span]);
+ {
+ for(y = 0; y < ZT_CHUNKSIZE; y++)
+ {
+ mychunk[1][y] = last_ecwrite[1][x];
+ last_ecwrite[1][x] =
+ writedata[1-curread][x + channels_per_span][y];
+ }
+ zt_ec_chunk(&spans[1].chans[x],
+ spans[1].chans[x].readchunk,mychunk[1]);
+ }
zt_receive(&spans[1]);
}
if (spans[0].flags & ZT_FLAG_RUNNING) {
/* Perform echo cancellation */
for (x=0;x<channels_per_span;x++)
- zt_ec_chunk(&spans[0].chans[x], spans[0].chans[x].readchunk, writedata[1-curread][x]);
+ {
+ for(y = 0; y < ZT_CHUNKSIZE; y++)
+ {
+ mychunk[0][y] = last_ecwrite[0][x];
+ last_ecwrite[0][x] = writedata[1-curread][x][y];
+ }
+ zt_ec_chunk(&spans[0].chans[x],
+ spans[0].chans[x].readchunk,mychunk[0]);
+ }
zt_receive(&spans[0]);
}