serial.e library help file

All functions binded in serial.e are exported by /lib/libc.so.6 which is a symbolic link to some version of /lib/libc-*.so where * should be replace by version number.

usefull link regarding serial programming


Table of contents


function serial_last_error()


Call this function to get last error code from a serial operation.
This return the value stored in errno variable exported by libc.

table of contents

function serial_open(sequence device,sequence open_flags)

bind to open() API function.
Call this function to open a serial device.
device is a serial device name string, like: /dev/tty0
open_flags is a sequence of the followings flags: for a complete list of these flags see fcntl.e file or open(2) man page.

table of contents

procedure serial_close(integer fd)

bind to close() API function.
Call this procedure to close a serial device. fd arguement is the handle returned by serial_open() function.

table of contents

procedure serial_flow(integer fd, atom action)

bind to tcflow() API function.
Call this procedure to stop or resume data flow on serial port.
fd is handle returned by serial_open()
action is one of the following action constants.

table of contents

function serial_get_attr(integer fd)

bind to tcgetattr() API function.
Call this function to get information about serial port current settings.
fd is the handle returned by serial_open()
If fail return -1 else return a sequence containing data peeked from termios structure
termios data contain line discipline, word length, parity, speed and control characters.
In case of failure call serial_last_error to get error code.
see termios for more detail.

table of contents

procedure serial_flush(integer fd, atom flag)

bind to tcflush() API function.
Call this procedure to discard pending data.
fd is handle returned by serial_open()
flag is one of the following constants:

table of contents

procedure serial_set_ospeed(integer fd, atom speed)

bind to cfsetospeed() API function.
Call this procedure to set serial port output speed. The speed change is immediate.
fd is handle returned by serial_open().
speed is a constant defined in serial.e. Those constants are of the form Bnnn where nnn is the baud rate. There is one defined for each valid baud rate.

table of contents

procedure serial_set_ispeed(integer fd,integer speed)

bind to cfsetispeed() API function.
Call this procedure to set serial port input speed. The speed change is immediate.
fd is the handle returned by serial_open()
speed is a constant defined in serial.e. These constants are of the form Bnnn where nnn is the baude rate. There is one defined for each valid baud rate.

table of contents

procedure serial_set_attr(integer fd, integer action, sequence attrib)

bind to tcsetattr() API function.
Call this function to set serial port attributes.
Attributes are line discipline, word length, parity, stop bit, speed and control characters
fd is the handle returned by serial_open()
action specify when the change take effect:
TCSANOW
the change occurs immediately.
TCSADRAIN
the change occurs after all output written to fd has been transmitted. This function should be used when changing parameters that affect output.
TCSAFLUSH
the change occurs after all output written to the object referred by fd has been transmitted, and all input that has been received but not read will be discarded before the change is made.
attrib is termios sequence containing attributes to setup.
see termios for more detail.

table of contents

function serial_get_ispeed(integer fd)

bind to cfgetispeed() API function.
Call this function to get serial port input speed. This is the Bnnn constant that is returned not the actual baud rate.
Bnnn constant are value from 1 to 15.To print actual baud rate one could index a sequence of string corresponding to each constant.
constant BAUD_STR={"50","75","110","134","150","200","300","600","1200",
"1800", "2400","4800","9600","19200","38400"}
printf(1,"input baud rate %s\n",{BAUD_STR[serial_get_ispeed(fd)]})
fd is the handle returned by serial_open()
This is equivalent to calling serial_get_attr() and then accessing TIOS_ISPEED element.

table of contents

function serial_get_ospeed(integer fd)

bind to cfgetospeed() API function.
Call this function to get serial port output speed. This is the Bnnn constant that is returned not the actual baud rate.
Bnnn constant are value from 1 to 15.To print actual baud rate one could index a sequence of string corresponding to each constant.
constant BAUD_STR={"50","75","110","134","150","200","300","600","1200",
"1800", "2400","4800","9600","19200","38400"}
printf(1,"output baud rate %s\n",{BAUD_STR[serial_get_ospeed(fd)]})
fd is the handle returned by serial_open()
This is equivalent to calling serial_get_attr() and then accessing TIOS_OSPEED element.

table of contents

function serial_write(integer fd, sequence data)

bind to write() API function.
Call this function to write a sequence of bytes to serial port.
fd is the handle returned by serial_open()
data is the data to write to serial port.
If the function succeed it return the number of bytes written, otherwise return -1. In the last case a call to serial_last_error() return the error number.

table of contents

function serial_read(integer fd, integer count)

bind to read() API function.
Call this function to read data from serial port.
fd is the handle returned by serial_open()
count is the number of bytes to read.
If succeed return a sequence of bytes else it return -1. In the last case a call to serial_last_error() will return the error number.

table of contents

function serial_read_line(integer fd, atom delay)

Helper function that read data from serial port up to including \n character or delay expiration.
fd is the handle returned by serial_open().
delay is expiration delay expressed in seconds. Precision is that of time() function.
If it succeed return a sequence of bytes with \n as last character. If expiration time occur before a \n is read then all bytes read up to expiration are returned. This helper funcion call repeatedly serial_read() but only check for EAGAIN error code so if another I/O error occur it is ignored and the function will returned after expiration delay with possibly an empty sequence. In that case serial_last_error() could be called to check for possible error_code other than EAGAIN.

table of contents

procedure serial_send_break(integer fd, integer duration)

bind to tcsendbreak()
Send a series of zero bits to serial port for duration.
fd is handle returned by serial_open()
duration is an integer, if it is zero delay is betwen .25 and .5 seconds, otherwise it depends on implementation.

table of contents

procedure serial_drain(integer fd)

bind to tcdrain()
This procedure wait until all bytes in output buffer are transmitted.
fd is handle returned by serial_open()

table of contents

procedure serial_raw_mode(integer fd)

bind to cfmakeraw()
Set serial communication to raw mode.
fd is handle returned by serial_open()

table of contents

termios

termios is a C struct used in many of the functions binded in serial.e. The library take care of allocating, freeing, poking and peeking the C structure. Where a C API function return a termios its binded equivalent return the data as a sequence with elements is same order as in structure. If a serial.e function bind to a function that need a termios structure as argument, its binding accept a termios sequence as argument.
termios is defined like this at http://linux.die.net/man/3/termios page.
struct termios{
tcflag_t c_iflag;      /* input modes */
tcflag_t c_oflag;      /* output modes */
tcflag_t c_cflag;      /* control modes */
tcflag_t c_lflag;      /* local modes */
cc_t     c_cc[NCCS];   /* control chars */
};
On fedora 10 and linpus lite linux in /usr/include/bits/termios.h I found the following definitions:
typedef unsigned char   cc_t;
typedef unsigned int    speed_t;
typedef unsigned int    tcflag_t;

#define NCCS 32
struct termios
  {
    tcflag_t c_iflag;           /* input mode flags */
    tcflag_t c_oflag;           /* output mode flags */
    tcflag_t c_cflag;           /* control mode flags */
    tcflag_t c_lflag;           /* local mode flags */
    cc_t c_line;                        /* line discipline */
    cc_t c_cc[NCCS];            /* control characters */
    speed_t c_ispeed;           /* input speed */
    speed_t c_ospeed;           /* output speed */
#define _HAVE_STRUCT_TERMIOS_C_ISPEED 1
#define _HAVE_STRUCT_TERMIOS_C_OSPEED 1
  };
But there is a catch, 3 bytes of padding are inserted between c_cc[NCCS] array and c_ispeed member. Not knowing it at first I was peeking and poking those 2 values at wrong position.
serial.e define the following constants to access termios sequence elements: More details are available about termios at http://linux.die.net/man/3/termios

table of contents

code example

This program example is adapted from http://tldp.org/HOWTO/Serial-Programming-HOWTO/x115.html
-- serial communication sample program
-- adapted from: http://tldp.org/HOWTO/Serial-Programming-HOWTO/x115.html

include serial.e

integer fd
object old_termios, new_termios

constant SERIAL_DEVICE="/dev/ttyUSB0" --change for one available on your system.

fd=serial_open(SERIAL_DEVICE,{O_RDWR, O_NOCTTY, O_NDELAY})
if fd=-1 then
  puts(1,"failed to open serial device, aborting.\n")
  abort(-1)
end if
printf(1,"testing serial communication (device handle=%d)\n",fd)
old_termios=serial_get_attr(fd) -- preserve original config.

--simplest way to configure serial port
serial_set_parameters(fd,"baud=38400,bits=8,stop=1,parity=none,flow=none")

-- more complex way but with more detaitled control.
--new_termios=repeat(0,TIOS_OSPEED)
--new_termios[TIOS_CC]=repeat(0,NCCS)
--new_termios[TIOS_CC][VEOF]=4   -- end of file character
--new_termios[TIOS_CC][VMIN]=1   -- wait for 1 character
--new_termios[TIOS_CC][VTIME]=1  -- inter-character wait delay .1 second.
--new_termios[TIOS_IFLAG]=or_all({IGNPAR,ICRNL}) -- ignore parity and framing error
                                                 -- convert received CR to NL
--new_termios[TIOS_OFLAG]=0
--new_termios[TIOS_CFLAG]=or_all({B38400,CS8,CLOCAL,CREAD})--no flow control
--new_termios[TIOS_LFLAG]=ICANON -- if your prefer raw mode skip this one. 
--serial_set_attr(fd,TCSANOW, new_termios) -- set new configuration.


integer key
object c, fnVal

--fnVal = serial_write(fd,"ready to receive\n")
while 1 do
   key = get_key()
   if key = 27 then exit end if
   if key > 0 then
     fnVal=serial_write(fd,{key})
   end if
   c = serial_read(fd,1)
   if sequence(c) then
     puts(1,c)
   end if  
end while
serial_set_attr(fd,TCSANOW,old_termios)--restore original config.
close(fd)

table of contents