Handle non-standard baud rates in sport_open().
This should allow the use of the Olimex MSP430-JTAG-ISO on Windows (and other platforms, if handling is implemented).
This commit is contained in:
parent
68f968a637
commit
cf5b7f3399
|
@ -28,11 +28,6 @@
|
|||
#include "output.h"
|
||||
#include "sport.h"
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <linux/serial.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
struct uif_transport {
|
||||
struct transport base;
|
||||
|
||||
|
@ -80,37 +75,6 @@ static void serial_destroy(transport_t tr_base)
|
|||
free(tr);
|
||||
}
|
||||
|
||||
#if defined(__linux__)
|
||||
static int open_olimex_iso(const char *device)
|
||||
{
|
||||
int fd = open(device, O_RDWR | O_NOCTTY);
|
||||
struct termios attr;
|
||||
struct serial_struct serial_info;
|
||||
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
|
||||
tcgetattr(fd, &attr);
|
||||
cfmakeraw(&attr);
|
||||
cfsetispeed(&attr, B38400);
|
||||
cfsetospeed(&attr, B38400);
|
||||
|
||||
serial_info.flags = ASYNC_SPD_CUST;
|
||||
serial_info.custom_divisor = 120;
|
||||
if (ioctl(fd, TIOCSSERIAL, &serial_info) < 0) {
|
||||
printc_err("open_olimex_iso: can't do "
|
||||
"ioctl TIOCSSERIAL: %s\n",
|
||||
last_error());
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tcsetattr(fd, TCSAFLUSH, &attr) < 0)
|
||||
return -1;
|
||||
|
||||
return fd;
|
||||
}
|
||||
#endif
|
||||
|
||||
transport_t uif_open(const char *device, uif_type_t type)
|
||||
{
|
||||
struct uif_transport *tr = malloc(sizeof(*tr));
|
||||
|
@ -144,13 +108,8 @@ transport_t uif_open(const char *device, uif_type_t type)
|
|||
break;
|
||||
|
||||
case UIF_TYPE_OLIMEX_ISO:
|
||||
#if defined(__linux__)
|
||||
printc("Trying to open Olimex (ISO) on %s...\n", device);
|
||||
tr->serial_fd = open_olimex_iso(device);
|
||||
#else
|
||||
printc_err("uif_open: ioctl TIOCSSERIAL not supported "
|
||||
"on this platform\n");
|
||||
#endif
|
||||
tr->serial_fd = sport_open(device, 200000, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
45
util/sport.c
45
util/sport.c
|
@ -23,6 +23,11 @@
|
|||
|
||||
#include "sport.h"
|
||||
#include "util.h"
|
||||
#include "output.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#include <linux/serial.h>
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
|
||||
|
@ -57,6 +62,35 @@ static int rate_to_code(int rate)
|
|||
return -1;
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
static int set_nonstandard_rate(int fd, int rate)
|
||||
{
|
||||
struct serial_struct ss;
|
||||
|
||||
if (ioctl(fd, TIOCGSERIAL, &ss) < 0) {
|
||||
pr_error("sport: TIOCGSERIAL failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ss.custom_divisor = ss.baud_base / rate;
|
||||
ss.flags = ASYNC_SPD_CUST;
|
||||
|
||||
if (ioctl(fd, TIOCSSERIAL, &ss) < 0) {
|
||||
pr_error("sport: TIOCSSERIAL failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int set_nonstandard_rate(int fd, int rate)
|
||||
{
|
||||
printc_err("sport: Can't set non-standard baud rate %d on "
|
||||
"this platform\n", rate);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
sport_t sport_open(const char *device, int rate, int flags)
|
||||
{
|
||||
int fd = open(device, O_RDWR | O_NOCTTY);
|
||||
|
@ -72,6 +106,17 @@ sport_t sport_open(const char *device, int rate, int flags)
|
|||
if (rate_code >= 0) {
|
||||
cfsetispeed(&attr, rate_code);
|
||||
cfsetospeed(&attr, rate_code);
|
||||
} else {
|
||||
if (set_nonstandard_rate(fd, rate) < 0) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* We need to set the rate code to B38400 on Linux for
|
||||
* the non-standard rate to take effect.
|
||||
*/
|
||||
cfsetispeed(&attr, B38400);
|
||||
cfsetospeed(&attr, B38400);
|
||||
}
|
||||
|
||||
if (flags & SPORT_EVEN_PARITY)
|
||||
|
|
Loading…
Reference in New Issue