move posix-specific serial port comms to serial.c
This commit is contained in:
parent
54dc4bc703
commit
d02a535e05
|
@ -19,8 +19,17 @@
|
||||||
|
|
||||||
#include <glob.h>
|
#include <glob.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include "sigrok.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
char *serial_port_glob[] = {
|
char *serial_port_glob[] = {
|
||||||
/* Linux */
|
/* Linux */
|
||||||
|
@ -56,3 +65,61 @@ GSList *list_serial_ports(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int serial_open(const char *pathname, int flags)
|
||||||
|
{
|
||||||
|
|
||||||
|
return open(pathname, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int serial_close(int fd)
|
||||||
|
{
|
||||||
|
|
||||||
|
return close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void *serial_backup_params(int fd)
|
||||||
|
{
|
||||||
|
struct termios *term;
|
||||||
|
|
||||||
|
term = malloc(sizeof(struct termios));
|
||||||
|
tcgetattr(fd, term);
|
||||||
|
|
||||||
|
return term;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void serial_restore_params(int fd, void *backup)
|
||||||
|
{
|
||||||
|
|
||||||
|
tcsetattr(fd, TCSADRAIN, (struct termios *) backup);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* flowcontrol 1 = rts/cts 2 = xon/xoff */
|
||||||
|
int serial_set_params(int fd, int speed, int bits, int parity, int stopbits, int flowcontrol)
|
||||||
|
{
|
||||||
|
struct termios term;
|
||||||
|
|
||||||
|
/* only supporting what we need really -- currently just the OLS driver */
|
||||||
|
if(speed != 115200 || bits != 8 || parity != 0 || stopbits != 1 || flowcontrol != 2)
|
||||||
|
return SIGROK_ERR;
|
||||||
|
|
||||||
|
if(tcgetattr(fd, &term) < 0)
|
||||||
|
return SIGROK_ERR;
|
||||||
|
if(cfsetispeed(&term, B115200) < 0)
|
||||||
|
return SIGROK_ERR;
|
||||||
|
term.c_cflag &= ~CSIZE;
|
||||||
|
term.c_cflag |= CS8;
|
||||||
|
term.c_cflag &= ~CSTOPB;
|
||||||
|
term.c_cflag |= IXON | IXOFF;
|
||||||
|
term.c_iflag |= IGNPAR;
|
||||||
|
if(tcsetattr(fd, TCSADRAIN, &term) < 0)
|
||||||
|
return SIGROK_ERR;
|
||||||
|
|
||||||
|
return SIGROK_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -190,9 +190,8 @@ static int hw_init(char *deviceinfo)
|
||||||
struct sigrok_device_instance *sdi;
|
struct sigrok_device_instance *sdi;
|
||||||
GSList *ports, *l;
|
GSList *ports, *l;
|
||||||
GPollFD *fds;
|
GPollFD *fds;
|
||||||
struct termios term, *prev_termios;
|
|
||||||
int devcnt, final_devcnt, num_ports, fd, ret, i;
|
int devcnt, final_devcnt, num_ports, fd, ret, i;
|
||||||
char buf[8], **device_names;
|
char buf[8], **device_names, **serial_params;
|
||||||
|
|
||||||
if(deviceinfo)
|
if(deviceinfo)
|
||||||
ports = g_slist_append(NULL, strdup(deviceinfo));
|
ports = g_slist_append(NULL, strdup(deviceinfo));
|
||||||
|
@ -203,7 +202,7 @@ static int hw_init(char *deviceinfo)
|
||||||
num_ports = g_slist_length(ports);
|
num_ports = g_slist_length(ports);
|
||||||
fds = calloc(1, num_ports * sizeof(GPollFD));
|
fds = calloc(1, num_ports * sizeof(GPollFD));
|
||||||
device_names = malloc(num_ports * (sizeof(char *)));
|
device_names = malloc(num_ports * (sizeof(char *)));
|
||||||
prev_termios = malloc(num_ports * sizeof(struct termios));
|
serial_params = malloc(num_ports * (sizeof(char *)));
|
||||||
devcnt = 0;
|
devcnt = 0;
|
||||||
for(l = ports; l; l = l->next) {
|
for(l = ports; l; l = l->next) {
|
||||||
/* The discovery procedure is like this: first send the Reset command (0x00) 5 times,
|
/* The discovery procedure is like this: first send the Reset command (0x00) 5 times,
|
||||||
|
@ -213,28 +212,22 @@ static int hw_init(char *deviceinfo)
|
||||||
* first, then wait for all of them to respond with g_poll().
|
* first, then wait for all of them to respond with g_poll().
|
||||||
*/
|
*/
|
||||||
g_message("probing %s...", (char *) l->data);
|
g_message("probing %s...", (char *) l->data);
|
||||||
fd = open(l->data, O_RDWR | O_NONBLOCK);
|
fd = serial_open(l->data, O_RDWR | O_NONBLOCK);
|
||||||
if(fd != -1) {
|
if(fd != -1) {
|
||||||
tcgetattr(fd, &prev_termios[devcnt]);
|
serial_params[devcnt] = serial_backup_params(fd);
|
||||||
tcgetattr(fd, &term);
|
serial_set_params(fd, 115200, 8, 0, 1, 2);
|
||||||
cfsetispeed(&term, SERIAL_SPEED);
|
|
||||||
term.c_cflag &= ~CSIZE;
|
|
||||||
term.c_cflag |= CS8;
|
|
||||||
term.c_cflag &= ~CSTOPB;
|
|
||||||
term.c_cflag |= IXON | IXOFF;
|
|
||||||
term.c_iflag |= IGNPAR;
|
|
||||||
tcsetattr(fd, TCSADRAIN, &term);
|
|
||||||
ret = SIGROK_OK;
|
ret = SIGROK_OK;
|
||||||
for(i = 0; i < 5; i++) {
|
for(i = 0; i < 5; i++) {
|
||||||
if( (ret = send_shortcommand(fd, CMD_RESET)) != SIGROK_OK) {
|
if( (ret = send_shortcommand(fd, CMD_RESET)) != SIGROK_OK) {
|
||||||
/* serial port is not writable... restore port settings */
|
/* serial port is not writable */
|
||||||
tcsetattr(fd, TCSADRAIN, &prev_termios[devcnt]);
|
|
||||||
close(fd);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(ret != SIGROK_OK)
|
if(ret != SIGROK_OK) {
|
||||||
|
serial_restore_params(fd, serial_params[devcnt]);
|
||||||
|
serial_close(fd);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
send_shortcommand(fd, CMD_ID);
|
send_shortcommand(fd, CMD_ID);
|
||||||
fds[devcnt].fd = fd;
|
fds[devcnt].fd = fd;
|
||||||
fds[devcnt].events = G_IO_IN;
|
fds[devcnt].events = G_IO_IN;
|
||||||
|
@ -262,7 +255,7 @@ static int hw_init(char *deviceinfo)
|
||||||
sdi->serial = serial_device_instance_new(device_names[i], -1);
|
sdi->serial = serial_device_instance_new(device_names[i], -1);
|
||||||
device_instances = g_slist_append(device_instances, sdi);
|
device_instances = g_slist_append(device_instances, sdi);
|
||||||
final_devcnt++;
|
final_devcnt++;
|
||||||
close(fds[i].fd);
|
serial_close(fds[i].fd);
|
||||||
fds[i].fd = 0;
|
fds[i].fd = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -270,14 +263,15 @@ static int hw_init(char *deviceinfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fds[i].fd != 0) {
|
if(fds[i].fd != 0) {
|
||||||
tcsetattr(fds[i].fd, TCSADRAIN, &prev_termios[i]);
|
serial_restore_params(fds[i].fd, serial_params[i]);
|
||||||
close(fds[i].fd);
|
serial_close(fds[i].fd);
|
||||||
}
|
}
|
||||||
|
free(serial_params[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(fds);
|
free(fds);
|
||||||
free(device_names);
|
free(device_names);
|
||||||
free(prev_termios);
|
free(serial_params);
|
||||||
g_slist_free(ports);
|
g_slist_free(ports);
|
||||||
|
|
||||||
cur_samplerate = samplerates.low;
|
cur_samplerate = samplerates.low;
|
||||||
|
@ -293,7 +287,7 @@ static int hw_opendev(int device_index)
|
||||||
if(!(sdi = get_sigrok_device_instance(device_instances, device_index)))
|
if(!(sdi = get_sigrok_device_instance(device_instances, device_index)))
|
||||||
return SIGROK_ERR;
|
return SIGROK_ERR;
|
||||||
|
|
||||||
sdi->serial->fd = open(sdi->serial->port, O_RDWR);
|
sdi->serial->fd = serial_open(sdi->serial->port, O_RDWR);
|
||||||
if(sdi->serial->fd == -1)
|
if(sdi->serial->fd == -1)
|
||||||
return SIGROK_ERR;
|
return SIGROK_ERR;
|
||||||
|
|
||||||
|
@ -311,7 +305,7 @@ static void hw_closedev(int device_index)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(sdi->serial->fd != -1) {
|
if(sdi->serial->fd != -1) {
|
||||||
close(sdi->serial->fd);
|
serial_close(sdi->serial->fd);
|
||||||
sdi->serial->fd = -1;
|
sdi->serial->fd = -1;
|
||||||
sdi->status = ST_INACTIVE;
|
sdi->status = ST_INACTIVE;
|
||||||
}
|
}
|
||||||
|
@ -328,7 +322,7 @@ static void hw_cleanup(void)
|
||||||
for(l = device_instances; l; l = l->next) {
|
for(l = device_instances; l; l = l->next) {
|
||||||
sdi = l->data;
|
sdi = l->data;
|
||||||
if(sdi->serial->fd != -1)
|
if(sdi->serial->fd != -1)
|
||||||
close(sdi->serial->fd);
|
serial_close(sdi->serial->fd);
|
||||||
sigrok_device_instance_free(sdi);
|
sigrok_device_instance_free(sdi);
|
||||||
}
|
}
|
||||||
g_slist_free(device_instances);
|
g_slist_free(device_instances);
|
||||||
|
@ -546,7 +540,7 @@ static int receive_data(int fd, int revents, void *user_data)
|
||||||
/* this is the main loop telling us a timeout was reached, or we've
|
/* this is the main loop telling us a timeout was reached, or we've
|
||||||
* acquired all the samples we asked for -- we're done */
|
* acquired all the samples we asked for -- we're done */
|
||||||
tcflush(fd, TCIOFLUSH);
|
tcflush(fd, TCIOFLUSH);
|
||||||
close(fd);
|
serial_close(fd);
|
||||||
packet.type = DF_END;
|
packet.type = DF_END;
|
||||||
packet.length = 0;
|
packet.length = 0;
|
||||||
session_bus(user_data, &packet);
|
session_bus(user_data, &packet);
|
||||||
|
|
5
sigrok.h
5
sigrok.h
|
@ -396,5 +396,10 @@ int ezusb_reset(struct libusb_device_handle *hdl, int set_clear);
|
||||||
int ezusb_install_firmware(libusb_device_handle *hdl, char *filename);
|
int ezusb_install_firmware(libusb_device_handle *hdl, char *filename);
|
||||||
|
|
||||||
GSList *list_serial_ports(void);
|
GSList *list_serial_ports(void);
|
||||||
|
int serial_open(const char *pathname, int flags);
|
||||||
|
int serial_close(int fd);
|
||||||
|
void *serial_backup_params(int fd);
|
||||||
|
void serial_restore_params(int fd, void *backup);
|
||||||
|
int serial_set_params(int fd, int speed, int bits, int parity, int stopbits, int flowcontrol);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue