/*
 *  RS-232 Hardware Manipulation Examples
 *  Copyright 2003 by Floyd L. Davidson, floyd@barrow.com
 *
 *  This program is free software; you can redistribute it
 *  and/or modify it under the terms of the GNU General Public
 *  License as published by the Free Software Foundation;
 *  either version 2, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be
 *  useful, but WITHOUT ANY WARRANTY; without even the implied
 *  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 *  PURPOSE.  See the GNU General Public License for details.
 *
 *  serial_spd.c  --  rate generator custom bitrate configuration
 *
 *  $Id: serial_spd.c,v 1.1.0.2 2004/07/28 17:03:12 floyd Exp floyd $
 */

/*
 *  This program is platform specific to Linux.  Definitions
 *  for ASYNC_SPD_MASK and ASYNC_SPD_CUST are found in
 *  <linux/serial.h>.
 *
 *  Porting to other Unix platforms probably requires only
 *  using grep to find the same or similar constants defined
 *  in platform specific headers.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <errno.h>

#ifdef __linux__
#include <linux/serial.h>
#endif

#define DEVICE "/dev/ttyS0"

int
main(void)
{
  struct serial_struct serinfo;
  int	fd;

  if ((fd = open(DEVICE, O_RDWR | O_NONBLOCK)) < 0) {
    perror(DEVICE);
    exit(1);
  }

  if (ioctl(fd, TIOCGSERIAL, &serinfo) < 0) {
    perror("Cannot get serial info");
    exit(2);
  }

  fprintf(stderr, "basebaud is: %d\n", serinfo.baud_base);
  serinfo.baud_base      = 57600;  
  fprintf(stderr, "divisor is:  %d\n", serinfo.custom_divisor);
  serinfo.custom_divisor = 4;      

  if (ioctl(fd, TIOCSSERIAL, &serinfo) < 0) {
    perror("Cannot set serial info");
    exit(3);
  }

  serinfo.flags &= ~ASYNC_SPD_MASK;
  serinfo.flags |=  ASYNC_SPD_CUST;

  if (ioctl(fd, TIOCSSERIAL, &serinfo) < 0) {
    perror("Cannot set SPD info");
    exit(4);
  }
  
  close(fd);
  return 0;
}