Here's a problem report sent to me. I think there is a problem with
our support of mark/space parity. Hope you can help. See my
comments later on.
David Lawyer
On Wed, Mar 01, 2000 at 03:19:55PM -0500, James Moger wrote:
> I have been reading your serial howto and some other howto's (serial
> programming, I/O programming) and I've got a question/problem which
> maybe you can help me solve. The company I work for makes medical
> devices which pump out a serial stream for optional data acquisition on
> a PC. Since I started working for them in 1997 they have switched their
> serial format on the new devices to standard N81 communications.
> However, we still have to support the older legacy communications
> setup. My boss developed a simple 4 page interrupt driven serial
> acquisition program (I hesitate to use the word driver) for DOS which we
> still use in Windows 98. (We made this program into a 16-bit DLL with
> good old Borland C and then we THUNK to that DLL to enable our 32-bit
> Windows code to use the 16-bit serial code. Ugh!) Neither of us are
> device driver programmers so we have avoided the whole Windows VDX
> business.
>
> I am working on developing a new product based on Linux - it has taken
> me a while to get permission to explore this as a possibility.
> Naturally, I want to be able to catch the serial stream coming in and
> write it to disk - to start with.
>
> I have already established communications with the new devices (N81) and
> am recording that data correctly and displaying as scrolling waveforms.
> The trouble is with the older "legacy" devices. Let me explain the
> format and how the 16-Bit DOS/Windows DLL works.
>
> The device sends out packets over the serial port. One packet contains
> 16 bytes. Each bit of each byte is valid data - we are using all 8 data
> bits. So the question is how do you know when you have the start of a
> packet, because without one you would have jumbled data? The
> implemented solution was to use the parity bit as a packet delimiter.
> The parity bit is set high for the first byte and remains low for the
> next 15 bytes. So we aren't really using parity for its intended
> design.
>
> On the DOS/Windows side of things the serial port is opened with 8 data
> bits, 1 stop bit, and space parity. With space parity and 8 data bits
> enabled, the UART expects that every 8-bit byte coming in will have a
> ninth bit (parity) set to zero. When the parity bit is set high the
> UART sets the parity error flag in the line control register. Thus we
> know that the first byte of a packet has arrived.
>
> An interrupt routine is fired on every byte coming in which first off
> checks for a parity error. If one has occurred it creates a new
> packet. Aside from the fact that this is slow and inefficient because
> there is an interrupt for every byte, it works for our slow data rate.
>
> Basically I am trying to reimplement this approach on the Linux side of
> things - using the parity bit as a packet delimiter for 8-data bits and
> the UART parity set to space. The documentation I've read for setting
> the parity bit talks of even, odd, and no parity - almost no mention of
> mark or space parity. The one thing I did download - "Serial
> Programming Guide for POSIX Operating Systems" tells me how to use space
> parity, but it looks like it sets up the UART as S71, expecting you will
> be using 7 data bits, 1 stop bit, and the 8-th data bit as parity. This
> approach will strip off an important bit from every byte of our data.
>
> Any suggestions, recommendations or referals?
>
> Thanks,
> --
> James Moger
> ===---------------------===
> Software Engineer
> Transonic Systems, Inc.
> {C/C++} {Java} {Smalltalk}
> Cornell Engineering '98
> ===---------------------===
I don't do any serial programming but it looks like there is a problem
supporting mark parity and space parity. James M. wants to use space
parity. Stty doesn't support it but the termios stucture in the
serial driver might. Such parity is specified by a c_cflag named
CMSPAR in <asm/termbits.h>. The equvalent is in <linux/serial-reg.h>
as UART_LCR_SPAR 0x20. This is called "sticky parity". It looks like
someone put a ? in the comment in the serial-reg.h file shown above and
called it "stick" instead of "sticky". If this "sticky" bit is set,
then the parity bit is always odd (1) or even (0) depending on how the
parity flag-bit has been set.
It would seem that the high-level way to go would be to set the sticky
parity bit in the termios structure, but will this do the job? To
change the termios structure one may use tcsetattr() and tcgetattr()
as shown in Vern's HOWTO. It seems that the flags normally used are
in <bits/termios.h> and CMSPAR is missing from this. <termios.h>
#includes this but <asm/termios.h> #includes the one you want that
contains the CMSPAR flags. Will this flag work OK if one changes the
#includes in their program to the </asm> directory? Why isn't it in
<bits/termios.h>?
A low-level way to set it would be by writing to the UART port Line
Control Register (it's bit 0x20 that should be set). I'm not sure how
to directly write to the ports and I don't think that Linux likes
(allows ?) this to be done by a program in user space. So the main
question is: Will Linux support sticky (mark/space) parity (or support
it better)?
David Lawyer
-
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to [EMAIL PROTECTED]