\ serial.fs
\
\ gforth interface words for Linux serial communcations.
\
\ Copyright (c) 2000--2004 David P. Wallace, Krishna Myneni
\ Provided under the terms of the GNU General Public License
\
\ Requires:
\
\ strings.fs
\ syscalls386.fs
\
\ Revisions:
\
\ 3-13-2000 first working version
\ 6-03-2001 modified serial_open to disable XON/XOFF flow control,
\ added bit constants for c_iflag, etc.,
\ modified serial_setparams for readability KM
\ 12-13-2001 modified serial_open to disable CR to NL translation. KM
\ 9-17-2004 ported from kForth KM
\ termios structure
require strings.fs
require syscalls386.fs
create termios 4 4 + 4 + 4 + 2 + 64 + 4 + 4 + allot
0 constant C_IFLAG
4 constant C_OFLAG
8 constant C_CFLAG
12 constant C_LFLAG
16 constant C_LINE
18 constant C__CC
82 constant C_ISPEED
86 constant C_OSPEED
\ c_iflag bits
1 constant IGNBRK
2 constant BRKINT
4 constant IGNPAR
8 constant PARMRK
16 constant INPCK
32 constant ISTRIP
64 constant INLCR
128 constant IGNCR
256 constant ICRNL
512 constant IUCLC
1024 constant IXON
2048 constant IXANY
4096 constant IXOFF
8192 constant IMAXBEL
\ c_oflag bits
1 constant OPOST
2 constant OLCUC
4 constant ONLCR
8 constant OCRNL
16 constant ONOCR
32 constant ONLRET
64 constant OFILL
128 constant OFDEL
256 constant NLDLY
\ c_cflag bits
\ baud rates constants
4111 constant CBAUD
0 constant B0
7 constant B300
9 constant B1200
11 constant B2400
12 constant B4800
13 constant B9600
14 constant B19200
15 constant B38400
4097 constant B57600
4098 constant B115200
\ character size constants
48 constant CSIZE
0 constant CS5
16 constant CS6
32 constant CS7
48 constant CS8
\ parity constants
768 constant CPARITY
0 constant PARNONE
256 constant PAREVEN
768 constant PARODD
\ stop bits constants
64 constant CSTOPB
0 constant ONESTOPB
64 constant TWOSTOPB
\ c_lflag bits
1 constant ISIG
2 constant ICANON
4 constant XCASE
8 constant ECHO
16 constant ECHOE
32 constant ECHOK
64 constant ECHONL
128 constant NOFLSH
256 constant TOSTOP
512 constant ECHOCTL
1024 constant ECHOPRT
2048 constant ECHOKE
4096 constant FLUSHO
16384 constant PENDIN
32768 constant IEXTEN
\ com port constants
0 constant COM1
1 constant COM2
2 constant COM3
3 constant COM4
\ ioctl request constants
hex
5401 constant TCGETS
5402 constant TCSETS
540B constant TCFLSH
541B constant FIONREAD
decimal
\ file control constants
hex
800 constant O_NDELAY
100 constant O_NOCTTY
002 constant O_RDWR
decimal
: serial_getoptions ( handle -- | read serial port options into termios )
TCGETS termios ioctl drop ;
: serial_setoptions ( handle -- | write termios into serial port options )
TCSETS termios ioctl drop ;
: serial_open ( port -- handle | opens the serial port for communcation )
\ port is the serial port to open
\ 0 = ttyS0 (COM1)
\ 1 = ttyS1 (COM2)
\ 2 = ttyS2 (COM3)
\ 3 = ttyS3 (COM4)
\ handle is a handle to the open serial port
\ if handle < 0 there was an error opening the port
dup
0 >=
if
s>string count
s" /dev/ttyS"
2swap
strcat
strpck
O_RDWR O_NOCTTY O_NDELAY or or
open
dup
dup
serial_getoptions
\ Disable XON/XOFF flow control and CR to NL mapping
termios C_IFLAG + @
IXON IXOFF or IXANY or ICRNL or ( not) invert and
termios C_IFLAG + !
\ Open for raw input
termios C_LFLAG + @
ISIG ICANON or ECHO or ECHOE or ( not) invert
and
termios C_LFLAG + !
\ Open for raw output
termios C_OFLAG + @
OPOST ( not) invert
and
termios C_OFLAG + !
serial_setoptions
then ;
: serial_close ( handle -- | closes the port )
\ handle = serial port handle received from serial_open
close ;
: serial_write ( handle buf num_to_write -- num_written )
\ handle = serial port handle received from serial_open
\ buf = address to buffer that holds chars to be written
\ num_to_write = number of chars to write
\ num_written = number of chars actually written
write ;
: serial_read ( handle buf num_to_read -- num_read )
\ handle = serial port handle received from serial_open
\ buf = address to buffer to hold chars to being read
\ num_to_read = number of chars to read
\ num_read = number of chars actually read
read ;
: serial_setbaud ( handle baud -- )
\ handle = serial port handle received from serial_open
\ baud = desired baud rate ( use constants defined above )
swap
dup
serial_getoptions
\ set the baud rate
swap
termios C_CFLAG + @
CBAUD ( not) invert and
or
termios C_CFLAG + !
serial_setoptions ;
: serial_setparity ( handle parity -- )
\ handle = serial port handle received from serial_open
\ parity = desired parity ( use constants defined above )
swap
dup
serial_getoptions
\ set the parity
swap
termios C_CFLAG + @
CPARITY ( not) invert and
or
termios C_CFLAG + !
serial_setoptions ;
: serial_setstopbits ( handle stopbits -- )
\ handle = serial port handle received from serial_open
\ stopbits = desired number of stopbits ( constants above )
swap
dup
serial_getoptions
\ set the stop_bit
swap
termios C_CFLAG + @
CSTOPB ( not) invert and
or
termios C_CFLAG + !
serial_setoptions ;
: serial_setdatabits ( handle databits -- )
\ handle = serial port handle received from serial_open
\ databits = desired number of databits ( constants above )
swap
dup
serial_getoptions
\ set the data size
swap
termios C_CFLAG + @
CSIZE ( not) invert and
or
termios C_CFLAG + !
serial_setoptions ;
: serial_flush ( handle -- )
\ handle = serial port handle received from serial_open
TCFLSH 2 ioctl drop ;
variable inque
: serial_lenrx ( handle -- rx_len)
\ handle = serial port handle received from serial_open
\ rx_len = number of chars in recieve que
FIONREAD inque ioctl drop
inque @ ;
: serial_setparams ( handle ^str -- )
\ ^str examples are 8N1, 7E1, etc.
swap >r
dup
1+ c@
case
[char] 8 of r@ CS8 serial_setdatabits endof
[char] 7 of r@ CS7 serial_setdatabits endof
endcase
dup
2 + c@
case
[char] N of r@ PARNONE serial_setparity endof
[char] E of r@ PAREVEN serial_setparity endof
[char] O of r@ PARODD serial_setparity endof
endcase
3 + c@
case
[char] 1 of r@ ONESTOPB serial_setstopbits endof
[char] 2 of r@ TWOSTOPB serial_setstopbits endof
endcase
r> drop ;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>