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>
|
2014-11-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||||
|
|
||||||
patch #8437: [PATCH] Serial-over-ethernet for Win32
|
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
|
- The "-P net:" syntax (forwarding of serial data over TCP) is now
|
||||||
also implemented for Win32 systems.
|
also implemented for Win32 systems.
|
||||||
|
|
||||||
|
- Allow for arbitrary serial baudrates under Linux (OSX and *BSD
|
||||||
|
could already handle it).
|
||||||
|
|
||||||
|
|
||||||
* New devices supported:
|
* New devices supported:
|
||||||
- AT90PWM216 (bug #42310: New part description for AT90PWM216)
|
- 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 #40870: config nitpick: ATtiny25/45/85 have 1 calibration byte not 2
|
||||||
- bug #42908: no external reset at JTAGICE3
|
- bug #42908: no external reset at JTAGICE3
|
||||||
- patch #8437: [PATCH] Serial-over-ethernet for Win32
|
- patch #8437: [PATCH] Serial-over-ethernet for Win32
|
||||||
|
- patch #8380: adds 500k 1M 2M baud to ser_posix.c
|
||||||
|
|
||||||
* Internals:
|
* Internals:
|
||||||
- Removing exit calls from config parser
|
- Removing exit calls from config parser
|
||||||
|
|
88
ser_posix.c
88
ser_posix.c
|
@ -37,6 +37,9 @@
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
#ifdef __linux__
|
||||||
|
#include <linux/serial.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
|
@ -52,8 +55,13 @@ struct baud_mapping {
|
||||||
speed_t speed;
|
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 [] = {
|
static struct baud_mapping baud_lookup_table [] = {
|
||||||
{ 1200, B1200 },
|
{ 1200, B1200 },
|
||||||
{ 2400, B2400 },
|
{ 2400, B2400 },
|
||||||
|
@ -73,8 +81,6 @@ static struct baud_mapping baud_lookup_table [] = {
|
||||||
{ 0, 0 } /* Terminator. */
|
{ 0, 0 } /* Terminator. */
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct termios original_termios;
|
|
||||||
static int saved_original_termios;
|
|
||||||
|
|
||||||
static speed_t serial_baud_lookup(long baud)
|
static speed_t serial_baud_lookup(long baud)
|
||||||
{
|
{
|
||||||
|
@ -95,12 +101,19 @@ static speed_t serial_baud_lookup(long baud)
|
||||||
|
|
||||||
return baud;
|
return baud;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int ser_setspeed(union filedescriptor *fd, long baud)
|
static int ser_setspeed(union filedescriptor *fd, long baud)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
struct termios termios;
|
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);
|
speed_t speed = serial_baud_lookup (baud);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!isatty(fd->ifd))
|
if (!isatty(fd->ifd))
|
||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
|
@ -128,16 +141,79 @@ static int ser_setspeed(union filedescriptor *fd, long baud)
|
||||||
termios.c_cflag = (CS8 | CREAD | CLOCAL);
|
termios.c_cflag = (CS8 | CREAD | CLOCAL);
|
||||||
termios.c_cc[VMIN] = 1;
|
termios.c_cc[VMIN] = 1;
|
||||||
termios.c_cc[VTIME] = 0;
|
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);
|
if (closestSpeed < speed * 98 / 100 || closestSpeed > speed * 102 / 100) {
|
||||||
cfsetispeed(&termios, speed);
|
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);
|
rc = tcsetattr(fd->ifd, TCSANOW, &termios);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
avrdude_message(MSG_INFO, "%s: ser_setspeed(): tcsetattr() failed\n",
|
avrdude_message(MSG_INFO, "%s: ser_setspeed(): tcsetattr() failed\n",
|
||||||
progname);
|
progname);
|
||||||
return -errno;
|
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
|
* Everything is now set up for a local line without modem control
|
||||||
|
|
Loading…
Reference in New Issue