patch #8380: adds 500k 1M 2M baud to ser_posix.c
* ser_posix.c: Add a hack to allow for arbitrary baud rates on Linux git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1351 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
parent
3fd1765025
commit
be5defaa86
|
@ -1,3 +1,9 @@
|
|||
2014-11-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #8380: adds 500k 1M 2M baud to ser_posix.c
|
||||
* ser_posix.c: Add a hack to allow for arbitrary baud rates on
|
||||
Linux
|
||||
|
||||
2014-11-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #8437: [PATCH] Serial-over-ethernet for Win32
|
||||
|
|
4
NEWS
4
NEWS
|
@ -28,6 +28,9 @@ Current:
|
|||
- The "-P net:" syntax (forwarding of serial data over TCP) is now
|
||||
also implemented for Win32 systems.
|
||||
|
||||
- Allow for arbitrary serial baudrates under Linux (OSX and *BSD
|
||||
could already handle it).
|
||||
|
||||
|
||||
* New devices supported:
|
||||
- AT90PWM216 (bug #42310: New part description for AT90PWM216)
|
||||
|
@ -57,6 +60,7 @@ Current:
|
|||
- bug #40870: config nitpick: ATtiny25/45/85 have 1 calibration byte not 2
|
||||
- bug #42908: no external reset at JTAGICE3
|
||||
- patch #8437: [PATCH] Serial-over-ethernet for Win32
|
||||
- patch #8380: adds 500k 1M 2M baud to ser_posix.c
|
||||
|
||||
* Internals:
|
||||
- Removing exit calls from config parser
|
||||
|
|
88
ser_posix.c
88
ser_posix.c
|
@ -37,6 +37,9 @@
|
|||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#ifdef __linux__
|
||||
#include <linux/serial.h>
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
|
@ -52,8 +55,13 @@ struct baud_mapping {
|
|||
speed_t speed;
|
||||
};
|
||||
|
||||
/* There are a lot more baud rates we could handle, but what's the point? */
|
||||
static struct termios original_termios;
|
||||
static int saved_original_termios;
|
||||
|
||||
#if !defined __linux__
|
||||
/* For linux this mapping is no longer needed.
|
||||
* (OSX and *BSD do not need this mapping either because for them,
|
||||
* Bxxx is the same as xxx.) */
|
||||
static struct baud_mapping baud_lookup_table [] = {
|
||||
{ 1200, B1200 },
|
||||
{ 2400, B2400 },
|
||||
|
@ -73,8 +81,6 @@ static struct baud_mapping baud_lookup_table [] = {
|
|||
{ 0, 0 } /* Terminator. */
|
||||
};
|
||||
|
||||
static struct termios original_termios;
|
||||
static int saved_original_termios;
|
||||
|
||||
static speed_t serial_baud_lookup(long baud)
|
||||
{
|
||||
|
@ -95,12 +101,19 @@ static speed_t serial_baud_lookup(long baud)
|
|||
|
||||
return baud;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int ser_setspeed(union filedescriptor *fd, long baud)
|
||||
{
|
||||
int rc;
|
||||
struct termios termios;
|
||||
#if defined __linux__
|
||||
/* for linux no conversion is needed*/
|
||||
speed_t speed = baud;
|
||||
#else
|
||||
/* converting the baud rate to the bit set needed by posix way*/
|
||||
speed_t speed = serial_baud_lookup (baud);
|
||||
#endif
|
||||
|
||||
if (!isatty(fd->ifd))
|
||||
return -ENOTTY;
|
||||
|
@ -128,16 +141,79 @@ static int ser_setspeed(union filedescriptor *fd, long baud)
|
|||
termios.c_cflag = (CS8 | CREAD | CLOCAL);
|
||||
termios.c_cc[VMIN] = 1;
|
||||
termios.c_cc[VTIME] = 0;
|
||||
#ifdef __linux__
|
||||
/* Support for custom baud rate for linux is implemented by setting
|
||||
* a dummy baud rate of 38400 and manupulating the custom divider of
|
||||
* the serial interface*/
|
||||
struct serial_struct ss;
|
||||
int ioret = ioctl(fd->ifd, TIOCGSERIAL, &ss);
|
||||
if (ioret < 0){
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: Cannot get serial port settings. ioctl returned %d\n",
|
||||
progname, ioret);
|
||||
return -errno;
|
||||
}
|
||||
ss.flags = (ss.flags & ~ASYNC_SPD_MASK) | ASYNC_SPD_CUST;
|
||||
ss.custom_divisor = (ss.baud_base + (speed / 2)) / speed;
|
||||
unsigned int closestSpeed = ss.baud_base / ss.custom_divisor;
|
||||
|
||||
cfsetospeed(&termios, speed);
|
||||
cfsetispeed(&termios, speed);
|
||||
|
||||
if (closestSpeed < speed * 98 / 100 || closestSpeed > speed * 102 / 100) {
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: Cannot set serial port speed to %d. Closest possible is %d\n",
|
||||
progname, speed, closestSpeed);
|
||||
return -errno;
|
||||
}
|
||||
ioret= ioctl(fd->ifd, TIOCSSERIAL, &ss);
|
||||
if (ioret < 0){
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: Cannot set serial port speed to %d. ioctl returned %d\n",
|
||||
progname, speed, ioret);
|
||||
return -errno;
|
||||
}
|
||||
if (cfsetispeed(&termios, B38400) < 0){
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: cfsetispeed: failed to set dummy baud\n",
|
||||
progname);
|
||||
return -errno;
|
||||
}
|
||||
if (cfsetospeed(&termios, B38400) < 0){
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: cfsetospeed: failed to set dummy baud\n",
|
||||
progname);
|
||||
return -errno;
|
||||
}
|
||||
#else /* !linux */
|
||||
if (cfsetospeed(&termios, speed) < 0){
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: cfsetospeed: failed to set speed: %d\n",
|
||||
progname, speed);
|
||||
return -errno;
|
||||
}
|
||||
if (cfsetispeed(&termios, speed) < 0){
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: cfsetispeed: failed to set speed: %d\n",
|
||||
progname, speed);
|
||||
return -errno;
|
||||
}
|
||||
#endif /* linux */
|
||||
rc = tcsetattr(fd->ifd, TCSANOW, &termios);
|
||||
if (rc < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: ser_setspeed(): tcsetattr() failed\n",
|
||||
progname);
|
||||
return -errno;
|
||||
}
|
||||
#ifdef __linux__
|
||||
/* a bit more linux specific stuff to set custom baud rates*/
|
||||
if (ioctl(fd->ifd, TIOCGSERIAL, &ss) < 0){
|
||||
avrdude_message(MSG_INFO, "%s: ioctl: failed to get port settins\n", progname);
|
||||
return -errno;
|
||||
}
|
||||
ss.flags &= ~ASYNC_SPD_MASK;
|
||||
if (ioctl(fd->ifd, TIOCSSERIAL, &ss) < 0){
|
||||
avrdude_message(MSG_INFO, "%s: ioctl: failed to set port settins\n", progname);
|
||||
return -errno;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Everything is now set up for a local line without modem control
|
||||
|
|
Loading…
Reference in New Issue