Implement mark and space parity generation. Accept one-and- a-half
stopbits: the most common uarts will generate this automatically when
there are 5 databits.
diff --git a/misc/comm.c b/misc/comm.c
index 54e56c5..4732f39 100644
--- a/misc/comm.c
+++ b/misc/comm.c
@@ -89,6 +89,10 @@
#define FLAG_LPT 0x80
+#ifdef linux
+#define CMSPAR 0x40000000 /* stick parity */
+#endif
+
struct DosDeviceStruct COM[MAX_PORTS];
struct DosDeviceStruct LPT[MAX_PORTS];
/* pointers to unknown(==undocumented) comm structure */
@@ -850,6 +854,8 @@
{
struct termios port;
struct DosDeviceStruct *ptr;
+ int bytesize, stopbits;
+ int fail=0;
TRACE("cid %d, ptr %p\n", lpdcb->Id, lpdcb);
if ((ptr = GetDeviceStruct(lpdcb->Id)) == NULL) {
@@ -931,7 +937,7 @@
#endif
default:
ptr->commerror = IE_BAUDRATE;
- return -1;
+ fail=1;
}
#elif !defined(__EMX__)
switch (lpdcb->BaudRate) {
@@ -973,13 +979,69 @@
break;
default:
ptr->commerror = IE_BAUDRATE;
- return -1;
+ fail=1;
}
port.c_ispeed = port.c_ospeed;
#endif
- TRACE("bytesize %d\n",lpdcb->ByteSize);
+ bytesize=lpdcb->ByteSize;
+ stopbits=lpdcb->StopBits;
+
+ TRACE("fParity %d Parity %d\n",lpdcb->fParity, lpdcb->Parity);
+#ifdef CMSPAR
+ port.c_cflag &= ~(PARENB | PARODD | CMSPAR);
+#else
+ port.c_cflag &= ~(PARENB | PARODD);
+#endif
+ if (lpdcb->fParity)
+ port.c_iflag |= INPCK;
+ else
+ port.c_iflag &= ~INPCK;
+ switch (lpdcb->Parity) {
+ case NOPARITY:
+ break;
+ case ODDPARITY:
+ port.c_cflag |= (PARENB | PARODD);
+ break;
+ case EVENPARITY:
+ port.c_cflag |= PARENB;
+ break;
+#ifdef CMSPAR
+ /* Linux defines mark/space (stick) parity */
+ case MARKPARITY:
+ port.c_cflag |= (PARENB | CMSPAR);
+ break;
+ case SPACEPARITY:
+ port.c_cflag |= (PARENB | PARODD | CMSPAR);
+ break;
+#else
+ /* try the POSIX way */
+ case MARKPARITY:
+ if( stopbits == ONESTOPBIT) {
+ stopbits = TWOSTOPBITS;
+ port.c_iflag &= ~INPCK;
+ } else {
+ ptr->commerror = IE_BYTESIZE;
+ fail=1;
+ }
+ break;
+ case SPACEPARITY:
+ if( bytesize < 8) {
+ bytesize +=1;
+ port.c_iflag &= ~INPCK;
+ } else {
+ ptr->commerror = IE_BYTESIZE;
+ fail=1;
+ }
+ break;
+#endif
+ default:
+ ptr->commerror = IE_BYTESIZE;
+ fail=1;
+ }
+
+ TRACE("bytesize %d\n",bytesize);
port.c_cflag &= ~CSIZE;
- switch (lpdcb->ByteSize) {
+ switch (bytesize) {
case 5:
port.c_cflag |= CS5;
break;
@@ -994,42 +1056,22 @@
break;
default:
ptr->commerror = IE_BYTESIZE;
- return -1;
+ fail=1;
}
- TRACE("fParity %d Parity %d\n",lpdcb->fParity, lpdcb->Parity);
- port.c_cflag &= ~(PARENB | PARODD);
- if (lpdcb->fParity)
- port.c_iflag |= INPCK;
- else
- port.c_iflag &= ~INPCK;
- switch (lpdcb->Parity) {
- case NOPARITY:
- break;
- case ODDPARITY:
- port.c_cflag |= (PARENB | PARODD);
- break;
- case EVENPARITY:
- port.c_cflag |= PARENB;
- break;
- default:
- ptr->commerror = IE_BYTESIZE;
- return -1;
- }
-
+ TRACE("stopbits %d\n",stopbits);
- TRACE("stopbits %d\n",lpdcb->StopBits);
-
- switch (lpdcb->StopBits) {
+ switch (stopbits) {
case ONESTOPBIT:
port.c_cflag &= ~CSTOPB;
break;
+ case ONE5STOPBITS: /* wil be selected if bytesize is 5 */
case TWOSTOPBITS:
port.c_cflag |= CSTOPB;
break;
default:
ptr->commerror = IE_BYTESIZE;
- return -1;
+ fail=1;
}
#ifdef CRTSCTS
@@ -1050,9 +1092,12 @@
ptr->evtchar = lpdcb->EvtChar;
+ if(fail)
+ return -1;
+
if (tcsetattr(ptr->fd, TCSADRAIN, &port) == -1) {
ptr->commerror = WinError();
- return FALSE;
+ return -1;
} else {
ptr->commerror = 0;
return 0;
@@ -1143,7 +1188,11 @@
lpdcb->fParity = TRUE;
else
lpdcb->fParity = FALSE;
+#ifdef CMSPAR
+ switch (port.c_cflag & (PARENB | PARODD | CMSPAR)) {
+#else
switch (port.c_cflag & (PARENB | PARODD)) {
+#endif
case 0:
lpdcb->Parity = NOPARITY;
break;
@@ -1153,12 +1202,23 @@
case (PARENB | PARODD):
lpdcb->Parity = ODDPARITY;
break;
+#ifdef CMSPAR
+ case (PARENB | CMSPAR):
+ lpdcb->Parity = MARKPARITY;
+ break;
+ case (PARENB | PARODD | CMSPAR):
+ lpdcb->Parity = SPACEPARITY;
+ break;
+#endif
}
if (port.c_cflag & CSTOPB)
- lpdcb->StopBits = TWOSTOPBITS;
+ if(lpdcb->ByteSize == 5)
+ lpdcb->StopBits = ONE5STOPBITS;
+ else
+ lpdcb->StopBits = TWOSTOPBITS;
else
- lpdcb->StopBits = ONESTOPBIT;
+ lpdcb->StopBits = ONESTOPBIT;
lpdcb->RlsTimeout = 50;
lpdcb->CtsTimeout = 50;
@@ -1910,6 +1970,7 @@
{
struct termios port;
int fd;
+ int bytesize, stopbits;
TRACE("handle %d, ptr %p\n", handle, lpdcb);
TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
@@ -2069,8 +2130,70 @@
}
port.c_ispeed = port.c_ospeed;
#endif
+ bytesize=lpdcb->ByteSize;
+ stopbits=lpdcb->StopBits;
+
+#ifdef CMSPAR
+ port.c_cflag &= ~(PARENB | PARODD | CMSPAR);
+#else
+ port.c_cflag &= ~(PARENB | PARODD);
+#endif
+ if (lpdcb->fParity)
+ port.c_iflag |= INPCK;
+ else
+ port.c_iflag &= ~INPCK;
+ switch (lpdcb->Parity) {
+ case NOPARITY:
+ break;
+ case ODDPARITY:
+ port.c_cflag |= (PARENB | PARODD);
+ break;
+ case EVENPARITY:
+ port.c_cflag |= PARENB;
+ break;
+#ifdef CMSPAR
+ /* Linux defines mark/space (stick) parity */
+ case MARKPARITY:
+ port.c_cflag |= (PARENB | CMSPAR);
+ break;
+ case SPACEPARITY:
+ port.c_cflag |= (PARENB | PARODD | CMSPAR);
+ break;
+#else
+ /* try the POSIX way */
+ case MARKPARITY:
+ if( stopbits == ONESTOPBIT) {
+ stopbits = TWOSTOPBITS;
+ port.c_iflag &= ~INPCK;
+ } else {
+ commerror = IE_BYTESIZE;
+ close( fd );
+ ERR("Cannot set MARK Parity\n");
+ return FALSE;
+ }
+ break;
+ case SPACEPARITY:
+ if( bytesize < 8) {
+ bytesize +=1;
+ port.c_iflag &= ~INPCK;
+ } else {
+ commerror = IE_BYTESIZE;
+ close( fd );
+ ERR("Cannot set SPACE Parity\n");
+ return FALSE;
+ }
+ break;
+#endif
+ default:
+ commerror = IE_BYTESIZE;
+ close( fd );
+ ERR("Parity\n");
+ return FALSE;
+ }
+
+
port.c_cflag &= ~CSIZE;
- switch (lpdcb->ByteSize) {
+ switch (bytesize) {
case 5:
port.c_cflag |= CS5;
break;
@@ -2089,33 +2212,12 @@
ERR("ByteSize\n");
return FALSE;
}
-
- port.c_cflag &= ~(PARENB | PARODD);
- if (lpdcb->fParity)
- port.c_iflag |= INPCK;
- else
- port.c_iflag &= ~INPCK;
- switch (lpdcb->Parity) {
- case NOPARITY:
- break;
- case ODDPARITY:
- port.c_cflag |= (PARENB | PARODD);
- break;
- case EVENPARITY:
- port.c_cflag |= PARENB;
- break;
- default:
- commerror = IE_BYTESIZE;
- close( fd );
- ERR("Parity\n");
- return FALSE;
- }
-
-
- switch (lpdcb->StopBits) {
+
+ switch (stopbits) {
case ONESTOPBIT:
port.c_cflag &= ~CSTOPB;
break;
+ case ONE5STOPBITS: /* wil be selected if bytesize is 5 */
case TWOSTOPBITS:
port.c_cflag |= CSTOPB;
break;
@@ -2275,7 +2377,11 @@
lpdcb->fParity = TRUE;
else
lpdcb->fParity = FALSE;
+#ifdef CMSPAR
+ switch (port.c_cflag & (PARENB | PARODD | CMSPAR)) {
+#else
switch (port.c_cflag & (PARENB | PARODD)) {
+#endif
case 0:
lpdcb->Parity = NOPARITY;
break;
@@ -2285,12 +2391,23 @@
case (PARENB | PARODD):
lpdcb->Parity = ODDPARITY;
break;
+#ifdef CMSPAR
+ case (PARENB | CMSPAR):
+ lpdcb->Parity = MARKPARITY;
+ break;
+ case (PARENB | PARODD | CMSPAR):
+ lpdcb->Parity = SPACEPARITY;
+ break;
+#endif
}
if (port.c_cflag & CSTOPB)
- lpdcb->StopBits = TWOSTOPBITS;
+ if(lpdcb->ByteSize == 5)
+ lpdcb->StopBits = ONE5STOPBITS;
+ else
+ lpdcb->StopBits = TWOSTOPBITS;
else
- lpdcb->StopBits = ONESTOPBIT;
+ lpdcb->StopBits = ONESTOPBIT;
lpdcb->fNull = 0;
lpdcb->fBinary = 1;