174 lines
3.5 KiB
C
174 lines
3.5 KiB
C
#include "Serial.h"
|
|
|
|
extern void cleanup();
|
|
|
|
int open_port(char* port) {
|
|
int fd;
|
|
fd = open(port, O_RDWR | O_NOCTTY | O_SYNC | O_NDELAY);
|
|
|
|
if (fd == -1) {
|
|
perror("The serial port could not be opened");
|
|
cleanup();
|
|
exit(1);
|
|
} else {
|
|
fcntl(fd, F_SETFL, 0);
|
|
}
|
|
|
|
return fd;
|
|
}
|
|
|
|
int close_port(int fd) {
|
|
return close(fd);
|
|
}
|
|
|
|
void set_speed(void *tty_s, int speed) {
|
|
cfsetospeed(tty_s, speed);
|
|
cfsetispeed(tty_s, speed);
|
|
}
|
|
|
|
bool setup_port(int fd, int speed) {
|
|
struct termios tty;
|
|
if (tcgetattr(fd, &tty) != 0) {
|
|
perror("Error setting port speed, could not read port parameters");
|
|
return false;
|
|
}
|
|
|
|
switch (speed) {
|
|
case 0:
|
|
set_speed(&tty, B0);
|
|
break;
|
|
case 50:
|
|
set_speed(&tty, B50);
|
|
break;
|
|
case 75:
|
|
set_speed(&tty, B75);
|
|
break;
|
|
case 110:
|
|
set_speed(&tty, B110);
|
|
break;
|
|
case 134:
|
|
set_speed(&tty, B134);
|
|
break;
|
|
case 150:
|
|
set_speed(&tty, B150);
|
|
break;
|
|
case 200:
|
|
set_speed(&tty, B200);
|
|
break;
|
|
case 300:
|
|
set_speed(&tty, B300);
|
|
break;
|
|
case 600:
|
|
set_speed(&tty, B600);
|
|
break;
|
|
case 1200:
|
|
set_speed(&tty, B1200);
|
|
break;
|
|
case 2400:
|
|
set_speed(&tty, B2400);
|
|
break;
|
|
case 4800:
|
|
set_speed(&tty, B4800);
|
|
break;
|
|
case 9600:
|
|
set_speed(&tty, B9600);
|
|
break;
|
|
case 19200:
|
|
set_speed(&tty, B19200);
|
|
break;
|
|
case 38400:
|
|
set_speed(&tty, B38400);
|
|
break;
|
|
case 57600:
|
|
set_speed(&tty, B57600);
|
|
break;
|
|
case 115200:
|
|
set_speed(&tty, B115200);
|
|
break;
|
|
case 230400:
|
|
set_speed(&tty, B230400);
|
|
break;
|
|
default:
|
|
printf("Error: Invalid port speed %d specified\r\n", speed);
|
|
cleanup();
|
|
exit(1);
|
|
return false;
|
|
}
|
|
|
|
// Set 8-bit characters, no parity, one stop bit
|
|
tty.c_cflag |= CS8;
|
|
tty.c_cflag &= ~PARENB;
|
|
tty.c_cflag &= ~CSTOPB;
|
|
|
|
// Disable hardware flow control
|
|
tty.c_cflag &= ~CRTSCTS;
|
|
|
|
// Enable reading and ignore modem
|
|
// control lines
|
|
tty.c_cflag |= CREAD | CLOCAL;
|
|
|
|
// Disable canonical mode, echo
|
|
// and signal characters.
|
|
tty.c_lflag &= ~ICANON;
|
|
tty.c_lflag &= ~ECHO;
|
|
tty.c_lflag &= ~ECHOE;
|
|
tty.c_lflag &= ~ECHONL;
|
|
tty.c_lflag &= ~ISIG;
|
|
|
|
// Disable processing of input,
|
|
// just pass the raw data.
|
|
tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL);
|
|
|
|
// Disable XON/XOFF software flow control.
|
|
tty.c_iflag &= ~(IXON | IXOFF | IXANY);
|
|
|
|
// Disable processing output bytes
|
|
// and new line conversions
|
|
tty.c_oflag &= ~OPOST;
|
|
tty.c_oflag &= ~ONLCR;
|
|
|
|
// Block forever until at least one byte is read.
|
|
tty.c_cc[VMIN] = 1;
|
|
tty.c_cc[VTIME] = 0;
|
|
|
|
// TODO: Check these
|
|
// Prevent conversion of tabs to spaces (NOT PRESENT IN LINUX)
|
|
// tty.c_oflag &= ~OXTABS;
|
|
// Prevent removal of C-d chars (0x004) in output (NOT PRESENT IN LINUX)
|
|
// tty.c_oflag &= ~ONOEOT;
|
|
|
|
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
|
|
perror("Could not configure serial port parameters");
|
|
return false;
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
bool set_port_blocking(int fd, bool should_block) {
|
|
struct termios tty;
|
|
memset(&tty, 0, sizeof tty);
|
|
|
|
if (tcgetattr(fd, &tty) != 0) {
|
|
perror("Error configuring port blocking behaviour, could not read port parameters");
|
|
return false;
|
|
} else {
|
|
// TODO: Implement this correctly
|
|
if (should_block) {
|
|
// Block forever until at least one byte is read.
|
|
tty.c_cc[VMIN] = 1;
|
|
tty.c_cc[VTIME] = 0;
|
|
} else {
|
|
// Never block, always return immediately with
|
|
// whatever is available.
|
|
tty.c_cc[VMIN] = 0;
|
|
tty.c_cc[VTIME] = 0;
|
|
}
|
|
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
|
|
perror("Could not set port parameters while configuring blocking behaviour");
|
|
return false;
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
} |