I'm attempting to interact with a peripheral from a Debian 10.4 laptop. They are connected using a Chipi-X RS-232<->USB cable, and I'm working on the code for the communication on the laptop (it's in CPython using pyserial), but I have little to no control over the implementation of the peripheral itself.
I'm having some trouble with a small fraction of the bytes transmitted being dropped, but that's possibly a subject for another question.
As part of trying to sort that out, I noticed that the serial connection has several special characters enabled, and I don't want that:
$ stty -a < /dev/ttyUSB0
below cmd output started 2020 Tue Jul 28 03:55:48 PM PDT
speed 38400 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl -ixon -ixoff -iuclc -ixany imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke -flusho -extproc
Is there a pyserial way to disable all those special characters (EG intr, quit, erase, etcetera), and tuning anything else required to make the connection fully 8 bit clean?
Right now, I'm opening the serial device using:
serial_file = serial.Serial(
port=self.serial_port_filename,
baudrate=self.baudrate,
bytesize=serial.EIGHTBITS,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
timeout=3,
)
Thanks!
Update: "stty -F /dev/ttyUSB0 raw" doesn't appear to be working:
$ stty -F /dev/ttyUSB0 raw
below cmd output started 2020 Wed Jul 29 11:52:35 AM PDT
above cmd output done 2020 Wed Jul 29 11:52:35 AM PDT
root@zareason-strata7440:~/src/orange-med/NKV-Gateway x86_64-pc-linux-gnu 6942
$ stty -F /dev/ttyUSB0 -a
below cmd output started 2020 Wed Jul 29 11:52:37 AM PDT
speed 38400 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
-isig -icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke -flusho -extproc
Neither does holding the file open and sleeping.
Neither does the apparent CPython equivalent:
tty.setraw(serial_file.fd, when=termios.TCSANOW)
Am I doing something wrong?
Another update: I think I have it doing 8 bit clean communication, but I'm still seeing spuriously dropped (or spuriously inserted) sequences of bytes. This could conceivably be due to the total lack of flow control.
Here's the code I'm using to get an 8 bit clean serial line. If someone sees a lingering problem in there, please do let me know!
"""Put a terminal in raw mode and/or make a terminal 8 bit clean."""
import termios
# Indexes for termios list.
IFLAG = 0
OFLAG = 1
CFLAG = 2
LFLAG = 3
ISPEED = 4
OSPEED = 5
CC = 6
def make_8_bit_clean(file_descriptor, when=termios.TCSANOW):
"""
Make file_descriptor able to send and receive all 256 eight bit characters without strangeness.
Based on:
https://stackoverflow.com/questions/12437593/how-to-read-a-binary-data-over-serial-terminal-in-c-program/12457195#12457195
Specifically the "Code that works on my ARM SoC is" answer.
"""
mode = termios.tcgetattr(file_descriptor)
cfmakeraw(mode)
mode[CC][termios.VMIN] = 1
mode[CC][termios.VTIME] = 0
mode[CFLAG] &= ~termios.CSTOPB
mode[CFLAG] &= ~termios.CRTSCTS
mode[CFLAG] |= termios.CLOCAL
mode[CFLAG] |= termios.CREAD
termios.tcsetattr(file_descriptor, when, mode)
def cfmakeraw(mode):
"""
Set flags to 'raw' mode.
Based on https://linux.die.net/man/3/cfmakeraw
"""
mode[IFLAG] &= ~termios.IGNBRK
mode[IFLAG] &= ~termios.BRKINT
mode[IFLAG] &= ~termios.IGNBRK
mode[IFLAG] &= ~termios.BRKINT
mode[IFLAG] &= ~termios.PARMRK
mode[IFLAG] &= ~termios.ISTRIP
mode[IFLAG] &= ~termios.INLCR
mode[IFLAG] &= ~termios.IGNCR
mode[IFLAG] &= ~termios.ICRNL
mode[IFLAG] &= ~termios.IXON
mode[OFLAG] &= ~termios.OPOST
mode[LFLAG] &= ~termios.ECHO
mode[LFLAG] &= ~termios.ECHONL
mode[LFLAG] &= ~termios.ICANON
mode[LFLAG] &= ~termios.ISIG
mode[LFLAG] &= ~termios.IEXTEN
mode[CFLAG] &= ~termios.CSIZE
mode[CFLAG] &= ~termios.PARENB
mode[CFLAG] |= termios.CS8
Thanks.