From 583f00e0b8efe2832f63efb478a51d3ad35e92ed Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Sun, 7 Oct 2007 22:16:03 +0200 Subject: Included SI2E avr modules. Well, this need more works... --- digital/avr/modules/uart/uart.host.c | 175 +++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 digital/avr/modules/uart/uart.host.c (limited to 'digital/avr/modules/uart/uart.host.c') diff --git a/digital/avr/modules/uart/uart.host.c b/digital/avr/modules/uart/uart.host.c new file mode 100644 index 00000000..9a335b2a --- /dev/null +++ b/digital/avr/modules/uart/uart.host.c @@ -0,0 +1,175 @@ +/* uart.host.c */ +/* avr.uart - UART AVR module. {{{ + * + * Copyright (C) 2005 Nicolas Schodet + * + * Robot APB Team/Efrei 2006. + * Web: http://assos.efrei.fr/robot/ + * Email: robot AT efrei DOT fr + * + * 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 of the License, 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 more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * }}} */ +#define _GNU_SOURCE +#include "common.h" +#include "uart.h" +#include "modules/host/host.h" + +#include "uart_common.h" + +#if AC_UART (PORT) != -1 + +#include +#include +#include +#include +#include +#include +#include + +/* Check uart driver. */ +#if UART_N == 0 +# define STDIO 1 +# define PTS 2 +# if AC_UART (HOST_DRIVER) == STDIO +# define DRIVER_STDIO +# elif AC_UART (HOST_DRIVER) == PTS +# else +# error "uart: invalid host driver" +# endif +#endif + +#ifndef DRIVER_STDIO + +/* Pseudo terminal file descriptor. */ +static int uart_pt_fd; + +/** Setup a non canonical mode. */ +static void +setup_raw (int fd) +{ + struct termios tc; + tcgetattr (fd, &tc); + tc.c_iflag &= ~(IGNPAR | PARMRK | ISTRIP | IGNBRK | BRKINT | IGNCR | + ICRNL | INLCR | IXON | IXOFF | IXANY | IMAXBEL); + tc.c_iflag |= INPCK; + tc.c_oflag &= ~(OPOST); + tc.c_cflag &= ~(HUPCL | CSTOPB | PARENB | PARODD | CSIZE); + tc.c_cflag |= CS8 | CLOCAL | CREAD; + tc.c_lflag &= ~(ICANON | ECHO | ISIG | IEXTEN | NOFLSH | TOSTOP); + tc.c_cc[VTIME] = 0; + tc.c_cc[VMIN] = 1; + tcflush (fd, TCIFLUSH); + tcsetattr (fd, TCSANOW, &tc); +} + +#endif /* DRIVER_STDIO */ + +/** Initialise uart. */ +void +uart_init (void) +{ +#ifdef DRIVER_STDIO + int r; +# define uart_pt_fd_in 0 +# define uart_pt_fd_out 1 + /* Always use line buffering. */ + r = setvbuf (stdout, 0, _IOLBF, BUFSIZ); + assert (r == 0); +#else +# define uart_pt_fd_in uart_pt_fd +# define uart_pt_fd_out uart_pt_fd + int slave_fd; + const char *name; +#define STRINGIFY(x) #x +#define FILE_NAME(x) "uart" STRINGIFY(x) ".pts" + /* Try to access an already opened pts. */ + uart_pt_fd = host_fetch_integer (FILE_NAME (UART_N)); + if (uart_pt_fd == -1) + { + /* Open and unlock pt. */ + if (openpty (&uart_pt_fd, &slave_fd, 0, 0, 0) == -1 + || grantpt (uart_pt_fd) == -1 + || unlockpt (uart_pt_fd) == -1) + assert_perror (errno); + /* Make a link to the slave pts. */ + unlink (FILE_NAME (UART_N)); + name = ptsname (uart_pt_fd); + assert (name); + if (symlink (name, FILE_NAME (UART_N)) == -1) + assert_perror (errno); + /* Register the file descriptor in case of reset. */ + host_register_integer (FILE_NAME (UART_N), uart_pt_fd); + /* Make slave raw. */ + setup_raw (slave_fd); + /* slave_fd is left open. */ + } +#endif +} + +/** Read a char. */ +uint8_t +uart_getc (void) +{ + uint8_t c; + int n; + n = read (uart_pt_fd_in, &c, 1); + if (n == -1) + assert_perror (errno); +#ifdef DRIVER_STDIO + /* Quit if EOF from stdin. */ + if (n == 0) + exit (0); + if (c == '\n') + c = '\r'; +#else + /* This is a quite unusual and dangerous behavior... */ + if (n == 0) + return 0xff; +#endif + return c; +} + +/** Write a char. */ +void +uart_putc (uint8_t c) +{ +#ifdef DRIVER_STDIO + if (c == '\r') + c = '\n'; +#endif + write (uart_pt_fd_out, &c, 1); +} + +/** Retrieve availlable chars. */ +uint8_t +uart_poll (void) +{ + fd_set fds; + struct timeval tv; + int r; + /* Use select to poll. */ + FD_ZERO (&fds); + FD_SET (uart_pt_fd_in, &fds); + tv.tv_sec = 0; + tv.tv_usec = 0; + r = select (FD_SETSIZE, &fds, 0, 0, &tv); + /* Check result. */ + if (r == -1) + assert_perror (errno); + return r; +} + +#endif /* AC_UART (PORT) != -1 */ -- cgit v1.2.3