[Asterisk-cvs] zaptel zaptel.h,1.43,1.44 pciradio.c,1.12,1.13

jim jim
Wed Aug 10 23:16:23 CDT 2005


Update of /usr/cvsroot/zaptel
In directory mongoose.digium.com:/tmp/cvs-serv24317

Modified Files:
	zaptel.h pciradio.c 
Log Message:
Added driver support for UART output in VHDL on each channel


Index: zaptel.h
===================================================================
RCS file: /usr/cvsroot/zaptel/zaptel.h,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -d -r1.43 -r1.44
--- zaptel.h	11 May 2005 23:43:11 -0000	1.43
+++ zaptel.h	11 Aug 2005 03:19:46 -0000	1.44
@@ -1492,11 +1492,14 @@
 	unsigned char radstat;		/* status bits of radio */
 };
 
+#define	RAD_SERIAL_BUFLEN 128
+
 struct zt_radio_param {
 	unsigned short radpar;	/* param identifier */
 	unsigned short index;	/* tone number */
 	int data;		/* param */
 	int data2;		/* param 2 */
+	unsigned char buf[RAD_SERIAL_BUFLEN];
 };
 
 
@@ -1557,7 +1560,9 @@
 
 #define	ZT_RADPAR_REMMODE 16	/* Remote control data mode */
 	#define	ZT_RADPAR_REM_NONE 0 	/* no remote control data mode */
-	#define	ZT_RADPAR_REM_RBI1 1	/* Doug Hall RBI-1 data mode */				   
+	#define	ZT_RADPAR_REM_RBI1 1	/* Doug Hall RBI-1 data mode */
+	#define	ZT_RADPAR_REM_SERIAL 2	/* Serial Data, 9600 BPS */
+	#define	ZT_RADPAR_REM_SERIAL_ASCII 3	/* Serial Ascii Data, 9600 BPS */
 
 #define	ZT_RADPAR_REMCOMMAND 17	/* Remote conrtol write data block & do cmd */
 

Index: pciradio.c
===================================================================
RCS file: /usr/cvsroot/zaptel/pciradio.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- pciradio.c	25 Jul 2005 18:30:55 -0000	1.12
+++ pciradio.c	11 Aug 2005 03:19:46 -0000	1.13
@@ -63,6 +63,10 @@
 
 #define	NUM_CODES 15
 
+#define	SERIAL_BUFLEN 128
+
+#define	SRX_TIMEOUT 300
+
 #define RAD_CNTL    	0x00
 #define RAD_OPER	0x01
 #define RAD_AUXC    	0x02
@@ -149,7 +153,13 @@
 	int freeregion;
 	int nchans;
 	spinlock_t lock;
-	spinlock_t rbilock;
+	spinlock_t remotelock;
+	unsigned char rxbuf[SERIAL_BUFLEN];
+	unsigned short rxindex;
+	unsigned long srxtimer;
+	unsigned char txbuf[SERIAL_BUFLEN];
+	unsigned short txindex;
+	unsigned short txlen;
 	unsigned char pasave;
 	unsigned char pfsave;
 	volatile unsigned long ioaddr;
@@ -464,7 +474,7 @@
 DECLARE_WAIT_QUEUE_HEAD(mywait);
 
 
-	spin_lock(&rad->rbilock);
+	spin_lock(&rad->remotelock);
 	while(__pciradio_getcreg(rad,0xc) & 2) interruptible_sleep_on_timeout(&mywait,2);
 	/* enable and address RBI serializer */
 	__pciradio_setcreg(rad,0xf,rad->pfsave | (n << 4) | 0x40);
@@ -472,7 +482,7 @@
 	for(x = 0; x < 5; x++) __pciradio_setcreg(rad,0xc,rbicmd[x]);
 	/* output it */
 	__pciradio_setcreg(rad,0xb,1);
-	spin_unlock(&rad->rbilock);
+	spin_unlock(&rad->remotelock);
 	return;
 }
 
@@ -891,6 +901,28 @@
 				}
 			}
 		}
+/* process serial if any */
+		/* send byte if there is one in buffer to send */
+		if (rad->txlen && (rad->txlen != rad->txindex))
+		{
+			/* if tx not busy */
+			if (!(__pciradio_getcreg(rad,9) & 0x80))
+			{
+				__pciradio_setcreg(rad, 4, rad->txbuf[rad->txindex++]);
+			}				
+		}
+		rad->srxtimer++;
+		/* if something in rx to read */
+		while(__pciradio_getcreg(rad,9) & 0x10)
+		{
+			unsigned char c = __pciradio_getcreg(rad,4);
+			rad->srxtimer = 0;
+			if (rad->rxindex < RAD_SERIAL_BUFLEN)
+			{
+				rad->rxbuf[rad->rxindex++] = c;
+			}
+			udelay(1);
+		}
 		pciradio_receiveprep(rad, ints);
 		pciradio_transmitprep(rad, ints);
 	}
@@ -1162,29 +1194,90 @@
 			rad->remmode[chan->chanpos - 1] = stack.p.data;
 			break;
 		case ZT_RADPAR_REMCOMMAND:
+			/* if no remote mode, return an error */
+			if (rad->remmode[chan->chanpos - 1] == ZT_RADPAR_REM_NONE)
+			{
+				spin_unlock_irqrestore(&rad->lock,flags);
+				return -EINVAL;
+			}
 			i = 0;
+			if (rad->remmode[chan->chanpos - 1] == ZT_RADPAR_REM_RBI1)
+			{
+				/* set UIOA and UIOB for output */
+				spin_lock_irqsave(&rad->lock,flags);
+				byte1 = __pciradio_getcreg(rad,0xe);
+				mask = (1 << (chan->chanpos - 1)) | 
+					(1 << (chan->chanpos + 3));
+				byte2 = byte1 & (~mask);
+				i = (byte2 != byte1);
+				__pciradio_setcreg(rad,0xe,byte2);
+				byte1 = __pciradio_getcreg(rad,8);
+				mask = 1 << (chan->chanpos - 1);
+				byte2 = byte1 | mask;
+				i = (byte2 != byte1);
+				__pciradio_setcreg(rad,8,byte2);
+				spin_unlock_irqrestore(&rad->lock,flags);
+				if (i || (jiffies < rad->lastremcmd + 10))
+					interruptible_sleep_on_timeout(&mywait,10);
+				rad->lastremcmd = jiffies;
+				rbi_out(rad,chan->chanpos - 1,(unsigned char *)&stack.p.data);
+				break;
+			}
 			/* set UIOA and UIOB for output */
 			spin_lock_irqsave(&rad->lock,flags);
 			byte1 = __pciradio_getcreg(rad,0xe);
-			mask = (1 << (chan->chanpos - 1)) | 
-				(1 << (chan->chanpos + 3));
+			mask = 1 << (chan->chanpos + 3); /* B an output */
 			byte2 = byte1 & (~mask);
-			i = (byte2 != byte1);
+			byte2 |= 1 << (chan->chanpos - 1); /* A in input */
 			__pciradio_setcreg(rad,0xe,byte2);
 			byte1 = __pciradio_getcreg(rad,8);
-			mask = 1 << (chan->chanpos - 1);
 			byte2 = byte1 | mask;
-			i = (byte2 != byte1);
+			byte2 |= 1 << (chan->chanpos - 1);
 			__pciradio_setcreg(rad,8,byte2);
 			spin_unlock_irqrestore(&rad->lock,flags);
-			if (i || (jiffies < rad->lastremcmd + 10))
+			if (byte1 != byte2)
+				interruptible_sleep_on_timeout(&mywait,100);
+			while (jiffies < rad->lastremcmd + 10)
 				interruptible_sleep_on_timeout(&mywait,10);
 			rad->lastremcmd = jiffies;
-			if (rad->remmode[chan->chanpos - 1])
-			{
-				rbi_out(rad,chan->chanpos - 1,(unsigned char *)&stack.p.data);
+			spin_lock(&rad->remotelock);
+			while(__pciradio_getcreg(rad,0xc) & 2) interruptible_sleep_on_timeout(&mywait,2);
+			spin_unlock(&rad->remotelock);
+			spin_lock_irqsave(&rad->lock,flags);
+			/* enable and address async serializer */
+			__pciradio_setcreg(rad,0xf,rad->pfsave | ((chan->chanpos - 1) << 4) | 0x80);
+			/* copy tx buffer */
+			memcpy(rad->txbuf,stack.p.buf,stack.p.index);
+			rad->txlen = stack.p.index;
+			rad->txindex = 0;
+			rad->rxindex = 0;
+			rad->srxtimer = 0;
+			memset(stack.p.buf,0,SERIAL_BUFLEN);
+			stack.p.index = 0;
+			for(;;)
+			{			
+				rad->rxbuf[rad->rxindex] = 0;
+				if (((!stack.p.data) || (rad->rxindex < stack.p.data)) &&
+				  (rad->srxtimer < SRX_TIMEOUT) &&
+				    ((rad->remmode[chan->chanpos - 1] == ZT_RADPAR_REM_SERIAL) ||
+					(!strchr(rad->rxbuf,'\r'))))
+				{
+					spin_unlock_irqrestore(&rad->lock,flags);
+					interruptible_sleep_on_timeout(&mywait,2);
+					spin_lock_irqsave(&rad->lock,flags);
+					continue;
+				}
+				memset(stack.p.buf,0,SERIAL_BUFLEN);
+				if (stack.p.data && (rad->rxindex > stack.p.data))
+					rad->rxindex = stack.p.data;
+				if (rad->rxindex)
+					memcpy(stack.p.buf,rad->rxbuf,rad->rxindex);
+				stack.p.index = rad->rxindex;
+				break;
 			}
-			break;
+			if (copy_to_user((struct zt_radio_stat *)data,&stack.p,sizeof(struct zt_radio_param))) return -EFAULT;
+			spin_unlock_irqrestore(&rad->lock,flags);
+			return 0;
 		default:
 			spin_unlock_irqrestore(&rad->lock,flags);
 			return -EINVAL;




More information about the svn-commits mailing list